Ignore:
Timestamp:
04/10/2008 00:22:36 (4 years ago)
Author:
chris
Message:

Remove Win32 command socket thread, as it has caused too much trouble.

Handle command socket on Win32 the same as all other platforms, removing
#ifdefs from BackupDaemon?.

Will replace this thread with regular but not excessive command socket
polling using timers in future.

Change error messages when command socket comms fail to make them clearer.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • box/trunk/lib/server/WinNamedPipeStream.cpp

    r2106 r2318  
    4545          mIsServer(false), 
    4646          mIsConnected(false) 
    47 { 
     47{ } 
     48 
     49// -------------------------------------------------------------------------- 
     50// 
     51// Function 
     52//              Name:    WinNamedPipeStream::WinNamedPipeStream(HANDLE) 
     53//              Purpose: Constructor (with already-connected pipe handle) 
     54//              Created: 2008/10/01 
     55// 
     56// -------------------------------------------------------------------------- 
     57WinNamedPipeStream::WinNamedPipeStream(HANDLE hNamedPipe) 
     58        : mSocketHandle(hNamedPipe), 
     59          mReadableEvent(INVALID_HANDLE_VALUE), 
     60          mBytesInBuffer(0), 
     61          mReadClosed(false), 
     62          mWriteClosed(false), 
     63          mIsServer(true), 
     64          mIsConnected(true) 
     65{  
     66        // create the Readable event 
     67        mReadableEvent = CreateEvent(NULL, TRUE, FALSE, NULL); 
     68 
     69        if (mReadableEvent == INVALID_HANDLE_VALUE) 
     70        { 
     71                BOX_ERROR("Failed to create the Readable event: " << 
     72                        GetErrorMessage(GetLastError())); 
     73                Close(); 
     74                THROW_EXCEPTION(CommonException, Internal) 
     75        } 
     76 
     77        // initialise the OVERLAPPED structure 
     78        memset(&mReadOverlap, 0, sizeof(mReadOverlap)); 
     79        mReadOverlap.hEvent = mReadableEvent; 
     80 
     81        // start the first overlapped read 
     82        if (!ReadFile(mSocketHandle, mReadBuffer, sizeof(mReadBuffer), 
     83                NULL, &mReadOverlap)) 
     84        { 
     85                DWORD err = GetLastError(); 
     86 
     87                if (err != ERROR_IO_PENDING) 
     88                { 
     89                        BOX_ERROR("Failed to start overlapped read: " << 
     90                                GetErrorMessage(err)); 
     91                        Close(); 
     92                        THROW_EXCEPTION(ConnectionException,  
     93                                Conn_SocketReadError) 
     94                } 
     95        } 
    4896} 
    4997 
     
    81129// 
    82130// -------------------------------------------------------------------------- 
    83 void WinNamedPipeStream::Accept(const std::string& rName) 
    84 { 
    85         if (mSocketHandle != INVALID_HANDLE_VALUE || mIsConnected)  
    86         { 
    87                 THROW_EXCEPTION(ServerException, SocketAlreadyOpen) 
    88         } 
    89  
    90         std::string socket = sPipeNamePrefix + rName; 
    91  
    92         mSocketHandle = CreateNamedPipeA(  
    93                 socket.c_str(),            // pipe name  
    94                 PIPE_ACCESS_DUPLEX |       // read/write access  
    95                 FILE_FLAG_OVERLAPPED,      // enabled overlapped I/O 
    96                 PIPE_TYPE_BYTE |           // message type pipe  
    97                 PIPE_READMODE_BYTE |       // message-read mode  
    98                 PIPE_WAIT,                 // blocking mode  
    99                 1,                         // max. instances   
    100                 4096,                      // output buffer size  
    101                 4096,                      // input buffer size  
    102                 NMPWAIT_USE_DEFAULT_WAIT,  // client time-out  
    103                 NULL);                     // default security attribute  
    104  
     131/* 
     132void WinNamedPipeStream::Accept() 
     133{ 
    105134        if (mSocketHandle == INVALID_HANDLE_VALUE) 
    106135        { 
    107                 BOX_ERROR("Failed to CreateNamedPipeA(" << socket << "): " << 
    108                         GetErrorMessage(GetLastError())); 
    109                 THROW_EXCEPTION(ServerException, SocketOpenError) 
     136                THROW_EXCEPTION(ServerException, BadSocketHandle); 
     137        } 
     138 
     139        if (mIsConnected)  
     140        { 
     141                THROW_EXCEPTION(ServerException, SocketAlreadyOpen); 
    110142        } 
    111143 
     
    157189        } 
    158190} 
     191*/ 
    159192 
    160193// -------------------------------------------------------------------------- 
     
    218251{ 
    219252        // TODO no support for timeouts yet 
    220         if (Timeout != IOStream::TimeOutInfinite) 
     253        if (!mIsServer && Timeout != IOStream::TimeOutInfinite) 
    221254        { 
    222255                THROW_EXCEPTION(CommonException, AssertFailed) 
     
    250283                        // overlapped I/O completed successfully?  
    251284                        // (wait if needed) 
    252  
    253                         if (GetOverlappedResult(mSocketHandle, 
     285                        DWORD waitResult = WaitForSingleObject( 
     286                                mReadOverlap.hEvent, Timeout); 
     287 
     288                        if (waitResult == WAIT_ABANDONED) 
     289                        { 
     290                                BOX_ERROR("Wait for command socket read " 
     291                                        "abandoned by system"); 
     292                                THROW_EXCEPTION(ServerException, 
     293                                        BadSocketHandle); 
     294                        } 
     295                        else if (waitResult == WAIT_TIMEOUT) 
     296                        { 
     297                                // wait timed out, nothing to read 
     298                                NumBytesRead = 0; 
     299                        } 
     300                        else if (waitResult != WAIT_OBJECT_0) 
     301                        { 
     302                                BOX_ERROR("Failed to wait for command " 
     303                                        "socket read: unknown result " << 
     304                                        waitResult); 
     305                        } 
     306                        // object is ready to read from 
     307                        else if (GetOverlappedResult(mSocketHandle, 
    254308                                &mReadOverlap, &NumBytesRead, TRUE)) 
    255309                        { 
     
    268322                                        if (err == ERROR_BROKEN_PIPE) 
    269323                                        { 
    270                                                 BOX_ERROR("Control client " 
     324                                                BOX_NOTICE("Control client " 
    271325                                                        "disconnected"); 
    272326                                        } 
     
    343397                        } 
    344398                } 
    345  
    346                 // If the read succeeded immediately, leave the event  
    347                 // signaled, so that we will be called again to process  
    348                 // the newly read data and start another overlapped read. 
    349                 if (needAnotherRead && !mReadClosed) 
    350                 { 
    351                         // leave signalled 
    352                 } 
    353                 else if (!needAnotherRead && mBytesInBuffer > 0) 
    354                 { 
    355                         // leave signalled 
    356                 } 
    357                 else 
    358                 { 
    359                         // nothing left to read, reset the event 
    360                         ResetEvent(mReadableEvent); 
    361                         // FIXME: a pending read could have signalled 
    362                         // the event (again) while we were busy reading. 
    363                         // that signal would be lost, and the reading 
    364                         // thread would block. Should be pretty obvious 
    365                         // if this happens in practice: control client 
    366                         // hangs. 
    367                 } 
    368399        } 
    369400        else 
     
    442473                { 
    443474                        // ERROR_NO_DATA is a strange name for  
    444                         // "The pipe is being closed". No exception wanted. 
     475                        // "The pipe is being closed". 
    445476 
    446477                        DWORD err = GetLastError(); 
     
    454485                        Close(); 
    455486 
    456                         if (err == ERROR_NO_DATA)  
    457                         { 
    458                                 return; 
    459                         } 
    460                         else 
    461                         { 
    462                                 THROW_EXCEPTION(ConnectionException,  
    463                                         Conn_SocketWriteError) 
    464                         } 
     487                        THROW_EXCEPTION(ConnectionException,  
     488                                Conn_SocketWriteError) 
    465489                } 
    466490 
Note: See TracChangeset for help on using the changeset viewer.