attachListener.hpp revision 3465:d2a62e0f25eb
1270096Strasz/* 2270096Strasz * Copyright (c) 2005, 2011, 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" 31270276Strasz 32270276Strasz// The AttachListener thread services a queue of operations that are enqueued 33270276Strasz// 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; 49294670Strasz 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 73270096Strasz 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 83270096Strasz // 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 90270096Strasz static void pd_detachall(); 91270096Strasz 92270096Strasz // platform specific data dump 93270096Strasz 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]; 115270096Strasz char _arg[arg_count_max][arg_length_max+1]; 116270096Strasz 117270096Strasz public: 118270096Strasz const char* name() const { return _name; } 119270096Strasz 120270096Strasz // set the operation name 121270096Strasz void set_name(char* name) { 122270096Strasz assert(strlen(name) <= name_length_max, "exceeds maximum name length"); 123270096Strasz strcpy(_name, name); 124270096Strasz } 125270096Strasz 126270096Strasz // get an argument value 127270096Strasz const char* arg(int i) const { 128270096Strasz assert(i>=0 && i<arg_count_max, "invalid argument index"); 129270096Strasz return _arg[i]; 130270096Strasz } 131270096Strasz 132270096Strasz // set an argument value 133270096Strasz void set_arg(int i, char* arg) { 134270096Strasz assert(i>=0 && i<arg_count_max, "invalid argument index"); 135270096Strasz if (arg == NULL) { 136270096Strasz _arg[i][0] = '\0'; 137270096Strasz } else { 138270096Strasz assert(strlen(arg) <= arg_length_max, "exceeds maximum argument length"); 139270096Strasz strcpy(_arg[i], arg); 140270096Strasz } 141270096Strasz } 142270096Strasz 143279846Strasz // create an operation of a given name 144279846Strasz AttachOperation(char* name) { 145270096Strasz set_name(name); 146270096Strasz for (int i=0; i<arg_count_max; i++) { 147270096Strasz set_arg(i, NULL); 148270096Strasz } 149270096Strasz } 150270096Strasz 151270096Strasz // complete operation by sending result code and any result data to the client 152270096Strasz virtual void complete(jint result, bufferedStream* result_stream) = 0; 153270096Strasz}; 154270096Strasz#endif // SERVICES_KERNEL 155270096Strasz 156270096Strasz#endif // SHARE_VM_SERVICES_ATTACHLISTENER_HPP 157270096Strasz