diff agent/src/os/win32/serverLists.hpp @ 0:a61af66fc99e jdk7-b24

Initial load
author duke
date Sat, 01 Dec 2007 00:00:00 +0000
parents
children c18cbe5936b8
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/agent/src/os/win32/serverLists.hpp	Sat Dec 01 00:00:00 2007 +0000
@@ -0,0 +1,204 @@
+/*
+ * Copyright 2000-2003 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+#ifndef _SERVER_LISTS_
+#define _SERVER_LISTS_
+
+#include <vector>
+#include <winsock2.h>
+#include "IOBuf.hpp"
+
+//
+// NOTE:
+//
+// All of these lists are guarded by the global lock managed by the
+// Lists class. Lists::init() must be called at the start of the
+// program.
+//
+
+class Lists {
+  friend class ListsLocker;
+public:
+  static void init();
+private:
+  static void lock();
+  static void unlock();
+  static CRITICAL_SECTION crit;
+};
+
+// Should be allocated on stack. Ensures proper locking/unlocking
+// pairing.
+class ListsLocker {
+public:
+  ListsLocker();
+  ~ListsLocker();
+};
+
+// We must keep track of all of the child processes we have forked to
+// handle attaching to a target process. This is necessary because we
+// allow clients to detach from processes, but the child processes we
+// fork must necessarily stay alive for the duration of the target
+// application. A subsequent attach operation to the target process
+// results in the same child process being reused. For this reason,
+// child processes are known to be in one of two states: attached and
+// detached.
+
+class ClientInfo;
+
+class ChildInfo {
+public:
+  /** The pid of the ChildInfo indicates the process ID of the target
+      process which the subprocess was created to debug, not the pid
+      of the subprocess itself. */
+  ChildInfo(DWORD pid, HANDLE childProcessHandle,
+            HANDLE writeToStdinHandle, HANDLE readFromStdoutHandle,
+            HANDLE auxHandle1, HANDLE auxHandle2);
+
+  DWORD getPid();
+  HANDLE getChildProcessHandle();
+  HANDLE getWriteToStdinHandle();
+  HANDLE getReadFromStdoutHandle();
+
+  /** Set the client which is currently attached to the target process
+      via this child process. Set this to NULL to indicate that the
+      child process is ready to accept another attachment. */
+  void setClient(ClientInfo* clientInfo);
+
+  ClientInfo* getClient();
+
+  /** This is NOT automatically called in the destructor */
+  void closeAll();
+
+private:
+  DWORD pid;
+  HANDLE childProcessHandle;
+  HANDLE writeToStdinHandle;
+  HANDLE readFromStdoutHandle;
+  HANDLE auxHandle1;
+  HANDLE auxHandle2;
+  ClientInfo* client;
+};
+
+// We keep track of a list of child debugger processes, each of which
+// is responsible for debugging a certain target process. These
+// debugger processes can serve multiple clients during their
+// lifetime. When a client detaches from a given process or tells the
+// debugger to "exit", the debug server is notified that the child
+// process is once again available to accept connections from clients.
+
+class ChildList {
+private:
+  typedef std::vector<ChildInfo*> ChildInfoList;
+
+public:
+  ChildList();
+  ~ChildList();
+
+  void addChild(ChildInfo*);
+
+  /** Removes and returns the ChildInfo* associated with the given
+      child process handle. */
+  ChildInfo* removeChild(HANDLE childProcessHandle);
+
+  /** Removes the given ChildInfo. */
+  void removeChild(ChildInfo* info);
+
+  /** Return the ChildInfo* associated with a given process ID without
+      removing it from the list. */
+  ChildInfo* getChildByPid(DWORD pid);
+
+  /** Iteration support */
+  int size();
+
+  /** Iteration support */
+  ChildInfo* getChildByIndex(int index);
+
+private:
+  ChildInfoList childList;
+};
+
+// We also keep a list of clients whose requests we are responsible
+// for serving. Clients can attach and detach from child processes.
+
+class ClientInfo {
+public:
+  ClientInfo(SOCKET dataSocket);
+  ~ClientInfo();
+
+  SOCKET getDataSocket();
+  /** Gets an IOBuf configured for the data socket, which should be
+      used for all communication with the client. */
+  IOBuf* getIOBuf();
+
+  /** Set the information for the process to which this client is
+      attached. Set this to NULL to indicate that the client is not
+      currently attached to any target process. */
+  void setTarget(ChildInfo* childInfo);
+
+  /** Get the information for the process to which this client is
+      currently attached, or NULL if none. */
+  ChildInfo* getTarget();
+
+  /** Close down the socket connection to this client. This is NOT
+      automatically called by the destructor. */
+  void closeAll();
+
+private:
+  SOCKET dataSocket;
+  IOBuf* buf;
+  ChildInfo* target;
+};
+
+class ClientList {
+private:
+  typedef std::vector<ClientInfo*> ClientInfoList;
+
+public:
+  ClientList();
+  ~ClientList();
+
+  /** Adds a client to the list. */
+  void addClient(ClientInfo* info);
+
+  /** Check to see whether the parent socket of any of the ClientInfo
+      objects is readable in the given fd_set. If so, returns TRUE and
+      sets the given ClientInfo* (a non-NULL pointer to which must be
+      given) appropriately. */
+  bool isAnyDataSocketSet(fd_set* fds, ClientInfo** info);
+
+  /** Removes a client from the list. User is responsible for deleting
+      the ClientInfo* using operator delete. */
+  void removeClient(ClientInfo* client);
+
+  /** Iteration support. */
+  int size();
+
+  /** Iteration support. */
+  ClientInfo* get(int num);
+
+private:
+  ClientInfoList clientList;
+};
+
+#endif  // #defined _SERVER_LISTS_