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