std::shared_ptr<PhpEvents::EventData> PhpEvents::poll(int32_t timeout) { std::shared_ptr<EventData> eventData; std::unique_lock<std::mutex> lock(_processingThreadMutex); try { { BaseLib::DisposableLockGuard bufferGuard(_bufferMutex); if(_bufferHead == _bufferTail) { bufferGuard.dispose(); if(timeout > 0) _processingConditionVariable.wait_for(lock, std::chrono::milliseconds(timeout), [&]{ return _processingEntryAvailable; }); else _processingConditionVariable.wait(lock, [&]{ return _processingEntryAvailable; }); } } if(GD::bl->shuttingDown) { lock.unlock(); return eventData; } _bufferMutex.lock(); eventData = _buffer[_bufferTail]; _buffer[_bufferTail].reset(); _bufferTail++; if(_bufferTail >= _bufferSize) _bufferTail = 0; if(_bufferHead == _bufferTail) _processingEntryAvailable = false; _bufferMutex.unlock(); } catch(const std::exception& ex) { GD::bl->out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what()); } catch(const BaseLib::Exception& ex) { GD::bl->out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what()); } catch(...) { GD::bl->out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__); } lock.unlock(); return eventData; }
void JournalWriter::_journalWriterThread() { Client::initThread("journal writer"); log() << "Journal writer thread started"; try { while (true) { Buffer* const buffer = [&] { MONGO_IDLE_THREAD_BLOCK; return _journalQueue.blockingPop(); }(); BufferGuard bufferGuard(buffer, &_readyQueue); if (buffer->_isShutdown) { invariant(buffer->_builder.len() == 0); // The journal writer thread is terminating. Nothing to notify or write. break; } if (buffer->_isNoop) { invariant(buffer->_builder.len() == 0); // There's nothing to be writen, but we still need to notify this commit number _commitNotify->notifyAll(buffer->_commitNumber); _applyToDataFilesNotify->notifyAll(buffer->_commitNumber); continue; } LOG(4) << "Journaling commit number " << buffer->_commitNumber << " (journal file " << buffer->_header.fileId << ", sequence " << buffer->_header.seqNumber << ", size " << buffer->_builder.len() << " bytes)"; // This performs synchronous I/O to the journal file and will block. WRITETOJOURNAL(buffer->_header, buffer->_builder); // Data is now persisted in the journal, which is sufficient for acknowledging // durability. dur::getJournalListener()->onDurable(buffer->journalListenerToken); _commitNotify->notifyAll(buffer->_commitNumber); // Apply the journal entries on top of the shared view so that when flush is // requested it would write the latest. WRITETODATAFILES(cc().makeOperationContext().get(), buffer->_header, buffer->_builder); // Data is now persisted on the shared view, so notify any potential journal file // cleanup waiters. _applyToDataFilesNotify->notifyAll(buffer->_commitNumber); } } catch (const DBException& e) { severe() << "dbexception in journalWriterThread causing immediate shutdown: " << redact(e); MONGO_UNREACHABLE; } catch (const std::ios_base::failure& e) { severe() << "ios_base exception in journalWriterThread causing immediate shutdown: " << e.what(); MONGO_UNREACHABLE; } catch (const std::bad_alloc& e) { severe() << "bad_alloc exception in journalWriterThread causing immediate shutdown: " << e.what(); MONGO_UNREACHABLE; } catch (const std::exception& e) { severe() << "exception in journalWriterThread causing immediate shutdown: " << redact(e.what()); MONGO_UNREACHABLE; } catch (...) { severe() << "unhandled exception in journalWriterThread causing immediate shutdown"; MONGO_UNREACHABLE; } log() << "Journal writer thread stopped"; }