void shutdownNoTerminate(const ShutdownTaskArgs& shutdownArgs) { decltype(shutdownTasks) localTasks; { stdx::lock_guard<stdx::mutex> lock(shutdownMutex); if (globalInShutdownDeprecated()) return; setShutdownFlag(); shutdownTasksInProgress = true; shutdownTasksThreadId = stdx::this_thread::get_id(); localTasks.swap(shutdownTasks); } runTasks(std::move(localTasks), shutdownArgs); { stdx::lock_guard<stdx::mutex> lock(shutdownMutex); shutdownTasksInProgress = false; shutdownExitCode.emplace(EXIT_CLEAN); } shutdownTasksComplete.notify_all(); }
void Dispatcher::waitUntilStopped() { _mutex.lock(); if (_state == State::STARTED) { LOGe("Cannot wait for dispatcher to stop because stopping wasn't requested."); assert(_state != State::STARTED); _mutex.unlock(); return; } if (_thread.get_id() == std::this_thread::get_id()) { auto tasks = std::move(_tasks); _mutex.unlock(); runTasks(tasks); } else { if (_thread.joinable()) { // TODO: race condition possible here? _mutex.unlock(); _thread.join(); } else { _mutex.unlock(); } } }
int main(void) { // Set the clocking to run directly from the crystal. SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN | SYSCTL_XTAL_8MHZ); startup(); // initialize system state and variables while (1) { runTasks(); // from schedule.h } }
void gep::TaskWorker::run() { try { while(m_pTaskQueue->m_isRunning) { m_hasWorkSemaphore.waitAndDecrement(); if(!m_pTaskQueue->m_isRunning) break; runTasks(); } } catch(std::exception& ex) { g_globalManager.getLogging()->logError("A task worker was killed due to a unhandeled exception:\n%s", ex.what()); } }
void shutdown(ExitCode code, const ShutdownTaskArgs& shutdownArgs) { decltype(shutdownTasks) localTasks; { stdx::unique_lock<stdx::mutex> lock(shutdownMutex); if (shutdownTasksInProgress) { // Someone better have called shutdown in some form already. invariant(globalInShutdownDeprecated()); // Re-entrant calls to shutdown are not allowed. invariant(shutdownTasksThreadId != stdx::this_thread::get_id()); ExitCode originallyRequestedCode = shutdownExitCode.get(); if (code != originallyRequestedCode) { log() << "While running shutdown tasks with the intent to exit with code " << originallyRequestedCode << ", an additional shutdown request arrived with " "the intent to exit with a different exit code " << code << "; ignoring the conflicting exit code"; } // Wait for the shutdown tasks to complete while (shutdownTasksInProgress) shutdownTasksComplete.wait(lock); logAndQuickExit_inlock(); } setShutdownFlag(); shutdownExitCode.emplace(code); shutdownTasksInProgress = true; shutdownTasksThreadId = stdx::this_thread::get_id(); localTasks.swap(shutdownTasks); } runTasks(std::move(localTasks), shutdownArgs); { stdx::lock_guard<stdx::mutex> lock(shutdownMutex); shutdownTasksInProgress = false; shutdownTasksComplete.notify_all(); logAndQuickExit_inlock(); } }
void Dispatcher::thread() { std::unique_lock<std::mutex> uniqueLock(_mutex, std::defer_lock); while (_state == State::STARTED) { uniqueLock.lock(); if (_tasks.empty()) { _signal.wait(uniqueLock); } if (_state != State::STARTED || _tasks.empty()) { uniqueLock.unlock(); continue; } auto task = std::move(_tasks.front()); _tasks.pop_front(); uniqueLock.unlock(); auto& game = server.game(); auto messagePool = OutputMessagePool::getInstance(); runTask(*task, game, messagePool); } _mutex.lock(); auto tasks = std::move(_tasks); _mutex.unlock(); runTasks(tasks); _mutex.lock(); _state = State::STOPPED; _mutex.unlock(); }