diff options
Diffstat (limited to 'node/IpcConnection.cpp')
-rw-r--r-- | node/IpcConnection.cpp | 110 |
1 files changed, 68 insertions, 42 deletions
diff --git a/node/IpcConnection.cpp b/node/IpcConnection.cpp index f0e09449..5924f545 100644 --- a/node/IpcConnection.cpp +++ b/node/IpcConnection.cpp @@ -47,10 +47,13 @@ IpcConnection::IpcConnection(const char *endpoint,void (*commandHandler)(void *, _handler(commandHandler), _arg(arg), #ifdef __WINDOWS__ - _sock(INVALID_HANDLE_VALUE) + _sock(INVALID_HANDLE_VALUE), + _incoming(false), #else - _sock(0) + _sock(-1), #endif + _run(true), + _running(true) { #ifdef __WINDOWS__ _sock = CreateFileA(endpoint,GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,NULL,OPEN_EXISTING,0,NULL); @@ -74,7 +77,7 @@ IpcConnection::IpcConnection(const char *endpoint,void (*commandHandler)(void *, } #endif - Thread::start(this); + _thread = Thread::start(this); } #ifdef __WINDOWS__ @@ -84,19 +87,26 @@ IpcConnection::IpcConnection(int s,void (*commandHandler)(void *,IpcConnection * #endif _handler(commandHandler), _arg(arg), - _sock(s) + _sock(s), +#ifdef __WINDOWS__ + _incoming(true), +#endif + _run(true), + _running(true) { - Thread::start(this); + _thread = Thread::start(this); } IpcConnection::~IpcConnection() { _writeLock.lock(); + _run = false; + _writeLock.unlock(); + #ifdef __WINDOWS__ - HANDLE s = _sock; - _sock = INVALID_HANDLE_VALUE; - if (s != INVALID_HANDLE_VALUE) { - CloseHandle(s); + while (_running) { + Thread::cancelIO(_thread); + Sleep(100); } #else int s = _sock; @@ -106,7 +116,6 @@ IpcConnection::~IpcConnection() ::close(s); } #endif - _writeLock.unlock(); } void IpcConnection::printf(const char *format,...) @@ -115,22 +124,20 @@ void IpcConnection::printf(const char *format,...) int n; char tmp[65536]; - Mutex::Lock _l(_writeLock); - - if (_sock <= 0) - return; - va_start(ap,format); n = (int)::vsnprintf(tmp,sizeof(tmp),format,ap); va_end(ap); if (n <= 0) return; + Mutex::Lock _l(_writeLock); + #ifdef __WINDOWS__ - DWORD bsent = 0; - WriteFile(_sock,tmp,n,&bsent,NULL); + _writeBuf.append(tmp,n); + Thread::cancelIO(_thread); #else - ::write(_sock,tmp,n); + if (_sock > 0) + ::write(_sock,tmp,n); #endif } @@ -140,29 +147,51 @@ void IpcConnection::threadMain() char tmp[65536]; char linebuf[65536]; unsigned int lineptr = 0; + char c; + #ifdef __WINDOWS__ - HANDLE s; DWORD n,i; + std::string wbuf; #else int s,n,i; #endif - char c; - for(;;) { + while (_run) { #ifdef __WINDOWS__ - s = _sock; - if (s == INVALID_HANDLE_VALUE) - break; - if (!ReadFile(s,tmp,sizeof(tmp),&n,NULL)) + { + Mutex::Lock _l(_writeLock); + if (!_run) + break; + if (_writeBuf.length() > 0) { + wbuf.append(_writeBuf); + _writeBuf.clear(); + } + } + if (wbuf.length() > 0) { + n = 0; + if ((WriteFile(_sock,wbuf.data(),(DWORD)(wbuf.length()),&n,NULL))&&(n > 0)) { + if (n < (DWORD)wbuf.length()) + wbuf.erase(0,n); + else wbuf.clear(); + } else if (GetLastError() != ERROR_OPERATION_ABORTED) + break; + FlushFileBuffers(_sock); + } + if (!_run) break; - if (n < 0) + n = 0; + if ((!ReadFile(_sock,tmp,sizeof(tmp),&n,NULL))||(n <= 0)) { + if (GetLastError() == ERROR_OPERATION_ABORTED) + n = 0; + else break; + } + if (!_run) break; #else - s = _sock; - if (s <= 0) + if ((s = _sock) <= 0) break; n = (int)::read(s,tmp,sizeof(tmp)); - if (n <= 0) + if ((n <= 0)||(_sock <= 0)) break; #endif for(i=0;i<n;++i) { @@ -177,22 +206,19 @@ void IpcConnection::threadMain() } } - { - _writeLock.lock(); - s = _sock; + _writeLock.lock(); + bool r = _run; + _writeLock.unlock(); + #ifdef __WINDOWS__ - _sock = INVALID_HANDLE_VALUE; - if (s != INVALID_HANDLE_VALUE) - CloseHandle(s); -#else - _sock = 0; - if (s > 0) - ::close(s); + if (_incoming) + DisconnectNamedPipe(_sock); + CloseHandle(_sock); + _running = false; #endif - _writeLock.unlock(); - } - _handler(_arg,this,IPC_EVENT_CONNECTION_CLOSED,(const char *)0); + if (r) + _handler(_arg,this,IPC_EVENT_CONNECTION_CLOSED,(const char *)0); } } // namespace ZeroTier |