src/hotspot/os/linux/attachListener_linux.cpp
changeset 55682 70fab3a8ff02
parent 50333 7cea35f78b50
equal deleted inserted replaced
55681:7b671e6b0d5b 55682:70fab3a8ff02
     1 /*
     1 /*
     2  * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
     2  * Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.
     7  * published by the Free Software Foundation.
    67   static bool _has_path;
    67   static bool _has_path;
    68 
    68 
    69   // the file descriptor for the listening socket
    69   // the file descriptor for the listening socket
    70   static int _listener;
    70   static int _listener;
    71 
    71 
    72   static void set_path(char* path) {
    72   static bool _atexit_registered;
    73     if (path == NULL) {
       
    74       _has_path = false;
       
    75     } else {
       
    76       strncpy(_path, path, UNIX_PATH_MAX);
       
    77       _path[UNIX_PATH_MAX-1] = '\0';
       
    78       _has_path = true;
       
    79     }
       
    80   }
       
    81 
       
    82   static void set_listener(int s)               { _listener = s; }
       
    83 
    73 
    84   // reads a request from the given connected socket
    74   // reads a request from the given connected socket
    85   static LinuxAttachOperation* read_request(int s);
    75   static LinuxAttachOperation* read_request(int s);
    86 
    76 
    87  public:
    77  public:
    90   };
    80   };
    91   enum {
    81   enum {
    92     ATTACH_ERROR_BADVERSION     = 101           // error codes
    82     ATTACH_ERROR_BADVERSION     = 101           // error codes
    93   };
    83   };
    94 
    84 
       
    85   static void set_path(char* path) {
       
    86     if (path == NULL) {
       
    87       _path[0] = '\0';
       
    88       _has_path = false;
       
    89     } else {
       
    90       strncpy(_path, path, UNIX_PATH_MAX);
       
    91       _path[UNIX_PATH_MAX-1] = '\0';
       
    92       _has_path = true;
       
    93     }
       
    94   }
       
    95 
       
    96   static void set_listener(int s)               { _listener = s; }
       
    97 
    95   // initialize the listener, returns 0 if okay
    98   // initialize the listener, returns 0 if okay
    96   static int init();
    99   static int init();
    97 
   100 
    98   static char* path()                   { return _path; }
   101   static char* path()                   { return _path; }
    99   static bool has_path()                { return _has_path; }
   102   static bool has_path()                { return _has_path; }
   123 
   126 
   124 // statics
   127 // statics
   125 char LinuxAttachListener::_path[UNIX_PATH_MAX];
   128 char LinuxAttachListener::_path[UNIX_PATH_MAX];
   126 bool LinuxAttachListener::_has_path;
   129 bool LinuxAttachListener::_has_path;
   127 int LinuxAttachListener::_listener = -1;
   130 int LinuxAttachListener::_listener = -1;
       
   131 bool LinuxAttachListener::_atexit_registered = false;
   128 
   132 
   129 // Supporting class to help split a buffer into individual components
   133 // Supporting class to help split a buffer into individual components
   130 class ArgumentIterator : public StackObj {
   134 class ArgumentIterator : public StackObj {
   131  private:
   135  private:
   132   char* _pos;
   136   char* _pos;
   157 
   161 
   158 // atexit hook to stop listener and unlink the file that it is
   162 // atexit hook to stop listener and unlink the file that it is
   159 // bound too.
   163 // bound too.
   160 extern "C" {
   164 extern "C" {
   161   static void listener_cleanup() {
   165   static void listener_cleanup() {
   162     static int cleanup_done;
   166     int s = LinuxAttachListener::listener();
   163     if (!cleanup_done) {
   167     if (s != -1) {
   164       cleanup_done = 1;
   168       LinuxAttachListener::set_listener(-1);
   165       int s = LinuxAttachListener::listener();
   169       ::shutdown(s, SHUT_RDWR);
   166       if (s != -1) {
   170       ::close(s);
   167         ::close(s);
   171     }
   168       }
   172     if (LinuxAttachListener::has_path()) {
   169       if (LinuxAttachListener::has_path()) {
   173       ::unlink(LinuxAttachListener::path());
   170         ::unlink(LinuxAttachListener::path());
   174       LinuxAttachListener::set_path(NULL);
   171       }
       
   172     }
   175     }
   173   }
   176   }
   174 }
   177 }
   175 
   178 
   176 // Initialization - create a listener socket and bind it to a file
   179 // Initialization - create a listener socket and bind it to a file
   179   char path[UNIX_PATH_MAX];          // socket file
   182   char path[UNIX_PATH_MAX];          // socket file
   180   char initial_path[UNIX_PATH_MAX];  // socket file during setup
   183   char initial_path[UNIX_PATH_MAX];  // socket file during setup
   181   int listener;                      // listener socket (file descriptor)
   184   int listener;                      // listener socket (file descriptor)
   182 
   185 
   183   // register function to cleanup
   186   // register function to cleanup
   184   ::atexit(listener_cleanup);
   187   if (!_atexit_registered) {
       
   188     _atexit_registered = true;
       
   189     ::atexit(listener_cleanup);
       
   190   }
   185 
   191 
   186   int n = snprintf(path, UNIX_PATH_MAX, "%s/.java_pid%d",
   192   int n = snprintf(path, UNIX_PATH_MAX, "%s/.java_pid%d",
   187                    os::get_temp_directory(), os::current_process_id());
   193                    os::get_temp_directory(), os::current_process_id());
   188   if (n < (int)UNIX_PATH_MAX) {
   194   if (n < (int)UNIX_PATH_MAX) {
   189     n = snprintf(initial_path, UNIX_PATH_MAX, "%s.tmp", path);
   195     n = snprintf(initial_path, UNIX_PATH_MAX, "%s.tmp", path);
   483   thread->check_and_wait_while_suspended();
   489   thread->check_and_wait_while_suspended();
   484 
   490 
   485   return ret_code;
   491   return ret_code;
   486 }
   492 }
   487 
   493 
       
   494 bool AttachListener::check_socket_file() {
       
   495   int ret;
       
   496   struct stat64 st;
       
   497   ret = stat64(LinuxAttachListener::path(), &st);
       
   498   if (ret == -1) { // need to restart attach listener.
       
   499     log_debug(attach)("Socket file %s does not exist - Restart Attach Listener",
       
   500                       LinuxAttachListener::path());
       
   501 
       
   502     listener_cleanup();
       
   503 
       
   504     // wait to terminate current attach listener instance...
       
   505     while (AttachListener::transit_state(AL_INITIALIZING,
       
   506                                          AL_NOT_INITIALIZED) != AL_NOT_INITIALIZED) {
       
   507       os::naked_yield();
       
   508     }
       
   509     return is_init_trigger();
       
   510   }
       
   511   return false;
       
   512 }
       
   513 
   488 // Attach Listener is started lazily except in the case when
   514 // Attach Listener is started lazily except in the case when
   489 // +ReduseSignalUsage is used
   515 // +ReduseSignalUsage is used
   490 bool AttachListener::init_at_startup() {
   516 bool AttachListener::init_at_startup() {
   491   if (ReduceSignalUsage) {
   517   if (ReduceSignalUsage) {
   492     return true;
   518     return true;