StdinDataIO :: StdinDataIO(bool blocking, bool writeToStdout) : _stdinBlocking(blocking) , _writeToStdout(writeToStdout) #ifdef USE_WIN32_STDINDATAIO_IMPLEMENTATION , _slaveSocketTag(0) #else , _fdIO(ConstSocketRef(&_stdinSocket, false), true) #endif { #ifdef USE_WIN32_STDINDATAIO_IMPLEMENTATION if (_stdinBlocking == false) { // For non-blocking I/O, we need to handle stdin in a separate thread. // note that I freopen stdin to "nul" so that other code (read: Python) // won't try to muck about with stdin and interfere with StdinDataIO's // operation. I don't know of any good way to restore it again after, // though... so a side effect of StdinDataIO under Windows is that // stdin gets redirected to nul... once you've created one non-blocking // StdinDataIO, you'll need to continue accessing stdin only via // non-blocking StdinDataIOs. bool okay = false; ConstSocketRef slaveSocket; if ((CreateConnectedSocketPair(_masterSocket, slaveSocket, false) == B_NO_ERROR)&&(SetSocketBlockingEnabled(slaveSocket, true) == B_NO_ERROR)&&(_slaveSocketsMutex.Lock() == B_NO_ERROR)) { bool threadCreated = false; if (_stdinThreadStatus == STDIN_THREAD_STATUS_UNINITIALIZED) { DWORD junkThreadID; #if __STDC_WANT_SECURE_LIB__ FILE * junkFD; #endif _stdinThreadStatus = ((DuplicateHandle(GetCurrentProcess(), GetStdHandle(STD_INPUT_HANDLE), GetCurrentProcess(), &_stdinHandle, 0, false, DUPLICATE_SAME_ACCESS))&& #if __STDC_WANT_SECURE_LIB__ (freopen_s(&junkFD, "nul", "r", stdin) == 0) #else (freopen("nul", "r", stdin) != NULL) #endif &&((_slaveThread = (::HANDLE) _beginthreadex(NULL, 0, StdinThreadEntryFunc, NULL, CREATE_SUSPENDED, (unsigned *) &junkThreadID)) != 0)) ? STDIN_THREAD_STATUS_RUNNING : STDIN_THREAD_STATUS_EXITED; threadCreated = (_stdinThreadStatus == STDIN_THREAD_STATUS_RUNNING); } if ((_stdinThreadStatus == STDIN_THREAD_STATUS_RUNNING)&&(_slaveSockets.Put(_slaveSocketTag = (++_slaveSocketTagCounter), slaveSocket) == B_NO_ERROR)) okay = true; else LogTime(MUSCLE_LOG_ERROR, "StdinDataIO: Could not start stdin thread!\n"); _slaveSocketsMutex.Unlock(); // We don't start the thread running until here, that way there's no chance of race conditions if the thread exits immediately if (threadCreated) ResumeThread(_slaveThread); } else LogTime(MUSCLE_LOG_ERROR, "StdinDataIO: Error setting up I/O sockets!\n"); if (okay == false) Close(); } #endif }
status_t AbstractReflectSession :: Reconnect() { TCHECKPOINT; #ifdef MUSCLE_ENABLE_SSL ConstByteBufferRef publicKey; // If it's an SSL connection we'll grab its key into here so we can reuse it #endif MASSERT(IsAttachedToServer(), "Can not call Reconnect() while not attached to the server"); if (_gateway()) { #ifdef MUSCLE_ENABLE_SSL SSLSocketDataIO * sdio = dynamic_cast<SSLSocketDataIO *>(_gateway()->GetDataIO()()); if (sdio) publicKey = sdio->GetPublicKeyCertificate(); #endif _gateway()->SetDataIO(DataIORef()); // get rid of any existing socket first _gateway()->Reset(); // set gateway back to its virgin state } _isConnected = _wasConnected = false; SetConnectingAsync(false); bool doTCPConnect = ((_reconnectViaTCP)&&(_asyncConnectDest.GetIPAddress() != invalidIP)); bool isReady = false; ConstSocketRef sock = doTCPConnect ? ConnectAsync(_asyncConnectDest.GetIPAddress(), _asyncConnectDest.GetPort(), isReady) : CreateDefaultSocket(); // FogBugz #5256: If ConnectAsync() fails, we want to act as if it succeeded, so that the calling // code still uses its normal asynchronous-connect-failure code path. That way the // caller doesn't have to worry about synchronous failure as a separate case. if ((doTCPConnect)&&(sock() == NULL)) { ConstSocketRef tempSockRef; // tempSockRef represents the closed remote end of the failed connection and is intentionally closed ASAP if (CreateConnectedSocketPair(sock, tempSockRef) == B_NO_ERROR) doTCPConnect = false; } if (sock()) { DataIORef io = CreateDataIO(sock); if (io()) { if (_gateway() == NULL) { _gateway = CreateGateway(); if (_gateway() == NULL) return B_ERROR; } #ifdef MUSCLE_ENABLE_SSL // auto-wrap the user's gateway and socket in the necessary SSL adapters! if ((publicKey())&&(dynamic_cast<TCPSocketDataIO *>(io()) != NULL)) { SSLSocketDataIO * ssio = newnothrow SSLSocketDataIO(sock, false, false); if (ssio == NULL) {WARN_OUT_OF_MEMORY; return B_ERROR;} io.SetRef(ssio); if (ssio->SetPublicKeyCertificate(publicKey) != B_NO_ERROR) return B_ERROR; if (dynamic_cast<SSLSocketAdapterGateway *>(_gateway()) == NULL) { _gateway.SetRef(newnothrow SSLSocketAdapterGateway(_gateway)); if (_gateway() == NULL) return B_ERROR; } } #endif _gateway()->SetDataIO(io); if (isReady) { _isConnected = _wasConnected = true; AsyncConnectCompleted(); } else { _isConnected = false; SetConnectingAsync(doTCPConnect); } _scratchReconnected = true; // tells ReflectServer not to shut down our new IO! return B_NO_ERROR; } } return B_ERROR; }
ConstSocketRef SignalHandlerSession :: CreateDefaultSocket() { ConstSocketRef sock; (void) CreateConnectedSocketPair(sock, _handlerSocket); return sock; }