attachListener.hpp revision 3465:d2a62e0f25eb
1218065Sadrian/*
2218065Sadrian * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
3240592Sadrian * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4218065Sadrian *
5218065Sadrian * This code is free software; you can redistribute it and/or modify it
6218065Sadrian * under the terms of the GNU General Public License version 2 only, as
7218065Sadrian * published by the Free Software Foundation.
8218065Sadrian *
9218065Sadrian * This code is distributed in the hope that it will be useful, but WITHOUT
10218065Sadrian * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11218065Sadrian * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12218065Sadrian * version 2 for more details (a copy is included in the LICENSE file that
13218065Sadrian * accompanied this code).
14218065Sadrian *
15218065Sadrian * You should have received a copy of the GNU General Public License version
16218065Sadrian * 2 along with this work; if not, write to the Free Software Foundation,
17218065Sadrian * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18218065Sadrian *
19218065Sadrian * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20218065Sadrian * or visit www.oracle.com if you need additional information or have any
21218065Sadrian * questions.
22218065Sadrian *
23218065Sadrian */
24218065Sadrian
25218065Sadrian#ifndef SHARE_VM_SERVICES_ATTACHLISTENER_HPP
26218065Sadrian#define SHARE_VM_SERVICES_ATTACHLISTENER_HPP
27218065Sadrian
28218065Sadrian#include "memory/allocation.hpp"
29218065Sadrian#include "utilities/debug.hpp"
30218065Sadrian#include "utilities/ostream.hpp"
31218065Sadrian
32218065Sadrian// The AttachListener thread services a queue of operations that are enqueued
33218065Sadrian// by client tools. Each operation is identified by a name and has up to 3
34218065Sadrian// arguments. The operation name is mapped to a function which performs the
35218065Sadrian// operation. The function is called with an outputStream which is can use to
36218065Sadrian// write any result data (for examples the properties command serializes
37218065Sadrian// properties names and values to the output stream). When the function
38218065Sadrian// complets the result value and any result data is returned to the client
39218065Sadrian// tool.
40218065Sadrian
41218065Sadrian#ifndef SERVICES_KERNEL
42218065Sadrian
43218065Sadrianclass AttachOperation;
44218065Sadrian
45218065Sadriantypedef jint (*AttachOperationFunction)(AttachOperation* op, outputStream* out);
46218065Sadrian
47218065Sadrianstruct AttachOperationFunctionInfo {
48218065Sadrian  const char* name;
49218065Sadrian  AttachOperationFunction func;
50218065Sadrian};
51218065Sadrian#endif // SERVICES_KERNEL
52218065Sadrian
53218065Sadrianclass AttachListener: AllStatic {
54218065Sadrian public:
55218065Sadrian  static void init()  KERNEL_RETURN;
56218065Sadrian  static void abort() KERNEL_RETURN;
57218065Sadrian
58218065Sadrian  // invoke to perform clean-up tasks when all clients detach
59218065Sadrian  static void detachall() KERNEL_RETURN;
60218065Sadrian
61218065Sadrian  // indicates if the Attach Listener needs to be created at startup
62218065Sadrian  static bool init_at_startup() KERNEL_RETURN_(false);
63218065Sadrian
64218065Sadrian  // indicates if we have a trigger to start the Attach Listener
65218065Sadrian  static bool is_init_trigger() KERNEL_RETURN_(false);
66218065Sadrian
67218065Sadrian#ifdef SERVICES_KERNEL
68218065Sadrian  static bool is_attach_supported()             { return false; }
69218065Sadrian#else // SERVICES_KERNEL
70218065Sadrian private:
71218065Sadrian  static volatile bool _initialized;
72218065Sadrian
73218065Sadrian public:
74218065Sadrian  static bool is_initialized()                  { return _initialized; }
75218065Sadrian  static void set_initialized()                 { _initialized = true; }
76218065Sadrian
77218065Sadrian  // indicates if this VM supports attach-on-demand
78218065Sadrian  static bool is_attach_supported()             { return !DisableAttachMechanism; }
79218065Sadrian
80218065Sadrian  // platform specific initialization
81227364Sadrian  static int pd_init();
82218065Sadrian
83218065Sadrian  // platform specific operation
84218065Sadrian  static AttachOperationFunctionInfo* pd_find_operation(const char* name);
85218065Sadrian
86218065Sadrian  // platform specific flag change
87218065Sadrian  static jint pd_set_flag(AttachOperation* op, outputStream* out);
88218065Sadrian
89218065Sadrian  // platform specific detachall
90218065Sadrian  static void pd_detachall();
91218065Sadrian
92218065Sadrian  // platform specific data dump
93218065Sadrian  static void pd_data_dump();
94218065Sadrian
95218065Sadrian  // dequeue the next operation
96218065Sadrian  static AttachOperation* dequeue();
97218065Sadrian#endif // SERVICES_KERNEL
98218065Sadrian};
99218065Sadrian
100218065Sadrian#ifndef SERVICES_KERNEL
101218065Sadrianclass AttachOperation: public CHeapObj<mtInternal> {
102218240Sadrian public:
103218065Sadrian  enum {
104242782Sadrian    name_length_max = 16,       // maximum length of  name
105242782Sadrian    arg_length_max = 1024,      // maximum length of argument
106242782Sadrian    arg_count_max = 3           // maximum number of arguments
107242782Sadrian  };
108218154Sadrian
109227364Sadrian  // name of special operation that can be enqueued when all
110227364Sadrian  // clients detach
111227364Sadrian  static char* detachall_operation_name() { return (char*)"detachall"; }
112227364Sadrian
113240946Sadrian private:
114240946Sadrian  char _name[name_length_max+1];
115240946Sadrian  char _arg[arg_count_max][arg_length_max+1];
116240946Sadrian
117240946Sadrian public:
118241170Sadrian  const char* name() const                      { return _name; }
119241170Sadrian
120241170Sadrian  // set the operation name
121227364Sadrian  void set_name(char* name) {
122227364Sadrian    assert(strlen(name) <= name_length_max, "exceeds maximum name length");
123227364Sadrian    strcpy(_name, name);
124227364Sadrian  }
125236872Sadrian
126236872Sadrian  // get an argument value
127227364Sadrian  const char* arg(int i) const {
128227364Sadrian    assert(i>=0 && i<arg_count_max, "invalid argument index");
129240639Sadrian    return _arg[i];
130240639Sadrian  }
131240639Sadrian
132227364Sadrian  // set an argument value
133243162Sadrian  void set_arg(int i, char* arg) {
134243162Sadrian    assert(i>=0 && i<arg_count_max, "invalid argument index");
135243162Sadrian    if (arg == NULL) {
136243162Sadrian      _arg[i][0] = '\0';
137243162Sadrian    } else {
138243162Sadrian      assert(strlen(arg) <= arg_length_max, "exceeds maximum argument length");
139243162Sadrian      strcpy(_arg[i], arg);
140243162Sadrian    }
141243162Sadrian  }
142243162Sadrian
143243162Sadrian  // create an operation of a given name
144243162Sadrian  AttachOperation(char* name) {
145243162Sadrian    set_name(name);
146243162Sadrian    for (int i=0; i<arg_count_max; i++) {
147243162Sadrian      set_arg(i, NULL);
148243162Sadrian    }
149243162Sadrian  }
150243162Sadrian
151243162Sadrian  // complete operation by sending result code and any result data to the client
152243162Sadrian  virtual void complete(jint result, bufferedStream* result_stream) = 0;
153243162Sadrian};
154243162Sadrian#endif // SERVICES_KERNEL
155243162Sadrian
156243162Sadrian#endif // SHARE_VM_SERVICES_ATTACHLISTENER_HPP
157243162Sadrian