LqString LqThreadBase::DebugInfo() const { const char* Prior; switch(Priority) { case LQTHREAD_PRIOR_IDLE: Prior = "idle"; break; case LQTHREAD_PRIOR_LOWER: Prior = "lower"; break; case LQTHREAD_PRIOR_LOW:Prior = "low"; break; case LQTHREAD_PRIOR_NONE: case LQTHREAD_PRIOR_NORMAL: Prior = "normal"; break; case LQTHREAD_PRIOR_HIGH: Prior = "high"; break; case LQTHREAD_PRIOR_HIGHER: Prior = "higher"; break; case LQTHREAD_PRIOR_REALTIME: Prior = "realtime"; break; default: Prior = "unknown"; } char Buf[1024]; LqFbuf_snprintf ( Buf, sizeof(Buf), "--------------\n" "Thread id: %llu\n" "Is work: %c\n" "Priority: %s\n" "Affinity mask: 0x%016llx\n", (unsigned long long)ThreadId(), (char)((IsThreadRunning()) ? '1' : '0'), Prior, AffinMask ); return Buf; }
void FileWatcher::Init(const WCHAR* fileFullPath) { // if the thread already exists then stop it if (IsThreadRunning()) SynchronousAbort(); str::ReplacePtr(&filePath, fileFullPath); WCHAR *dirPath = path::GetDir(filePath); hDir = CreateFile( dirPath, // pointer to the directory containing the tex files FILE_LIST_DIRECTORY, // access (read-write) mode FILE_SHARE_READ|FILE_SHARE_DELETE|FILE_SHARE_WRITE, // share mode NULL, // security descriptor OPEN_EXISTING, // how to create FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED , // file attributes NULL); // file with attributes to copy free(dirPath); ZeroMemory(&overl, sizeof(overl)); ZeroMemory(buffer, sizeof(buffer)); overl.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL); // watch the directory ReadDirectoryChangesW( hDir, /* handle to directory */ &buffer[curBuffer], /* read results buffer */ sizeof(buffer[curBuffer]), /* length of buffer */ FALSE, /* monitoring option */ //FILE_NOTIFY_CHANGE_CREATION| FILE_NOTIFY_CHANGE_LAST_WRITE, /* filter conditions */ NULL, /* bytes returned */ &overl, /* overlapped buffer */ NULL); /* completion routine */ }
void LqThreadBase::WaitEnd() const { bool IsNotOut = true; if(IsThisThread()) return; while(IsNotOut) { StartThreadLocker.LockWriteYield(); IsNotOut = IsThreadRunning(); StartThreadLocker.UnlockWrite(); } }
// Start watching a file for changes void FileWatcher::StartWatchThread() { // if the thread already exists then stop it if (IsThreadRunning()) SynchronousAbort(); CrashIf(!hDir); // reset the hEvtStopWatching event so that it can be set if // some thread requires the watching thread to stop ResetEvent(hEvtStopWatching); DWORD watchingthreadID; hWatchingThread = CreateThread(NULL, 0, WatchingThread, this, 0, &watchingthreadID); }
bool LqThreadBase::SetAffinity(uint64_t Mask) { bool Res = true; StartThreadLocker.LockWrite(); if(AffinMask != Mask) { AffinMask = Mask; if(IsThreadRunning()) { #if defined(LQPLATFORM_WINDOWS) SetThreadAffinityMask((HANDLE)NativeHandle(), Mask); #elif !defined(LQPLATFORM_ANDROID) pthread_setaffinity_np(NativeHandle(), sizeof(Mask), (const cpu_set_t*)&Mask); #endif } else { lq_errno_set(ENOENT); Res = false; } } StartThreadLocker.UnlockWrite(); return Res; }
bool LqThreadBase::SetPriority(LqThreadPriorEnm New) { bool Res = true; StartThreadLocker.LockWrite(); if(Priority != New) { Priority = New; if(IsThreadRunning()) { #if defined(LQPLATFORM_WINDOWS) SetThreadPriority((HANDLE)NativeHandle(), __GetRealPrior(Priority)); #else sched_param schedparams; schedparams.sched_priority = __GetRealPrior(Priority); pthread_setschedparam(NativeHandle(), SCHED_OTHER, &schedparams); #endif } else { lq_errno_set(ENOENT); Res = false; } } StartThreadLocker.UnlockWrite(); return Res; }
// THREAD INFO INSIDE RESPONSES // id The numeric id assigned to the thread by gdb. This field is always present. // target-id Target-specific string identifying the thread. This field is always present. // details Additional information about the thread provided by the target. It is supposed to be human-readable and not interpreted by the frontend. This field is optional. // state Either `stopped' or `running', depending on whether the thread is presently running. This field is always present. // core The value of this field is an integer number of the processor core the thread was last seen on. This field is optional. // // REMARKS : by now, we just handle synchronous output and check asynchronous one just to detect // debugger run/stop status -- all remaining asynchrnonous output is discarded MIValue Gdb_MI2::MICmd(const char *cmdLine) { MIValue res; #ifdef flagMT // on MT, we interrupt all non-main threads // issued GDB commands (which normally can lag several seconds...) // before issuing the command if(IsMainThread() && IsThreadRunning()) ShutDownThreads(); // quick exit for service thread if(!IsMainThread() && IsStopThread()) throw BreakExc(); // lock other thread's access INTERLOCKED { #endif // sends command to debugger and get result data // should handle dbg unexpected termination ? if(!dbg || !dbg->IsRunning() /* || IdeIsDebugLock() */) return MIValue(); // consume previous output from gdb... don't know why sometimes // is there and gives problems to MI interface. We shall maybe // parse and store it somewhere ReadGdb(false); dbg->Write(String("-") + cmdLine + "\n"); res = ReadGdb(); #ifdef flagMT } #endif return res; }
bool LqThreadBase::StartThreadAsync() { bool Res = true; StartThreadLocker.LockWrite(); if(IsThreadRunning()) { StartThreadLocker.UnlockWrite(); lq_errno_set(EALREADY); return false; } IsShouldEnd = false; IsStarted = false; #ifdef LQPLATFORM_WINDOWS unsigned threadID; uintptr_t Handler = _beginthreadex(NULL, 0, BeginThreadHelper, this, 0, &threadID); CurThreadId = threadID; ThreadHandler = Handler; if(Handler == -1L) { switch(errno) { case EAGAIN: lq_errno_set(EAGAIN); break; case EINVAL: lq_errno_set(EINVAL); break; case EACCES: lq_errno_set(EACCES); break; } #else pthread_t threadID = 0; int Err = pthread_create(&threadID, NULL, BeginThreadHelper, this); CurThreadId = threadID; if(Err != 0) { #endif Res = false; CurThreadId = -((intptr_t)1); ThreadHandler = 0; } StartThreadLocker.UnlockWrite(); return Res; } bool LqThreadBase::StartThreadSync() { bool Res = true; StartThreadLocker.LockWrite(); if(IsThreadRunning()) { StartThreadLocker.UnlockWrite(); lq_errno_set(EALREADY); return false; } IsShouldEnd = false; IsStarted = false; #ifdef LQPLATFORM_WINDOWS unsigned threadID; uintptr_t Handler = _beginthreadex(NULL, 0, BeginThreadHelper, this, 0, &threadID); CurThreadId = threadID; ThreadHandler = Handler; if(Handler == -1L) { switch(errno) { case EAGAIN: lq_errno_set(EAGAIN); break; case EINVAL: lq_errno_set(EINVAL); break; case EACCES: lq_errno_set(EACCES); break; } #else pthread_t threadID = 0; int Err = pthread_create(&threadID, NULL, BeginThreadHelper, this); CurThreadId = threadID; if(Err != 0){ #endif Res = false; CurThreadId = -((intptr_t)1); ThreadHandler = 0; } else { while(!IsStarted) LqThreadYield(); } StartThreadLocker.UnlockWrite(); return Res; } bool LqThreadBase::IsThisThread() const { #ifdef LQPLATFORM_WINDOWS return GetCurrentThreadId() == CurThreadId; #else return pthread_equal(pthread_self(), CurThreadId); #endif } bool LqThreadBase::ExitThreadAsync() { bool r = true; StartThreadLocker.LockWrite(); if(IsThreadRunning()) { IsShouldEnd = true; if(!IsThisThread()) NotifyThread(); } else { lq_errno_set(ENOENT); r = false; } StartThreadLocker.UnlockWrite(); return r; }
BOOL CCommMng::IsRecvThreadRuning() { return IsThreadRunning(); }
STDMETHODIMP CTsReaderFilter::Pause() { //m_ShowBufferVideo = INIT_SHOWBUFFERVIDEO; //m_ShowBufferAudio = INIT_SHOWBUFFERAUDIO; LogDebug("CTsReaderFilter::Pause() - IsTimeShifting = %d - state = %d", IsTimeShifting(), m_State); CAutoLock cObjectLock(m_pLock); if (m_State == State_Running) { m_lastPause = GetTickCount(); m_RandomCompensation = 0; } //pause filter HRESULT hr=CSource::Pause(); if (!m_bPauseOnClockTooFast) { //are we using rtsp? if (m_fileDuration==NULL) { //yes, are we busy seeking? if (!IsSeeking()) { //not seeking, is rtsp streaming at the moment? if (!m_rtspClient.IsRunning()) { //not streaming atm double startTime=m_seekTime.Millisecs(); startTime/=1000.0; long Old_rtspDuration = m_rtspClient.Duration() ; //clear buffers LogDebug(" -- Pause() ->start rtsp from %f", startTime); m_buffer.Clear(); m_demultiplexer.Flush(); //start streaming m_buffer.Run(true); m_rtspClient.Play(startTime,0.0); // m_tickCount = GetTickCount(); LogDebug(" -- Pause() ->rtsp started"); //update the duration of the stream CPcr pcrStart, pcrEnd, pcrMax ; double duration = m_rtspClient.Duration() / 1000.0f ; if (m_bTimeShifting) { // EndPcr is continuously increasing ( until ~26 hours for rollover that will fail ! ) // So, we refer duration to End, and just update start. pcrEnd = m_duration.EndPcr() ; double start = pcrEnd.ToClock() - duration; if (start<0) start=0 ; pcrStart.FromClock(start) ; m_duration.Set( pcrStart, pcrEnd, pcrMax) ; // Pause()-RTSP } else { // It's a record, eventually end can increase if recording is in progress, let the end virtually updated by ThreadProc() //m_bRecording = (Old_rtspDuration != m_rtspClient.Duration()) ; m_bRecording = true; // duration may have not increased in such a short time } LogDebug("Timeshift %d, Recording %d, StartPCR %f, EndPcr %f, Duration %f",m_bTimeShifting,m_bRecording,m_duration.StartPcr().ToClock(),m_duration.EndPcr().ToClock(),(float)m_duration.Duration().Millisecs()/1000.0f) ; } else { //we are streaming at the moment. //query the current position, so it can resume on un-pause at this position //can be required in multiseat with rtsp when changing audio streams IMediaSeeking * ptrMediaPos; if (SUCCEEDED(GetFilterGraph()->QueryInterface(IID_IMediaSeeking, (void**)&ptrMediaPos))) { ptrMediaPos->GetCurrentPosition(&m_seekTime.m_time); ptrMediaPos->Release(); } //pause the streaming LogDebug(" -- Pause() ->pause rtsp at position: %f", (m_seekTime.Millisecs() / 1000.0f)); m_rtspClient.Pause(); } } else //we are seeking { IMediaSeeking * ptrMediaPos; if (SUCCEEDED(GetFilterGraph()->QueryInterface(IID_IMediaSeeking, (void**)&ptrMediaPos))) { LONGLONG currentPos; ptrMediaPos->GetCurrentPosition(¤tPos); ptrMediaPos->Release(); double clock = currentPos;clock /= 10000000.0; float clockEnd = m_duration.EndPcr().ToClock() ; if (clock >= clockEnd && clockEnd > 0 ) { LogDebug("End of rtsp stream..."); m_demultiplexer.SetEndOfFile(true); } } } } m_demultiplexer.m_LastDataFromRtsp = GetTickCount() ; } //is the duration update thread running? if (!IsThreadRunning()) { //nop? then start it //LogDebug(" CTsReaderFilter::Pause()->start duration thread"); StartThread(); } LogDebug("CTsReaderFilter::Pause() - END - state = %d", m_State); return hr; }