< prev index next >

src/os/linux/vm/attachListener_linux.cpp

Print this page
rev 9381 : 8225690: Multiple AttachListener threads can be created
Reviewed-by: sspitsyn, cjplummer

@@ -1,7 +1,7 @@
 /*
- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 only, as
  * published by the Free Software Foundation.

@@ -65,21 +65,11 @@
   static bool _has_path;
 
   // the file descriptor for the listening socket
   static int _listener;
 
-  static void set_path(char* path) {
-    if (path == NULL) {
-      _has_path = false;
-    } else {
-      strncpy(_path, path, UNIX_PATH_MAX);
-      _path[UNIX_PATH_MAX-1] = '\0';
-      _has_path = true;
-    }
-  }
-
-  static void set_listener(int s)               { _listener = s; }
+  static bool _atexit_registered;
 
   // reads a request from the given connected socket
   static LinuxAttachOperation* read_request(int s);
 
  public:

@@ -88,10 +78,23 @@
   };
   enum {
     ATTACH_ERROR_BADVERSION     = 101           // error codes
   };
 
+  static void set_path(char* path) {
+    if (path == NULL) {
+      _path[0] = '\0';
+      _has_path = false;
+    } else {
+      strncpy(_path, path, UNIX_PATH_MAX);
+      _path[UNIX_PATH_MAX-1] = '\0';
+      _has_path = true;
+    }
+  }
+
+  static void set_listener(int s)               { _listener = s; }
+
   // initialize the listener, returns 0 if okay
   static int init();
 
   static char* path()                   { return _path; }
   static bool has_path()                { return _has_path; }

@@ -121,10 +124,11 @@
 
 // statics
 char LinuxAttachListener::_path[UNIX_PATH_MAX];
 bool LinuxAttachListener::_has_path;
 int LinuxAttachListener::_listener = -1;
+bool LinuxAttachListener::_atexit_registered = false;
 
 // Supporting class to help split a buffer into individual components
 class ArgumentIterator : public StackObj {
  private:
   char* _pos;

@@ -151,20 +155,19 @@
 
 // atexit hook to stop listener and unlink the file that it is
 // bound too.
 extern "C" {
   static void listener_cleanup() {
-    static int cleanup_done;
-    if (!cleanup_done) {
-      cleanup_done = 1;
       int s = LinuxAttachListener::listener();
       if (s != -1) {
+      LinuxAttachListener::set_listener(-1);
+      ::shutdown(s, SHUT_RDWR);
         ::close(s);
       }
       if (LinuxAttachListener::has_path()) {
         ::unlink(LinuxAttachListener::path());
-      }
+      LinuxAttachListener::set_path(NULL);
     }
   }
 }
 
 // Initialization - create a listener socket and bind it to a file

@@ -173,11 +176,14 @@
   char path[UNIX_PATH_MAX];          // socket file
   char initial_path[UNIX_PATH_MAX];  // socket file during setup
   int listener;                      // listener socket (file descriptor)
 
   // register function to cleanup
+  if (!_atexit_registered) {
+    _atexit_registered = true;
   ::atexit(listener_cleanup);
+  }
 
   int n = snprintf(path, UNIX_PATH_MAX, "%s/.java_pid%d",
                    os::get_temp_directory(), os::current_process_id());
   if (n < (int)UNIX_PATH_MAX) {
     n = snprintf(initial_path, UNIX_PATH_MAX, "%s.tmp", path);

@@ -470,10 +476,30 @@
   thread->check_and_wait_while_suspended();
 
   return ret_code;
 }
 
+bool AttachListener::check_socket_file() {
+  int ret;
+  struct stat64 st;
+  ret = stat64(LinuxAttachListener::path(), &st);
+  if (ret == -1) { // need to restart attach listener.
+    debug_only(warning("Socket file %s does not exist - Restart Attach Listener",
+                      LinuxAttachListener::path()));
+
+    listener_cleanup();
+
+    // wait to terminate current attach listener instance...
+    while (AttachListener::transit_state(AL_INITIALIZING,
+                                         AL_NOT_INITIALIZED) != AL_NOT_INITIALIZED) {
+      os::yield();
+    }
+    return is_init_trigger();
+  }
+  return false;
+}
+
 // Attach Listener is started lazily except in the case when
 // +ReduseSignalUsage is used
 bool AttachListener::init_at_startup() {
   if (ReduceSignalUsage) {
     return true;
< prev index next >