pipeConnectionWin32.cpp

00001 
00002 /* Copyright (c) 2007-2008, Stefan Eilemann <eile@equalizergraphics.com> 
00003  *
00004  * This library is free software; you can redistribute it and/or modify it under
00005  * the terms of the GNU Lesser General Public License version 2.1 as published
00006  * by the Free Software Foundation.
00007  *  
00008  * This library is distributed in the hope that it will be useful, but WITHOUT
00009  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00010  * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
00011  * details.
00012  * 
00013  * You should have received a copy of the GNU Lesser General Public License
00014  * along with this library; if not, write to the Free Software Foundation, Inc.,
00015  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
00016  */
00017 
00018 #include "pipeConnection.h"
00019 
00020 #include "connectionDescription.h"
00021 #include "node.h"
00022 
00023 #include <eq/base/log.h>
00024 #include <eq/base/thread.h>
00025 
00026 using namespace eq::base;
00027 using namespace std;
00028 
00029 #ifdef WIN32
00030 
00031 namespace eq
00032 {
00033 namespace net
00034 {
00035 
00036 PipeConnection::PipeConnection()
00037         : _readHandle( 0 ),
00038           _writeHandle( 0 ),
00039           _size( 0 ),
00040           _dataPending( CreateEvent( 0, TRUE, FALSE, 0 ))
00041 
00042 {
00043     _description = new ConnectionDescription;
00044     _description->type = CONNECTIONTYPE_PIPE;
00045 }
00046 
00047 PipeConnection::~PipeConnection()
00048 {
00049     close();
00050     CloseHandle( _dataPending );
00051 }
00052 
00053 //----------------------------------------------------------------------
00054 // connect
00055 //----------------------------------------------------------------------
00056 bool PipeConnection::connect()
00057 {
00058     EQASSERT( _description->type == CONNECTIONTYPE_PIPE );
00059 
00060     if( _state != STATE_CLOSED )
00061         return false;
00062 
00063     _state = STATE_CONNECTING;
00064     _size  = 0;
00065 
00066     if( !_createPipe( ))
00067     {
00068         close();
00069         return false;
00070     }
00071 
00072     _state = STATE_CONNECTED;
00073     _fireStateChanged();
00074     return true;
00075 }
00076 
00077 bool PipeConnection::_createPipe()
00078 {
00079     if( CreatePipe( &_readHandle, &_writeHandle, 0, 0 ) == 0 )
00080     {
00081         EQERROR << "Could not create pipe: " << getErrorString( GetLastError( ))
00082                 << endl;
00083         close();
00084         return false;
00085     }
00086     return true;
00087 }
00088 
00089 void PipeConnection::close()
00090 {
00091     if( _readHandle )
00092     {
00093         CloseHandle( _readHandle );
00094         _readHandle = 0;
00095     }
00096     if( _writeHandle )
00097     {
00098         CloseHandle( _writeHandle );
00099         _writeHandle = 0;
00100     }
00101     _state = STATE_CLOSED;
00102     _fireStateChanged();
00103 }
00104 void PipeConnection::readNB( void* buffer, const uint64_t bytes ) { /* NOP */ }
00105 int64_t PipeConnection::readSync( void* buffer, const uint64_t bytes )
00106 {
00107     if( !_readHandle )
00108         return -1;
00109 
00110     DWORD bytesRead = 0;
00111     const BOOL ret = ReadFile( _readHandle, buffer, static_cast<DWORD>( bytes ),
00112                                &bytesRead, 0 );
00113 
00114     if( ret == 0 ) // Error
00115     {
00116         EQWARN << "Error during read: " << getErrorString( GetLastError( ))
00117                << endl;
00118         return -1;
00119     }
00120 
00121     if( bytesRead == 0 ) // EOF
00122     {
00123         close();
00124         return -1;
00125     }
00126 
00127     _mutex.set();
00128     EQASSERT( _size >= bytesRead );
00129     _size -= bytesRead;
00130     if( _size == 0 )
00131         ResetEvent( _dataPending );
00132     _mutex.unset();
00133 
00134     return bytesRead;
00135 }
00136 
00137 int64_t PipeConnection::write( const void* buffer, const uint64_t bytes )
00138 {
00139     if( !_writeHandle )
00140         return -1;
00141 
00142     const DWORD write = EQ_MIN( static_cast<DWORD>( bytes ), 4096 );
00143 
00144     _mutex.set();
00145     _size += write; // speculatively 'write' everything
00146     _mutex.unset();
00147 
00148     DWORD bytesWritten = 0;
00149     const BOOL ret = WriteFile( _writeHandle, buffer, write, &bytesWritten, 0 );
00150 
00151     if( ret == 0 ) // Error
00152     {
00153         EQWARN << "Error during write: " << getErrorString( GetLastError( ))
00154                << endl;
00155         bytesWritten = 0;
00156     }
00157 
00158     _mutex.set();
00159     EQASSERT( _size >= write - bytesWritten );
00160     _size -= (write - bytesWritten); // correct size
00161 
00162     if( _size > 0 )
00163         SetEvent( _dataPending );
00164     else
00165     {
00166         EQASSERT( _size == 0 );
00167         ResetEvent( _dataPending );
00168     }
00169     _mutex.unset();
00170 
00171     if( ret==0 ) 
00172         return -1;
00173     return bytesWritten;
00174 }
00175 }
00176 }
00177 #else
00178 #  error "File is only for WIN32 builds"
00179 #endif
Generated on Mon Aug 10 18:58:40 2009 for Equalizer 0.9 by  doxygen 1.5.8