attachListener.hpp revision 3718:b9a9ed0f8eeb
1270096Strasz/* 2270096Strasz * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved. 3270096Strasz * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4270096Strasz * 5270096Strasz * This code is free software; you can redistribute it and/or modify it 6270096Strasz * under the terms of the GNU General Public License version 2 only, as 7270096Strasz * published by the Free Software Foundation. 8270096Strasz * 9270096Strasz * This code is distributed in the hope that it will be useful, but WITHOUT 10270096Strasz * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11270096Strasz * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12270096Strasz * version 2 for more details (a copy is included in the LICENSE file that 13270096Strasz * accompanied this code). 14270096Strasz * 15270096Strasz * You should have received a copy of the GNU General Public License version 16270096Strasz * 2 along with this work; if not, write to the Free Software Foundation, 17270096Strasz * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18270096Strasz * 19270096Strasz * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20270096Strasz * or visit www.oracle.com if you need additional information or have any 21270096Strasz * questions. 22270096Strasz * 23270096Strasz */ 24270096Strasz 25270096Strasz#ifndef SHARE_VM_SERVICES_ATTACHLISTENER_HPP 26270096Strasz#define SHARE_VM_SERVICES_ATTACHLISTENER_HPP 27270096Strasz 28270096Strasz#include "memory/allocation.hpp" 29270096Strasz#include "utilities/debug.hpp" 30270096Strasz#include "utilities/ostream.hpp" 31270096Strasz 32270096Strasz// The AttachListener thread services a queue of operations that are enqueued 33270096Strasz// by client tools. Each operation is identified by a name and has up to 3 34270096Strasz// arguments. The operation name is mapped to a function which performs the 35270096Strasz// operation. The function is called with an outputStream which is can use to 36270096Strasz// write any result data (for examples the properties command serializes 37270096Strasz// properties names and values to the output stream). When the function 38270096Strasz// complets the result value and any result data is returned to the client 39270096Strasz// tool. 40270096Strasz 41270096Strasz#ifndef SERVICES_KERNEL 42270096Strasz 43270096Straszclass AttachOperation; 44270096Strasz 45270096Strasztypedef jint (*AttachOperationFunction)(AttachOperation* op, outputStream* out); 46270096Strasz 47270096Straszstruct AttachOperationFunctionInfo { 48270096Strasz const char* name; 49270096Strasz AttachOperationFunction func; 50270096Strasz}; 51270096Strasz#endif // SERVICES_KERNEL 52270096Strasz 53270096Straszclass AttachListener: AllStatic { 54270096Strasz public: 55270096Strasz static void init() KERNEL_RETURN; 56270096Strasz static void abort() KERNEL_RETURN; 57270096Strasz 58270096Strasz // invoke to perform clean-up tasks when all clients detach 59270096Strasz static void detachall() KERNEL_RETURN; 60270096Strasz 61270096Strasz // indicates if the Attach Listener needs to be created at startup 62270096Strasz static bool init_at_startup() KERNEL_RETURN_(false); 63270096Strasz 64270096Strasz // indicates if we have a trigger to start the Attach Listener 65270096Strasz static bool is_init_trigger() KERNEL_RETURN_(false); 66270096Strasz 67270096Strasz#ifdef SERVICES_KERNEL 68270096Strasz static bool is_attach_supported() { return false; } 69270096Strasz#else // SERVICES_KERNEL 70270096Strasz private: 71270096Strasz static volatile bool _initialized; 72270096Strasz 73279813Strasz public: 74270096Strasz static bool is_initialized() { return _initialized; } 75270096Strasz static void set_initialized() { _initialized = true; } 76270096Strasz 77270096Strasz // indicates if this VM supports attach-on-demand 78270096Strasz static bool is_attach_supported() { return !DisableAttachMechanism; } 79270096Strasz 80270096Strasz // platform specific initialization 81270096Strasz static int pd_init(); 82270096Strasz 83273127Strasz // platform specific operation 84270096Strasz static AttachOperationFunctionInfo* pd_find_operation(const char* name); 85270096Strasz 86270096Strasz // platform specific flag change 87270096Strasz static jint pd_set_flag(AttachOperation* op, outputStream* out); 88270096Strasz 89270096Strasz // platform specific detachall 90279916Strasz static void pd_detachall(); 91270096Strasz 92273127Strasz // platform specific data dump 93273127Strasz static void pd_data_dump(); 94270096Strasz 95270096Strasz // dequeue the next operation 96270096Strasz static AttachOperation* dequeue(); 97270096Strasz#endif // SERVICES_KERNEL 98270096Strasz}; 99270096Strasz 100270096Strasz#ifndef SERVICES_KERNEL 101270096Straszclass AttachOperation: public CHeapObj<mtInternal> { 102270096Strasz public: 103270096Strasz enum { 104270096Strasz name_length_max = 16, // maximum length of name 105270096Strasz arg_length_max = 1024, // maximum length of argument 106270096Strasz arg_count_max = 3 // maximum number of arguments 107270096Strasz }; 108270096Strasz 109270096Strasz // name of special operation that can be enqueued when all 110270096Strasz // clients detach 111270096Strasz static char* detachall_operation_name() { return (char*)"detachall"; } 112270096Strasz 113270096Strasz private: 114270096Strasz char _name[name_length_max+1]; 115 char _arg[arg_count_max][arg_length_max+1]; 116 117 public: 118 const char* name() const { return _name; } 119 120 // set the operation name 121 void set_name(char* name) { 122 assert(strlen(name) <= name_length_max, "exceeds maximum name length"); 123 strcpy(_name, name); 124 } 125 126 // get an argument value 127 const char* arg(int i) const { 128 assert(i>=0 && i<arg_count_max, "invalid argument index"); 129 return _arg[i]; 130 } 131 132 // set an argument value 133 void set_arg(int i, char* arg) { 134 assert(i>=0 && i<arg_count_max, "invalid argument index"); 135 if (arg == NULL) { 136 _arg[i][0] = '\0'; 137 } else { 138 assert(strlen(arg) <= arg_length_max, "exceeds maximum argument length"); 139 strcpy(_arg[i], arg); 140 } 141 } 142 143 // create an operation of a given name 144 AttachOperation(char* name) { 145 set_name(name); 146 for (int i=0; i<arg_count_max; i++) { 147 set_arg(i, NULL); 148 } 149 } 150 151 // complete operation by sending result code and any result data to the client 152 virtual void complete(jint result, bufferedStream* result_stream) = 0; 153}; 154#endif // SERVICES_KERNEL 155 156#endif // SHARE_VM_SERVICES_ATTACHLISTENER_HPP 157