< prev index next >
src/hotspot/os/linux/attachListener_linux.cpp
Print this page
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2005, 2018, 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.
@@ -67,21 +67,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:
@@ -90,10 +80,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; }
@@ -123,10 +126,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;
@@ -157,20 +161,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
@@ -179,11 +182,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);
@@ -483,10 +489,31 @@
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.
+ log_debug(attach)("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::naked_yield();
+ }
+ is_init_trigger();
+ return true;
+ }
+ 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 >