void AsyncFileWriter::ioThread() { folly::setThreadName("log_writer"); while (true) { // With the lock held, grab a pointer to the current queue, then increment // the ioThreadCounter index so that other threads will write into the // other queue as we process this one. std::vector<std::string>* ioQueue; size_t numDiscarded; bool stop; { auto data = data_.lock(); ioQueue = data->getCurrentQueue(); while (ioQueue->empty() && !data->stop) { messageReady_.wait(data.getUniqueLock()); } ++data->ioThreadCounter; numDiscarded = data->numDiscarded; data->numDiscarded = 0; data->currentBufferSize = 0; stop = data->stop; } ioCV_.notify_all(); // Write the log messages now that we have released the lock try { performIO(ioQueue); } catch (const std::exception& ex) { onIoError(ex); } // clear() empties the vector, but the allocated capacity remains so we can // just reuse it without having to re-allocate in most cases. ioQueue->clear(); if (numDiscarded > 0) { auto msg = getNumDiscardedMsg(numDiscarded); if (!msg.empty()) { auto ret = folly::writeFull(file_.fd(), msg.data(), msg.size()); // We currently ignore errors from writeFull() here. // There's not much we can really do. (void)ret; } } if (stop) { data_->ioThreadDone = true; break; } } }
void main(int argc, char *argv[]) #endif { char szText[160]; bool bSuccess; short nTries = 0; // Set results of what happens when a call to new fails set_new_handler(badNew); // Call the startup function #ifdef OD32 startup(lpszCmdLine); #else startup(argc, argv); #endif Sleep(500); do { // Attempt to start up the door server process. (No need to check if the door server process is already // running; it does that on its own and shuts down extra copies as needed) bSuccess = CreateProcess(DOOR_SERVER_EXE, NULL, NULL, NULL, false, DETACHED_PROCESS, NULL, NULL, new STARTUPINFO, new PROCESS_INFORMATION); Sleep(1000); nTries++; } while ( bSuccess == false && nTries < 5 ); // Get a handle on the door server's input mailslot hInputSlot = openSlot(-1); // Create this node's output mailslot. hOutputSlot = createSlot( getNode() ); // If unable to open input slot, re-try up to 5 times (intial failure seems to happen on WinXP randomly) // If still failure, this indicates the door server is not running and could not be started, so shut down. nTries = 0; while (hInputSlot == INVALID_HANDLE_VALUE ) { Sleep(500); hInputSlot = openSlot(-1); if ( ++nTries > 5 ) { local("Unable to start door: IPC error"); exitDoor(1); } } // If the output slot for this node is already open, it means the node is already running the door. if ( hOutputSlot == INVALID_HANDLE_VALUE ) { local("Unable to start door: This node is already in use!"); pausePrompt(); exitDoor(1); } // Now that the mailslot handles were successful, call setupExitFunction() to register beforeExit() as the // function called upon exit. setupExitFunction(); // Send an input message to the server, to tell it a user is trying to enter the game. The user's info is // passed as a string in the format below. sprintf(szText, "%d&%c&%d&%s&%s", isSysop(), getGender(), getPlatform(), getAlias(), getRealName()); sendInput(szText, IP_ENTER_GAME); // Handle I/O for the user while (1) { performIO(); } }