void Lock::DBWrite::unlockDB() { if( _weLocked ) { recordTime(); // for lock stats if ( _nested ) lockState().unlockedNestable(); else lockState().unlockedOther(); _weLocked->unlock(); } if( _locked_w ) { if (DB_LEVEL_LOCKING_ENABLED) { qlk.unlock_w(); } else { qlk.unlock_W(); } } if( _locked_W ) { qlk.unlock_W(); } _weLocked = 0; _locked_W = _locked_w = false; }
Lock::UpgradeGlobalLockToExclusive::UpgradeGlobalLockToExclusive() { fassert( 16187, lockState().threadState() == 'w' ); // We're about to temporarily drop w, so stop the lock time stopwatch lockState().recordLockTime(); _gotUpgrade = qlk.w_to_X(); if ( _gotUpgrade ) { lockState().changeLockState('W'); lockState().resetLockTime(); } }
Lock::UpgradeGlobalLockToExclusive::~UpgradeGlobalLockToExclusive() { if ( _gotUpgrade ) { fassert( 16188, lockState().threadState() == 'W' ); lockState().recordLockTime(); qlk.X_to_w(); lockState().changeLockState('w'); } else { fassert( 16189, lockState().threadState() == 'w' ); } // Start recording lock time again lockState().resetLockTime(); }
bool ReadMedia::rewind() { // NOTE!! Always check for stream count before setting aeof or veof lockState(); if ( m_state == STATE_READY && m_file != NULL) { //printf("ReadMedia::rewind(), valid_samples=%d\n", m_audio_frame->valid_samples); m_pcm_seek = SEEK_REWIND; if(m_audio_stream_count) m_aeof = false; //m_atime = 0; m_frame_seek=SEEK_REWIND; if (m_video_stream_count) m_veof = false; //m_vtime=0; unlockState(); if (m_audio_stream_count) { signalA(); // only signal one or the other here //printf("ReadMedia::rewind(), signaled audio\n"); // we are gong to flush here even though it is flushed // during the audio or video thread. This will ensure our fifo // is clean and empty. Otherwise, the audio thread may be waiting // at the bottom of its loop and not make it to the flush part even // though we signalled it. if (m_fifoaudio) m_fifoaudio->Flush(); } else if (m_video_stream_count) { signalV(); if (m_fifovideo) m_fifovideo->Flush(); } return true; } unlockState(); return false; }
void Lock::DBRead::lockOther(const StringData& db) { fassert( 16255, !db.empty() ); LockState& ls = lockState(); // we do checks first, as on assert destructor won't be called so don't want to be half finished with our work. if( ls.otherCount() ) { // nested. prev could be read or write. if/when we do temprelease with DBRead/DBWrite we will need to increment/decrement here // (so we can not release or assert if nested). temprelease we should avoid if we can though, it's a bit of an anti-pattern. massert(16099, str::stream() << "internal error tried to lock two databases at the same time. old:" << ls.otherName() << " new:" << db, db == ls.otherName() ); return; } // first lock for this db. check consistent order with local db lock so we never deadlock. local always comes last massert(16100, str::stream() << "can't dblock:" << db << " when local or admin is already locked", ls.nestableCount() == 0); if (db != ls.otherName()) { DBLocksMap::ref r(dblocks); WrapperForRWLock*& lock = r[db]; if (lock == NULL) { lock = new WrapperForRWLock(db); } ls.lockedOther( db , -1 , lock ); } else { DEV OCCASIONALLY { dassert( dblocks.get(db) == ls.otherLock() ); } ls.lockedOther(-1); } fassert(16135,_weLocked==0); ls.otherLock()->lock_shared(); _weLocked = ls.otherLock(); }
void Lock::GlobalRead::_relock() { fassert(16129, !noop); char ts = threadState(); fassert(16130, ts == 0); Acquiring a(this,lockState()); qlk.lock_R(); }
void Lock::ScopedLock::ParallelBatchWriterSupport::relock() { LockState& ls = lockState(); if ( ! ls._batchWriter ) { AcquiringParallelWriter a(ls); _lk.reset( new RWLockRecursive::Shared(ParallelBatchWriterMode::_batchLock) ); } }
Lock::TempRelease::~TempRelease() { if( cant ) return; LockState& ls = lockState(); dassert( ls.recursive == 0 ); DESTRUCTOR_GUARD( fassert(0, ls.threadState == 't' || ls.threadState == 0); ls.threadState = 0; switch( type ) { case 'W': lock_W(); break; case 'R': lock_R(); break; case 'w': if( local ) localDBLock.lock(); else ls.otherLock->lock(); lock_w(); break; case 'r': if( local ) localDBLock.lock_shared(); else ls.otherLock->lock_shared(); lock_r(); break; default: wassert(false); } ) }
int ReadMedia::getState() { int s=STATE_EMPTY; lockState(); s = m_state; unlockState(); return s; }
int ReadMedia::getVideoTimescale() { int t=0; lockState(); t = m_video_format.timescale; unlockState(); return t; }
bool ReadMedia::quitAVThreads() { bool b =false; lockState(); b = quit_av_threads; unlockState(); return b; }
int64_t ReadMedia::getLengthInVideoFrames() { int64_t frames = 0; lockState(); frames = m_num_frames; unlockState(); return frames; }
int64_t ReadMedia::getLengthInAudioSamples() { int64_t samples = 0; lockState(); samples = m_num_samples; unlockState(); return samples; }
double ReadMedia::getLengthInSeconds() { double secs = 0.0; lockState(); secs = m_length_in_seconds; unlockState(); return secs; }
gavl_time_t ReadMedia::getLengthInGavlTime() { gavl_time_t time = 0; lockState(); time = m_length_in_gavltime; unlockState(); return time; }
void Lock::DBRead::lockDB(const string& ns) { fassert( 16254, !ns.empty() ); LockState& ls = lockState(); Acquiring a(this,ls); _locked_r=false; _weLocked=0; if ( ls.isRW() ) return; if (DB_LEVEL_LOCKING_ENABLED) { char db[MaxDatabaseNameLen]; nsToDatabase(ns.data(), db); Nestable nested = n(db); if( !nested ) lockOther(db); lockTop(ls); if( nested ) lockNestable(nested); } else { qlk.lock_R(); _locked_r = true; } }
static void lock_R() { LockState& ls = lockState(); massert(16103, str::stream() << "can't lock_R, threadState=" << (int) ls.threadState, ls.threadState == 0); ls.threadState = 'R'; Acquiring a('R'); q.lock_R(); }
// NOT PUBLIC bool ReadMedia::getVEOF() { bool tmp = false; lockState(); tmp = m_veof; unlockState(); return tmp; }
void Lock::DBWrite::lockOther(const StringData& db, const string &context) { fassert( 16252, !db.empty() ); LockState& ls = lockState(); // we do checks first, as on assert destructor won't be called so don't want to be half finished with our work. if( ls.otherCount() ) { // (so we can not release or assert if nested). massert(16106, str::stream() << "internal error tried to lock two databases at the same time. old:" << ls.otherName() << " new:" << db , db == ls.otherName() ); return; } // first lock for this db. check consistent order with local db lock so we never deadlock. local always comes last massert(16098, str::stream() << "can't dblock:" << db << " when local or admin is already locked", ls.nestableCount() == 0); if( db != ls.otherName() ) { DBLocksMap::ref r(dblocks); WrapperForRWLock*& lock = r[db]; if( lock == 0 ) lock = new WrapperForRWLock(db); ls.lockedOther( db , 1 , lock, context ); } else { DEV OCCASIONALLY { dassert( dblocks.get(db) == ls.otherLock() ); } ls.lockedOther(1, context); } fassert(16134,_weLocked==0); ls.otherLock()->lock(); _weLocked = ls.otherLock(); }
int ReadMedia::getSamplesPerFrame() { int spf=0; lockState(); spf = m_audio_format.samples_per_frame; unlockState(); return spf; }
void MultiApplier::_callback(const executor::TaskExecutor::CallbackArgs& cbd) { if (!cbd.status.isOK()) { _finishCallback(cbd.status, _operations); return; } invariant(!_operations.empty()); StatusWith<OpTime> applyStatus(ErrorCodes::InternalError, "not mutated"); try { auto txn = cc().makeOperationContext(); // Refer to multiSyncApply() and multiInitialSyncApply() in sync_tail.cpp. txn->setReplicatedWrites(false); // allow us to get through the magic barrier txn->lockState()->setIsBatchWriter(true); applyStatus = _multiApply(txn.get(), _operations, _applyOperation); } catch (...) { applyStatus = exceptionToStatus(); } if (!applyStatus.isOK()) { _finishCallback(applyStatus.getStatus(), _operations); return; } _finishCallback(applyStatus.getValue().getTimestamp(), _operations); }
int ReadMedia::getAudioStreamCount() { int asc=0; lockState(); asc = m_audio_stream_count; unlockState(); return asc; }
void Lock::GlobalWrite::_relock() { fassert(16125, !noop); char ts = threadState(); fassert(16126, ts == 0); Acquiring a(this,lockState()); qlk.lock_W(); }
int ReadMedia::getVideoStreamCount() { int vsc=0; lockState(); vsc = m_video_stream_count; unlockState(); return vsc; }
void Lock::DBWrite::lockDB(const string& ns) { fassert( 16253, !ns.empty() ); LockState& ls = lockState(); Acquiring a(this,ls); _locked_W=false; _locked_w=false; _weLocked=0; massert( 16186 , "can't get a DBWrite while having a read lock" , ! ls.hasAnyReadLock() ); if( ls.isW() ) return; StringData db = nsToDatabaseSubstring( ns ); Nestable nested = n(db); if( nested == admin ) { // we can't nestedly lock both admin and local as implemented. so lock_W. qlk.lock_W(); _locked_W = true; return; } if( !nested ) lockOther(db); lockTop(ls); if( nested ) lockNestable(nested); }
// NOT PUBLIC int ReadMedia::getCommand() { int cmd= CMD_NULL; lockState(); cmd = m_cmd; unlockState(); return cmd; }
// NOT PUBLIC // killAVThreads is only called from the opener thread // and from the destructor // THIS IS NOT REALLY A PUBLIC function void ReadMedia::killAVThreads() { lockState(); m_state = STATE_EMPTY; quit_av_threads = true; unlockState(); signalAV(); signalAV(); // FIRST need to join the threads that exist and are running if (m_audio_thread_ret == 0) { pthread_join( m_thread_fillaudiofifo, NULL); //pthread_detach( m_thread_fillaudiofifo); } if (m_video_thread_ret == 0){ pthread_join( m_thread_fillvideofifo, NULL); //pthread_detach( m_thread_fillvideofifo); } m_audio_thread_ret = -1; m_video_thread_ret = -1; // no need to lock here quit_av_threads = false; }
void Lock::DBWrite::lockDB(const string& ns) { fassert( 16253, !ns.empty() ); LockState& ls = lockState(); Acquiring a(this,ls); _locked_W=false; _locked_w=false; _weLocked=0; massert( 16186 , "can't get a DBWrite while having a read lock" , ! ls.hasAnyReadLock() ); if( ls.isW() ) return; if (DB_LEVEL_LOCKING_ENABLED) { char db[MaxDatabaseNameLen]; nsToDatabase(ns.data(), db); Nestable nested = n(db); if( nested == admin ) { // we can't nestedly lock both admin and local as implemented. so lock_W. qlk.lock_W(); _locked_W = true; return; } if( !nested ) lockOther(db); lockTop(ls); if( nested ) lockNestable(nested); } else { qlk.lock_W(); _locked_w = true; } }
void OperationContextImpl::checkForInterrupt() const { // We cannot interrupt operation, while it's inside of a write unit of work, because logOp // cannot handle being iterrupted. if (lockState()->inAWriteUnitOfWork()) return; uassertStatusOK(checkForInterruptNoAssert()); }
int ReadMedia::decodeAudio( gavl_audio_frame_t * af ) { lockState(); if (m_state != STATE_READY || m_audio_stream_count < 1 || m_fifoaudio == NULL ) { unlockState(); return -1; } if ( !m_fifoaudio->Get( af ) ) { if ( m_aeof ) { m_pcm_seek = SEEK_NOTHING; unlockState(); signalA(); return 0; } else { printf("Couldn't get an audio frame, audiofifo is %f full.\n", m_fifoaudio->getSizePercentage()); // this can only happen if the fifo is empty unlockState(); signalA(); return -1; } } //m_atime = af->timestamp / (double)m_audio_format.samplerate; unlockState(); signalA(); return 1 ; }