equal
deleted
inserted
replaced
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; |