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 }
ConstSocketRef AbstractReflectSession :: CreateDefaultSocket() { return ConstSocketRef(); // NULL Ref means run clientless by default }