src/hotspot/os/windows/attachListener_windows.cpp
author chegar
Thu, 17 Oct 2019 20:53:35 +0100
branchdatagramsocketimpl-branch
changeset 58678 9cf78a70fa4f
parent 51584 d395677d99f3
child 58679 9c3209ff7550
permissions -rw-r--r--
datagramsocketimpl-branch: update to default
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
     1
/*
58678
9cf78a70fa4f datagramsocketimpl-branch: update to default
chegar
parents: 51584
diff changeset
     2
 * Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
489c9b5090e2 Initial load
duke
parents:
diff changeset
     4
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
489c9b5090e2 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
489c9b5090e2 Initial load
duke
parents:
diff changeset
     7
 * published by the Free Software Foundation.
489c9b5090e2 Initial load
duke
parents:
diff changeset
     8
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
     9
 * This code is distributed in the hope that it will be useful, but WITHOUT
489c9b5090e2 Initial load
duke
parents:
diff changeset
    10
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
489c9b5090e2 Initial load
duke
parents:
diff changeset
    11
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
489c9b5090e2 Initial load
duke
parents:
diff changeset
    12
 * version 2 for more details (a copy is included in the LICENSE file that
489c9b5090e2 Initial load
duke
parents:
diff changeset
    13
 * accompanied this code).
489c9b5090e2 Initial load
duke
parents:
diff changeset
    14
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
    15
 * You should have received a copy of the GNU General Public License version
489c9b5090e2 Initial load
duke
parents:
diff changeset
    16
 * 2 along with this work; if not, write to the Free Software Foundation,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    17
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    18
 *
5547
f4b087cbb361 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1
diff changeset
    19
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
f4b087cbb361 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1
diff changeset
    20
 * or visit www.oracle.com if you need additional information or have any
f4b087cbb361 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1
diff changeset
    21
 * questions.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    22
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
    23
 */
489c9b5090e2 Initial load
duke
parents:
diff changeset
    24
7397
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    25
#include "precompiled.hpp"
49982
9042ffe5b7fe 8200729: Conditional compilation of GCs
stefank
parents: 49742
diff changeset
    26
#include "logging/log.hpp"
49449
ef5d5d343e2a 8199263: Split interfaceSupport.hpp to not require including .inline.hpp files
coleenp
parents: 47216
diff changeset
    27
#include "runtime/interfaceSupport.inline.hpp"
7397
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    28
#include "runtime/os.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    29
#include "services/attachListener.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    30
#include "services/dtraceAttacher.hpp"
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    31
489c9b5090e2 Initial load
duke
parents:
diff changeset
    32
#include <windows.h>
489c9b5090e2 Initial load
duke
parents:
diff changeset
    33
#include <signal.h>             // SIGBREAK
27471
6e56277909f1 8062370: Various minor code improvements
goetz
parents: 18931
diff changeset
    34
#include <stdio.h>
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    35
489c9b5090e2 Initial load
duke
parents:
diff changeset
    36
// The AttachListener thread services a queue of operations. It blocks in the dequeue
489c9b5090e2 Initial load
duke
parents:
diff changeset
    37
// function until an operation is enqueued. A client enqueues an operation by creating
489c9b5090e2 Initial load
duke
parents:
diff changeset
    38
// a thread in this process using the Win32 CreateRemoteThread function. That thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
    39
// executes a small stub generated by the client. The stub invokes the
489c9b5090e2 Initial load
duke
parents:
diff changeset
    40
// JVM_EnqueueOperation function which checks the operation parameters and enqueues
489c9b5090e2 Initial load
duke
parents:
diff changeset
    41
// the operation to the queue serviced by the attach listener. The thread created by
489c9b5090e2 Initial load
duke
parents:
diff changeset
    42
// the client is a native thread and is restricted to a single page of stack. To keep
489c9b5090e2 Initial load
duke
parents:
diff changeset
    43
// it simple operations are pre-allocated at initialization time. An enqueue thus
489c9b5090e2 Initial load
duke
parents:
diff changeset
    44
// takes a preallocated operation, populates the operation parameters, adds it to
489c9b5090e2 Initial load
duke
parents:
diff changeset
    45
// queue and wakes up the attach listener.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    46
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
    47
// When an operation has completed the attach listener is required to send the
489c9b5090e2 Initial load
duke
parents:
diff changeset
    48
// operation result and any result data to the client. In this implementation the
489c9b5090e2 Initial load
duke
parents:
diff changeset
    49
// client is a pipe server. In the enqueue operation it provides the name of pipe
489c9b5090e2 Initial load
duke
parents:
diff changeset
    50
// to this process. When the operation is completed this process opens the pipe and
489c9b5090e2 Initial load
duke
parents:
diff changeset
    51
// sends the result and output back to the client. Note that writing to the pipe
489c9b5090e2 Initial load
duke
parents:
diff changeset
    52
// (and flushing the output) is a blocking operation. This means that a non-responsive
489c9b5090e2 Initial load
duke
parents:
diff changeset
    53
// client could potentially hang the attach listener thread indefinitely. In that
489c9b5090e2 Initial load
duke
parents:
diff changeset
    54
// case no new operations would be executed but the VM would continue as normal.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    55
// As only suitably privileged processes can open this process we concluded that
489c9b5090e2 Initial load
duke
parents:
diff changeset
    56
// this wasn't worth worrying about.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    57
489c9b5090e2 Initial load
duke
parents:
diff changeset
    58
489c9b5090e2 Initial load
duke
parents:
diff changeset
    59
// forward reference
489c9b5090e2 Initial load
duke
parents:
diff changeset
    60
class Win32AttachOperation;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    61
489c9b5090e2 Initial load
duke
parents:
diff changeset
    62
489c9b5090e2 Initial load
duke
parents:
diff changeset
    63
class Win32AttachListener: AllStatic {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    64
 private:
489c9b5090e2 Initial load
duke
parents:
diff changeset
    65
  enum {
29322
1f646019dc45 8073042: jcmd hangs until another jcmd is executed (which, in turn also hangs)
mgronlun
parents: 27471
diff changeset
    66
    max_enqueued_operations = 4
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    67
  };
489c9b5090e2 Initial load
duke
parents:
diff changeset
    68
489c9b5090e2 Initial load
duke
parents:
diff changeset
    69
  // protects the preallocated list and the operation list
489c9b5090e2 Initial load
duke
parents:
diff changeset
    70
  static HANDLE _mutex;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    71
489c9b5090e2 Initial load
duke
parents:
diff changeset
    72
  // head of preallocated operations list
489c9b5090e2 Initial load
duke
parents:
diff changeset
    73
  static Win32AttachOperation* _avail;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    74
489c9b5090e2 Initial load
duke
parents:
diff changeset
    75
  // head and tail of enqueue operations list
489c9b5090e2 Initial load
duke
parents:
diff changeset
    76
  static Win32AttachOperation* _head;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    77
  static Win32AttachOperation* _tail;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    78
489c9b5090e2 Initial load
duke
parents:
diff changeset
    79
489c9b5090e2 Initial load
duke
parents:
diff changeset
    80
  static Win32AttachOperation* head()                       { return _head; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    81
  static void set_head(Win32AttachOperation* head)          { _head = head; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    82
489c9b5090e2 Initial load
duke
parents:
diff changeset
    83
  static Win32AttachOperation* tail()                       { return _tail; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    84
  static void set_tail(Win32AttachOperation* tail)          { _tail = tail; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    85
489c9b5090e2 Initial load
duke
parents:
diff changeset
    86
29322
1f646019dc45 8073042: jcmd hangs until another jcmd is executed (which, in turn also hangs)
mgronlun
parents: 27471
diff changeset
    87
  // A semaphore is used for communication about enqueued operations.
1f646019dc45 8073042: jcmd hangs until another jcmd is executed (which, in turn also hangs)
mgronlun
parents: 27471
diff changeset
    88
  // The maximum count for the semaphore object will be set to "max_enqueued_operations".
1f646019dc45 8073042: jcmd hangs until another jcmd is executed (which, in turn also hangs)
mgronlun
parents: 27471
diff changeset
    89
  // The state of a semaphore is signaled when its count is greater than
1f646019dc45 8073042: jcmd hangs until another jcmd is executed (which, in turn also hangs)
mgronlun
parents: 27471
diff changeset
    90
  // zero (there are operations enqueued), and nonsignaled when it is zero.
1f646019dc45 8073042: jcmd hangs until another jcmd is executed (which, in turn also hangs)
mgronlun
parents: 27471
diff changeset
    91
  static HANDLE _enqueued_ops_semaphore;
1f646019dc45 8073042: jcmd hangs until another jcmd is executed (which, in turn also hangs)
mgronlun
parents: 27471
diff changeset
    92
  static HANDLE enqueued_ops_semaphore() { return _enqueued_ops_semaphore; }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    93
489c9b5090e2 Initial load
duke
parents:
diff changeset
    94
 public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
    95
  enum {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    96
    ATTACH_ERROR_DISABLED               = 100,              // error codes
489c9b5090e2 Initial load
duke
parents:
diff changeset
    97
    ATTACH_ERROR_RESOURCE               = 101,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    98
    ATTACH_ERROR_ILLEGALARG             = 102,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    99
    ATTACH_ERROR_INTERNAL               = 103
489c9b5090e2 Initial load
duke
parents:
diff changeset
   100
  };
489c9b5090e2 Initial load
duke
parents:
diff changeset
   101
489c9b5090e2 Initial load
duke
parents:
diff changeset
   102
  static int init();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   103
  static HANDLE mutex()                                     { return _mutex; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   104
489c9b5090e2 Initial load
duke
parents:
diff changeset
   105
  static Win32AttachOperation* available()                  { return _avail; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   106
  static void set_available(Win32AttachOperation* avail)    { _avail = avail; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   107
489c9b5090e2 Initial load
duke
parents:
diff changeset
   108
  // enqueue an operation to the end of the list
489c9b5090e2 Initial load
duke
parents:
diff changeset
   109
  static int enqueue(char* cmd, char* arg1, char* arg2, char* arg3, char* pipename);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   110
489c9b5090e2 Initial load
duke
parents:
diff changeset
   111
  // dequeue an operation from from head of the list
489c9b5090e2 Initial load
duke
parents:
diff changeset
   112
  static Win32AttachOperation* dequeue();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   113
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
   114
489c9b5090e2 Initial load
duke
parents:
diff changeset
   115
// statics
489c9b5090e2 Initial load
duke
parents:
diff changeset
   116
HANDLE Win32AttachListener::_mutex;
29322
1f646019dc45 8073042: jcmd hangs until another jcmd is executed (which, in turn also hangs)
mgronlun
parents: 27471
diff changeset
   117
HANDLE Win32AttachListener::_enqueued_ops_semaphore;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   118
Win32AttachOperation* Win32AttachListener::_avail;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   119
Win32AttachOperation* Win32AttachListener::_head;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   120
Win32AttachOperation* Win32AttachListener::_tail;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   121
489c9b5090e2 Initial load
duke
parents:
diff changeset
   122
489c9b5090e2 Initial load
duke
parents:
diff changeset
   123
// Win32AttachOperation is an AttachOperation that additionally encapsulates the name
489c9b5090e2 Initial load
duke
parents:
diff changeset
   124
// of a pipe which is used to send the operation reply/output to the client.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   125
// Win32AttachOperation can also be linked in a list.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   126
489c9b5090e2 Initial load
duke
parents:
diff changeset
   127
class Win32AttachOperation: public AttachOperation {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   128
 private:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   129
  friend class Win32AttachListener;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   130
489c9b5090e2 Initial load
duke
parents:
diff changeset
   131
  enum {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   132
    pipe_name_max = 256             // maximum pipe name
489c9b5090e2 Initial load
duke
parents:
diff changeset
   133
  };
489c9b5090e2 Initial load
duke
parents:
diff changeset
   134
49742
1196aa0be8be 8201247: Various cleanups in the attach framework
clanger
parents: 49449
diff changeset
   135
  char _pipe[pipe_name_max + 1];
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   136
489c9b5090e2 Initial load
duke
parents:
diff changeset
   137
  const char* pipe() const                              { return _pipe; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   138
  void set_pipe(const char* pipe) {
49742
1196aa0be8be 8201247: Various cleanups in the attach framework
clanger
parents: 49449
diff changeset
   139
    assert(strlen(pipe) <= pipe_name_max, "exceeds maximum length of pipe name");
1196aa0be8be 8201247: Various cleanups in the attach framework
clanger
parents: 49449
diff changeset
   140
    os::snprintf(_pipe, sizeof(_pipe), "%s", pipe);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   141
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   142
489c9b5090e2 Initial load
duke
parents:
diff changeset
   143
  HANDLE open_pipe();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   144
  static BOOL write_pipe(HANDLE hPipe, char* buf, int len);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   145
489c9b5090e2 Initial load
duke
parents:
diff changeset
   146
  Win32AttachOperation* _next;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   147
489c9b5090e2 Initial load
duke
parents:
diff changeset
   148
  Win32AttachOperation* next() const                    { return _next; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   149
  void set_next(Win32AttachOperation* next)             { _next = next; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   150
489c9b5090e2 Initial load
duke
parents:
diff changeset
   151
  // noarg constructor as operation is preallocated
489c9b5090e2 Initial load
duke
parents:
diff changeset
   152
  Win32AttachOperation() : AttachOperation("<noname>") {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   153
    set_pipe("<nopipe>");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   154
    set_next(NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   155
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   156
489c9b5090e2 Initial load
duke
parents:
diff changeset
   157
 public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   158
  void Win32AttachOperation::complete(jint result, bufferedStream* result_stream);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   159
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
   160
489c9b5090e2 Initial load
duke
parents:
diff changeset
   161
29322
1f646019dc45 8073042: jcmd hangs until another jcmd is executed (which, in turn also hangs)
mgronlun
parents: 27471
diff changeset
   162
// Preallocate the maximum number of operations that can be enqueued.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   163
int Win32AttachListener::init() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   164
  _mutex = (void*)::CreateMutex(NULL, FALSE, NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   165
  guarantee(_mutex != (HANDLE)NULL, "mutex creation failed");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   166
29322
1f646019dc45 8073042: jcmd hangs until another jcmd is executed (which, in turn also hangs)
mgronlun
parents: 27471
diff changeset
   167
  _enqueued_ops_semaphore = ::CreateSemaphore(NULL, 0, max_enqueued_operations, NULL);
1f646019dc45 8073042: jcmd hangs until another jcmd is executed (which, in turn also hangs)
mgronlun
parents: 27471
diff changeset
   168
  guarantee(_enqueued_ops_semaphore != (HANDLE)NULL, "semaphore creation failed");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   169
489c9b5090e2 Initial load
duke
parents:
diff changeset
   170
  set_head(NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   171
  set_tail(NULL);
29322
1f646019dc45 8073042: jcmd hangs until another jcmd is executed (which, in turn also hangs)
mgronlun
parents: 27471
diff changeset
   172
  set_available(NULL);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   173
29322
1f646019dc45 8073042: jcmd hangs until another jcmd is executed (which, in turn also hangs)
mgronlun
parents: 27471
diff changeset
   174
  for (int i=0; i<max_enqueued_operations; i++) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   175
    Win32AttachOperation* op = new Win32AttachOperation();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   176
    op->set_next(available());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   177
    set_available(op);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   178
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   179
489c9b5090e2 Initial load
duke
parents:
diff changeset
   180
  return 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   181
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   182
489c9b5090e2 Initial load
duke
parents:
diff changeset
   183
// Enqueue an operation. This is called from a native thread that is not attached to VM.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   184
// Also we need to be careful not to execute anything that results in more than a 4k stack.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   185
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   186
int Win32AttachListener::enqueue(char* cmd, char* arg0, char* arg1, char* arg2, char* pipename) {
51584
d395677d99f3 8199811: com/sun/jdi/ProcessAttachTest.java fails intermittently: Remote thread failed for unknown reason
cjplummer
parents: 49982
diff changeset
   187
  // wait up to 10 seconds for listener to be up and running
d395677d99f3 8199811: com/sun/jdi/ProcessAttachTest.java fails intermittently: Remote thread failed for unknown reason
cjplummer
parents: 49982
diff changeset
   188
  int sleep_count = 0;
d395677d99f3 8199811: com/sun/jdi/ProcessAttachTest.java fails intermittently: Remote thread failed for unknown reason
cjplummer
parents: 49982
diff changeset
   189
  while (!AttachListener::is_initialized()) {
d395677d99f3 8199811: com/sun/jdi/ProcessAttachTest.java fails intermittently: Remote thread failed for unknown reason
cjplummer
parents: 49982
diff changeset
   190
    Sleep(1000); // 1 second
d395677d99f3 8199811: com/sun/jdi/ProcessAttachTest.java fails intermittently: Remote thread failed for unknown reason
cjplummer
parents: 49982
diff changeset
   191
    sleep_count++;
d395677d99f3 8199811: com/sun/jdi/ProcessAttachTest.java fails intermittently: Remote thread failed for unknown reason
cjplummer
parents: 49982
diff changeset
   192
    if (sleep_count > 10) { // try for 10 seconds
d395677d99f3 8199811: com/sun/jdi/ProcessAttachTest.java fails intermittently: Remote thread failed for unknown reason
cjplummer
parents: 49982
diff changeset
   193
      return ATTACH_ERROR_DISABLED;
d395677d99f3 8199811: com/sun/jdi/ProcessAttachTest.java fails intermittently: Remote thread failed for unknown reason
cjplummer
parents: 49982
diff changeset
   194
    }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   195
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   196
489c9b5090e2 Initial load
duke
parents:
diff changeset
   197
  // check that all paramteres to the operation
489c9b5090e2 Initial load
duke
parents:
diff changeset
   198
  if (strlen(cmd) > AttachOperation::name_length_max) return ATTACH_ERROR_ILLEGALARG;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   199
  if (strlen(arg0) > AttachOperation::arg_length_max) return ATTACH_ERROR_ILLEGALARG;
33794
41ef3dc95179 8140482: Various minor code improvements (runtime)
goetz
parents: 29322
diff changeset
   200
  if (strlen(arg1) > AttachOperation::arg_length_max) return ATTACH_ERROR_ILLEGALARG;
41ef3dc95179 8140482: Various minor code improvements (runtime)
goetz
parents: 29322
diff changeset
   201
  if (strlen(arg2) > AttachOperation::arg_length_max) return ATTACH_ERROR_ILLEGALARG;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   202
  if (strlen(pipename) > Win32AttachOperation::pipe_name_max) return ATTACH_ERROR_ILLEGALARG;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   203
489c9b5090e2 Initial load
duke
parents:
diff changeset
   204
  // check for a well-formed pipename
489c9b5090e2 Initial load
duke
parents:
diff changeset
   205
  if (strstr(pipename, "\\\\.\\pipe\\") != pipename) return ATTACH_ERROR_ILLEGALARG;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   206
489c9b5090e2 Initial load
duke
parents:
diff changeset
   207
  // grab the lock for the list
489c9b5090e2 Initial load
duke
parents:
diff changeset
   208
  DWORD res = ::WaitForSingleObject(mutex(), INFINITE);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   209
  if (res != WAIT_OBJECT_0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   210
    return ATTACH_ERROR_INTERNAL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   211
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   212
489c9b5090e2 Initial load
duke
parents:
diff changeset
   213
  // try to get an operation from the available list
489c9b5090e2 Initial load
duke
parents:
diff changeset
   214
  Win32AttachOperation* op = available();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   215
  if (op != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   216
    set_available(op->next());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   217
489c9b5090e2 Initial load
duke
parents:
diff changeset
   218
    // add to end (tail) of list
489c9b5090e2 Initial load
duke
parents:
diff changeset
   219
    op->set_next(NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   220
    if (tail() == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   221
      set_head(op);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   222
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   223
      tail()->set_next(op);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   224
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   225
    set_tail(op);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   226
489c9b5090e2 Initial load
duke
parents:
diff changeset
   227
    op->set_name(cmd);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   228
    op->set_arg(0, arg0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   229
    op->set_arg(1, arg1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   230
    op->set_arg(2, arg2);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   231
    op->set_pipe(pipename);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   232
29322
1f646019dc45 8073042: jcmd hangs until another jcmd is executed (which, in turn also hangs)
mgronlun
parents: 27471
diff changeset
   233
    // Increment number of enqueued operations.
1f646019dc45 8073042: jcmd hangs until another jcmd is executed (which, in turn also hangs)
mgronlun
parents: 27471
diff changeset
   234
    // Side effect: Semaphore will be signaled and will release
1f646019dc45 8073042: jcmd hangs until another jcmd is executed (which, in turn also hangs)
mgronlun
parents: 27471
diff changeset
   235
    // any blocking waiters (i.e. the AttachListener thread).
1f646019dc45 8073042: jcmd hangs until another jcmd is executed (which, in turn also hangs)
mgronlun
parents: 27471
diff changeset
   236
    BOOL not_exceeding_semaphore_maximum_count =
1f646019dc45 8073042: jcmd hangs until another jcmd is executed (which, in turn also hangs)
mgronlun
parents: 27471
diff changeset
   237
      ::ReleaseSemaphore(enqueued_ops_semaphore(), 1, NULL);
1f646019dc45 8073042: jcmd hangs until another jcmd is executed (which, in turn also hangs)
mgronlun
parents: 27471
diff changeset
   238
    guarantee(not_exceeding_semaphore_maximum_count, "invariant");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   239
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   240
  ::ReleaseMutex(mutex());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   241
489c9b5090e2 Initial load
duke
parents:
diff changeset
   242
  return (op != NULL) ? 0 : ATTACH_ERROR_RESOURCE;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   243
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   244
489c9b5090e2 Initial load
duke
parents:
diff changeset
   245
29322
1f646019dc45 8073042: jcmd hangs until another jcmd is executed (which, in turn also hangs)
mgronlun
parents: 27471
diff changeset
   246
// dequeue the operation from the head of the operation list.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   247
Win32AttachOperation* Win32AttachListener::dequeue() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   248
  for (;;) {
29322
1f646019dc45 8073042: jcmd hangs until another jcmd is executed (which, in turn also hangs)
mgronlun
parents: 27471
diff changeset
   249
    DWORD res = ::WaitForSingleObject(enqueued_ops_semaphore(), INFINITE);
1f646019dc45 8073042: jcmd hangs until another jcmd is executed (which, in turn also hangs)
mgronlun
parents: 27471
diff changeset
   250
    // returning from WaitForSingleObject will have decreased
1f646019dc45 8073042: jcmd hangs until another jcmd is executed (which, in turn also hangs)
mgronlun
parents: 27471
diff changeset
   251
    // the current count of the semaphore by 1.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   252
    guarantee(res == WAIT_OBJECT_0, "wait failed");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   253
489c9b5090e2 Initial load
duke
parents:
diff changeset
   254
    res = ::WaitForSingleObject(mutex(), INFINITE);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   255
    guarantee(res == WAIT_OBJECT_0, "wait failed");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   256
489c9b5090e2 Initial load
duke
parents:
diff changeset
   257
    Win32AttachOperation* op = head();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   258
    if (op != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   259
      set_head(op->next());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   260
      if (head() == NULL) {     // list is empty
489c9b5090e2 Initial load
duke
parents:
diff changeset
   261
        set_tail(NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   262
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   263
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   264
    ::ReleaseMutex(mutex());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   265
489c9b5090e2 Initial load
duke
parents:
diff changeset
   266
    if (op != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   267
      return op;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   268
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   269
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   270
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   271
489c9b5090e2 Initial load
duke
parents:
diff changeset
   272
489c9b5090e2 Initial load
duke
parents:
diff changeset
   273
// open the pipe to the client
489c9b5090e2 Initial load
duke
parents:
diff changeset
   274
HANDLE Win32AttachOperation::open_pipe() {
58678
9cf78a70fa4f datagramsocketimpl-branch: update to default
chegar
parents: 51584
diff changeset
   275
  HANDLE hPipe = ::CreateFile( pipe(),  // pipe name
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   276
                        GENERIC_WRITE,   // write only
489c9b5090e2 Initial load
duke
parents:
diff changeset
   277
                        0,              // no sharing
489c9b5090e2 Initial load
duke
parents:
diff changeset
   278
                        NULL,           // default security attributes
489c9b5090e2 Initial load
duke
parents:
diff changeset
   279
                        OPEN_EXISTING,  // opens existing pipe
489c9b5090e2 Initial load
duke
parents:
diff changeset
   280
                        0,              // default attributes
489c9b5090e2 Initial load
duke
parents:
diff changeset
   281
                        NULL);          // no template file
489c9b5090e2 Initial load
duke
parents:
diff changeset
   282
  return hPipe;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   283
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   284
489c9b5090e2 Initial load
duke
parents:
diff changeset
   285
// write to the pipe
489c9b5090e2 Initial load
duke
parents:
diff changeset
   286
BOOL Win32AttachOperation::write_pipe(HANDLE hPipe, char* buf, int len) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   287
  do {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   288
    DWORD nwrote;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   289
489c9b5090e2 Initial load
duke
parents:
diff changeset
   290
    BOOL fSuccess = WriteFile(  hPipe,                  // pipe handle
489c9b5090e2 Initial load
duke
parents:
diff changeset
   291
                                (LPCVOID)buf,           // message
489c9b5090e2 Initial load
duke
parents:
diff changeset
   292
                                (DWORD)len,             // message length
489c9b5090e2 Initial load
duke
parents:
diff changeset
   293
                                &nwrote,                // bytes written
489c9b5090e2 Initial load
duke
parents:
diff changeset
   294
                                NULL);                  // not overlapped
489c9b5090e2 Initial load
duke
parents:
diff changeset
   295
    if (!fSuccess) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   296
      return fSuccess;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   297
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   298
    buf += nwrote;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   299
    len -= nwrote;
58678
9cf78a70fa4f datagramsocketimpl-branch: update to default
chegar
parents: 51584
diff changeset
   300
  } while (len > 0);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   301
  return TRUE;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   302
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   303
489c9b5090e2 Initial load
duke
parents:
diff changeset
   304
// Complete the operation:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   305
//   - open the pipe to the client
489c9b5090e2 Initial load
duke
parents:
diff changeset
   306
//   - write the operation result (a jint)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   307
//   - write the operation output (the result stream)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   308
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   309
void Win32AttachOperation::complete(jint result, bufferedStream* result_stream) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   310
  JavaThread* thread = JavaThread::current();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   311
  ThreadBlockInVM tbivm(thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   312
489c9b5090e2 Initial load
duke
parents:
diff changeset
   313
  thread->set_suspend_equivalent();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   314
  // cleared by handle_special_suspend_equivalent_condition() or
489c9b5090e2 Initial load
duke
parents:
diff changeset
   315
  // java_suspend_self() via check_and_wait_while_suspended()
489c9b5090e2 Initial load
duke
parents:
diff changeset
   316
489c9b5090e2 Initial load
duke
parents:
diff changeset
   317
  HANDLE hPipe = open_pipe();
58678
9cf78a70fa4f datagramsocketimpl-branch: update to default
chegar
parents: 51584
diff changeset
   318
  int lastError = (int)::GetLastError();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   319
  if (hPipe != INVALID_HANDLE_VALUE) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   320
    BOOL fSuccess;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   321
489c9b5090e2 Initial load
duke
parents:
diff changeset
   322
    char msg[32];
27471
6e56277909f1 8062370: Various minor code improvements
goetz
parents: 18931
diff changeset
   323
    _snprintf(msg, sizeof(msg), "%d\n", result);
6e56277909f1 8062370: Various minor code improvements
goetz
parents: 18931
diff changeset
   324
    msg[sizeof(msg) - 1] = '\0';
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   325
489c9b5090e2 Initial load
duke
parents:
diff changeset
   326
    fSuccess = write_pipe(hPipe, msg, (int)strlen(msg));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   327
    if (fSuccess) {
49742
1196aa0be8be 8201247: Various cleanups in the attach framework
clanger
parents: 49449
diff changeset
   328
      fSuccess = write_pipe(hPipe, (char*)result_stream->base(), (int)(result_stream->size()));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   329
    }
58678
9cf78a70fa4f datagramsocketimpl-branch: update to default
chegar
parents: 51584
diff changeset
   330
    lastError = (int)::GetLastError();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   331
489c9b5090e2 Initial load
duke
parents:
diff changeset
   332
    // Need to flush buffers
489c9b5090e2 Initial load
duke
parents:
diff changeset
   333
    FlushFileBuffers(hPipe);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   334
    CloseHandle(hPipe);
49742
1196aa0be8be 8201247: Various cleanups in the attach framework
clanger
parents: 49449
diff changeset
   335
1196aa0be8be 8201247: Various cleanups in the attach framework
clanger
parents: 49449
diff changeset
   336
    if (fSuccess) {
1196aa0be8be 8201247: Various cleanups in the attach framework
clanger
parents: 49449
diff changeset
   337
      log_debug(attach)("wrote result of attach operation %s to pipe %s", name(), pipe());
1196aa0be8be 8201247: Various cleanups in the attach framework
clanger
parents: 49449
diff changeset
   338
    } else {
58678
9cf78a70fa4f datagramsocketimpl-branch: update to default
chegar
parents: 51584
diff changeset
   339
      log_error(attach)("failure (%d) writing result of operation %s to pipe %s", lastError, name(), pipe());
49742
1196aa0be8be 8201247: Various cleanups in the attach framework
clanger
parents: 49449
diff changeset
   340
    }
1196aa0be8be 8201247: Various cleanups in the attach framework
clanger
parents: 49449
diff changeset
   341
  } else {
58678
9cf78a70fa4f datagramsocketimpl-branch: update to default
chegar
parents: 51584
diff changeset
   342
    log_error(attach)("could not open (%d) pipe %s to send result of operation %s", lastError, pipe(), name());
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   343
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   344
489c9b5090e2 Initial load
duke
parents:
diff changeset
   345
  DWORD res = ::WaitForSingleObject(Win32AttachListener::mutex(), INFINITE);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   346
  if (res == WAIT_OBJECT_0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   347
489c9b5090e2 Initial load
duke
parents:
diff changeset
   348
    // put the operation back on the available list
489c9b5090e2 Initial load
duke
parents:
diff changeset
   349
    set_next(Win32AttachListener::available());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   350
    Win32AttachListener::set_available(this);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   351
489c9b5090e2 Initial load
duke
parents:
diff changeset
   352
    ::ReleaseMutex(Win32AttachListener::mutex());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   353
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   354
489c9b5090e2 Initial load
duke
parents:
diff changeset
   355
  // were we externally suspended while we were waiting?
489c9b5090e2 Initial load
duke
parents:
diff changeset
   356
  thread->check_and_wait_while_suspended();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   357
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   358
489c9b5090e2 Initial load
duke
parents:
diff changeset
   359
489c9b5090e2 Initial load
duke
parents:
diff changeset
   360
// AttachOperation functions
489c9b5090e2 Initial load
duke
parents:
diff changeset
   361
489c9b5090e2 Initial load
duke
parents:
diff changeset
   362
AttachOperation* AttachListener::dequeue() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   363
  JavaThread* thread = JavaThread::current();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   364
  ThreadBlockInVM tbivm(thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   365
489c9b5090e2 Initial load
duke
parents:
diff changeset
   366
  thread->set_suspend_equivalent();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   367
  // cleared by handle_special_suspend_equivalent_condition() or
489c9b5090e2 Initial load
duke
parents:
diff changeset
   368
  // java_suspend_self() via check_and_wait_while_suspended()
489c9b5090e2 Initial load
duke
parents:
diff changeset
   369
489c9b5090e2 Initial load
duke
parents:
diff changeset
   370
  AttachOperation* op = Win32AttachListener::dequeue();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   371
489c9b5090e2 Initial load
duke
parents:
diff changeset
   372
  // were we externally suspended while we were waiting?
489c9b5090e2 Initial load
duke
parents:
diff changeset
   373
  thread->check_and_wait_while_suspended();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   374
489c9b5090e2 Initial load
duke
parents:
diff changeset
   375
  return op;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   376
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   377
18931
5de3638104b4 7162400: Intermittent java.io.IOException: Bad file number during HotSpotVirtualMachine.executeCommand
allwin
parents: 7397
diff changeset
   378
void AttachListener::vm_start() {
5de3638104b4 7162400: Intermittent java.io.IOException: Bad file number during HotSpotVirtualMachine.executeCommand
allwin
parents: 7397
diff changeset
   379
  // nothing to do
5de3638104b4 7162400: Intermittent java.io.IOException: Bad file number during HotSpotVirtualMachine.executeCommand
allwin
parents: 7397
diff changeset
   380
}
5de3638104b4 7162400: Intermittent java.io.IOException: Bad file number during HotSpotVirtualMachine.executeCommand
allwin
parents: 7397
diff changeset
   381
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   382
int AttachListener::pd_init() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   383
  return Win32AttachListener::init();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   384
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   385
58678
9cf78a70fa4f datagramsocketimpl-branch: update to default
chegar
parents: 51584
diff changeset
   386
// This function is used for Un*x OSes only.
9cf78a70fa4f datagramsocketimpl-branch: update to default
chegar
parents: 51584
diff changeset
   387
// We need not to implement it for Windows.
9cf78a70fa4f datagramsocketimpl-branch: update to default
chegar
parents: 51584
diff changeset
   388
bool AttachListener::check_socket_file() {
9cf78a70fa4f datagramsocketimpl-branch: update to default
chegar
parents: 51584
diff changeset
   389
  return false;
9cf78a70fa4f datagramsocketimpl-branch: update to default
chegar
parents: 51584
diff changeset
   390
}
9cf78a70fa4f datagramsocketimpl-branch: update to default
chegar
parents: 51584
diff changeset
   391
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   392
bool AttachListener::init_at_startup() {
35212
7a6d0993a080 8048521: Remove obsolete code from os_windows.cpp/hpp
ctornqvi
parents: 33794
diff changeset
   393
  return true;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   394
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   395
489c9b5090e2 Initial load
duke
parents:
diff changeset
   396
// no trigger mechanism on Windows to start Attach Listener lazily
489c9b5090e2 Initial load
duke
parents:
diff changeset
   397
bool AttachListener::is_init_trigger() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   398
  return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   399
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   400
489c9b5090e2 Initial load
duke
parents:
diff changeset
   401
void AttachListener::abort() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   402
  // nothing to do
489c9b5090e2 Initial load
duke
parents:
diff changeset
   403
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   404
489c9b5090e2 Initial load
duke
parents:
diff changeset
   405
void AttachListener::pd_data_dump() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   406
  os::signal_notify(SIGBREAK);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   407
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   408
489c9b5090e2 Initial load
duke
parents:
diff changeset
   409
AttachOperationFunctionInfo* AttachListener::pd_find_operation(const char* n) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   410
  return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   411
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   412
489c9b5090e2 Initial load
duke
parents:
diff changeset
   413
jint AttachListener::pd_set_flag(AttachOperation* op, outputStream* out) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   414
  out->print_cr("flag '%s' cannot be changed", op->arg(0));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   415
  return JNI_ERR;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   416
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   417
489c9b5090e2 Initial load
duke
parents:
diff changeset
   418
void AttachListener::pd_detachall() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   419
  // do nothing for now
489c9b5090e2 Initial load
duke
parents:
diff changeset
   420
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   421
489c9b5090e2 Initial load
duke
parents:
diff changeset
   422
// Native thread started by remote client executes this.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   423
extern "C" {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   424
  JNIEXPORT jint JNICALL
489c9b5090e2 Initial load
duke
parents:
diff changeset
   425
    JVM_EnqueueOperation(char* cmd, char* arg0, char* arg1, char* arg2, char* pipename) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   426
      return (jint)Win32AttachListener::enqueue(cmd, arg0, arg1, arg2, pipename);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   427
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   428
489c9b5090e2 Initial load
duke
parents:
diff changeset
   429
} // extern