Mercurial > hg > truffle
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_