Main Page   Modules   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

PServer.cpp

Go to the documentation of this file.
00001 // PServer.cpp: implementation of the PServer class.
00004 
00005 
00006 #include "stdafx.h"
00007 #include "PServer.h"
00008 #include "errorCodes.h"
00009 
00011 // Construction/Destruction
00013 
00022 PServer::PServer(const TString &name, const bool isOut, const DWORD bufferSize)
00023 : Pipe( name, isOut )
00024 {
00025     hConnectThread = NULL;
00026     connected = false;
00027 
00028     if( isOutbound ){
00029         in = 0;
00030         out = bufferSize;
00031     } else {
00032         in = bufferSize;
00033         out = 0;
00034     }
00035 }
00036 
00040 PServer::~PServer()
00041 {
00042     disconnect();
00043     if(hConnectThread != NULL)
00044         CloseHandle(hConnectThread);
00045 }
00046 
00048 // Member Functions
00050 
00057 void PServer::disconnect()
00058 {
00059     if( getAttemptConnectResult() == PS_WAITING ) {
00061         TerminateThread(hConnectThread, PS_CANCELLED);  
00062         connected = false;
00063     }
00064     
00065     connected = false;
00066     DisconnectNamedPipe(hPipe);
00067     CloseHandle(hPipe);
00068     
00069     ResetEvent(clientStayConnected);
00070 }
00071 
00077 bool PServer::serve()
00078 {
00079     if( PServer::isConnected() ){
00080         return true;
00081     }
00082 
00083     if( WaitForSingleObject(serverStayConnected, 0) == WAIT_OBJECT_0 ){
00084         return false; // Client yet to process disconnect request
00085     }
00086 
00087     hPipe = CreateNamedPipe(
00088         pipeName,           // pipe name
00089         isOutbound ? PIPE_ACCESS_OUTBOUND : PIPE_ACCESS_INBOUND,    // pipe open mode
00090         0,                  // Byte mode, blocking operations
00091         1,                  // Maximum pipe Instances
00092         out,                // output buffer size
00093         in,                 // input buffer size
00094         NMPWAIT_WAIT_FOREVER,   // default time-out interval
00095         NULL);              // Default Security, non inheritable
00096 
00097     if( GetLastError() == ERROR_ALREADY_EXISTS ) {
00098         CloseHandle(hPipe);  // Close duplicated handle
00099         hPipe = INVALID_HANDLE_VALUE;
00100     }
00101     if ( hPipe == INVALID_HANDLE_VALUE ) {
00102         return false;
00103     }
00104     
00105     if(hConnectThread != NULL)
00106         CloseHandle(hConnectThread);
00107 
00108     hConnectThread = chBEGINTHREADEX(
00109         NULL,           // Default Security, non inheritable
00110         0,              // use default stack size  
00111         &waitForClient, // thread function
00112         this,           // thread argument
00113         0,              // use default creation flags 
00114         NULL);          // don't need thread identifier
00115 
00116     if(hConnectThread == NULL){
00117         CloseHandle(hPipe);
00118         return false;
00119     }
00120 
00121     return true;
00122 }
00123 
00127 DWORD WINAPI PServer::waitForClient(LPVOID param)
00128 {
00129     PServer* server = (PServer*) param;
00130 
00131     // Wait for the client to connect; if it succeeds, 
00132     // the function returns a nonzero value. If the function returns 
00133     // zero, GetLastError returns ERROR_PIPE_CONNECTED.
00134     server->connected = ConnectNamedPipe(server->hPipe, NULL) ? 
00135         true : (GetLastError() == ERROR_PIPE_CONNECTED);
00136 
00137     if( server->connected ){
00138         return PS_CONNECTED;
00139     } else {
00140         return PS_FAILED;
00141     }
00142 
00143 }
00144 
00148 HANDLE PServer::getConnectedEventHandle()
00149 {
00150     HANDLE rtrn;
00151 
00152     // The thread handle can be used as an event object.
00153     // becomes signalled when the thread stops running
00154 
00155     DuplicateHandle(
00156         GetCurrentProcess(),
00157         hConnectThread,     // handle to duplicate
00158         GetCurrentProcess(),
00159         &rtrn,              // duplicate handle
00160         SYNCHRONIZE,        // handle can only be used to wait on
00161         false,              // non inheritable
00162         0);                 // no extra options
00163 
00164     return rtrn;
00165 }
00166 
00170 DWORD PServer::getAttemptConnectResult() const
00171 {
00172     DWORD exitCode;
00173     GetExitCodeThread(hConnectThread, &exitCode);
00174 
00175     return exitCode;
00176 }
00177 
00185 bool PServer::isConnected()
00186 {
00187     if( WaitForSingleObject(clientStayConnected, 0) == WAIT_OBJECT_0 ){
00188         this->disconnect();
00189     }
00190 
00191     return connected;
00192 }

Generated on Mon Mar 25 06:29:59 2002 for Window Dressing by doxygen1.2.13.1 written by Dimitri van Heesch, © 1997-2001