📄 osutils.cxx
字号:
}unsigned PTrace::GetLevel(){ return PTraceLevelThreshold;}BOOL PTrace::CanTrace(unsigned level){ return level <= PTraceLevelThreshold;}ostream & PTrace::Begin(unsigned level, const char * fileName, int lineNum){ if (PTraceMutex == NULL) { PAssertAlways("Cannot use PTRACE before PProcess constructed."); return *PTraceStream; } PWaitAndSignal m(*PTraceMutex); if (level == UINT_MAX) return *PTraceStream; // Save log level for this message so End() function can use. This is // protected by the PTraceMutex PTraceCurrentLevel = level; if ((PTrace_Filename != NULL) && (PTraceOptions&RotateDaily) != 0) { int day = PTime((PTraceOptions&GMTTime) ? PTime::GMT : PTime::Local).GetDayOfYear(); if (day != PTrace_lastDayOfYear) { delete PTraceStream; PTraceStream = NULL; OpenTraceFile(); if (PTraceStream == NULL) return *PTraceStream; } } if ((PTraceOptions&SystemLogStream) == 0) { if ((PTraceOptions&DateAndTime) != 0) { PTime now; *PTraceStream << now.AsString("yyyy/MM/dd hh:mm:ss.uuu\t", (PTraceOptions&GMTTime) ? PTime::GMT : PTime::Local); } if ((PTraceOptions&Timestamp) != 0) *PTraceStream << setprecision(3) << setw(10) << (PTimer::Tick()-ApplicationStartTick) << '\t'; if ((PTraceOptions&Thread) != 0) { PThread * thread = PThread::Current(); if (thread == NULL) *PTraceStream << "ThreadID=0x" << setfill('0') << hex << setw(8) << PThread::GetCurrentThreadId() << setfill(' ') << dec; else { PString name = thread->GetThreadName(); if (name.GetLength() <= 23) *PTraceStream << setw(23) << name; else *PTraceStream << name.Left(10) << "..." << name.Right(10); } *PTraceStream << '\t'; } if ((PTraceOptions&ThreadAddress) != 0) *PTraceStream << hex << setfill('0') << setw(7) << (void *)PThread::Current() << dec << setfill(' ') << '\t'; } if ((PTraceOptions&TraceLevel) != 0) *PTraceStream << level << '\t'; if ((PTraceOptions&FileAndLine) != 0 && fileName != NULL) { const char * file = strrchr(fileName, '/'); if (file != NULL) file++; else { file = strrchr(fileName, '\\'); if (file != NULL) file++; else file = fileName; } *PTraceStream << setw(16) << file << '(' << lineNum << ")\t"; } return *PTraceStream;}ostream & PTrace::End(ostream & s){ /* Only output if there is something to output, this prevents some blank trace entries from appearing under some patholgical conditions. Unfortunately if stderr is used the unitbuf flag causes the out_waiting() not to work so we must suffer with blank lines in that case. */ // ::streambuf & rb = *s.rdbuf();#if 0#ifndef P_LINUX if (((s.flags()&ios::unitbuf) != 0) ||#ifdef __USE_STL__ rb.pubseekoff(0, ios::cur, ios::out) > 0#else rb.out_waiting() > 0#endif )#endif#endif { if ((PTraceOptions&SystemLogStream) != 0) { // Get the trace level for this message and set the stream width to that // level so that the PSystemLog can extract the log level back out of the // ios structure. There could be portability issues with this though it // should work pretty universally. s.width(PTraceCurrentLevel+1); s.flush(); } else s << endl; } return s;}PTrace::Block::Block(const char * fileName, int lineNum, const char * traceName){ file = fileName; line = lineNum; name = traceName; if ((PTraceOptions&Blocks) != 0) { PThread * thread = PThread::Current(); thread->traceBlockIndentLevel += 2; ostream & s = PTrace::Begin(1, file, line); s << "B-Entry\t"; for (unsigned i = 0; i < thread->traceBlockIndentLevel; i++) s << '='; s << "> " << name << PTrace::End; }}PTrace::Block::~Block(){ if ((PTraceOptions&Blocks) != 0) { PThread * thread = PThread::Current(); ostream & s = PTrace::Begin(1, file, line); s << "B-Exit\t<"; for (unsigned i = 0; i < thread->traceBlockIndentLevel; i++) s << '='; s << ' ' << name << PTrace::End; thread->traceBlockIndentLevel -= 2; }}///////////////////////////////////////////////////////////////////////////////// PDirectoryvoid PDirectory::CloneContents(const PDirectory * d){ CopyContents(*d);}///////////////////////////////////////////////////////////////////////////////// PTimeIntervalDWORD PTimeInterval::GetInterval() const{ if (milliseconds <= 0) return 0; if (milliseconds >= UINT_MAX) return UINT_MAX; return (DWORD)milliseconds;}///////////////////////////////////////////////////////////////////////////////// PTimerPTimer::PTimer(long millisecs, int seconds, int minutes, int hours, int days) : resetTime(millisecs, seconds, minutes, hours, days){ Construct();}PTimer::PTimer(const PTimeInterval & time) : resetTime(time){ Construct();}void PTimer::Construct(){ state = Stopped; timerList = PProcess::Current().GetTimerList(); timerList->listMutex.Wait(); timerList->Append(this); timerList->listMutex.Signal(); timerList->processingMutex.Wait(); StartRunning(TRUE);}PTimer & PTimer::operator=(DWORD milliseconds){ timerList->processingMutex.Wait(); resetTime.SetInterval(milliseconds); StartRunning(oneshot); return *this;}PTimer & PTimer::operator=(const PTimeInterval & time){ timerList->processingMutex.Wait(); resetTime = time; StartRunning(oneshot); return *this;}PTimer::~PTimer(){ timerList->listMutex.Wait(); timerList->Remove(this); BOOL isCurrentTimer = this == timerList->currentTimer; timerList->listMutex.Signal(); // Make sure that the OnTimeout for this timer has completed before // destroying the timer if (isCurrentTimer) { timerList->inTimeoutMutex.Wait(); timerList->inTimeoutMutex.Signal(); }}void PTimer::SetInterval(PInt64 milliseconds, long seconds, long minutes, long hours, int days){ timerList->processingMutex.Wait(); resetTime.SetInterval(milliseconds, seconds, minutes, hours, days); StartRunning(oneshot);}void PTimer::RunContinuous(const PTimeInterval & time){ timerList->processingMutex.Wait(); resetTime = time; StartRunning(FALSE);}void PTimer::StartRunning(BOOL once){ PTimeInterval::operator=(resetTime); oneshot = once; state = (*this) != 0 ? Starting : Stopped; if (IsRunning()) PProcess::Current().SignalTimerChange(); // This must have been set by the caller timerList->processingMutex.Signal();}void PTimer::Stop(){ timerList->processingMutex.Wait(); state = Stopped; milliseconds = 0; BOOL isCurrentTimer = this == timerList->currentTimer; timerList->processingMutex.Signal(); // Make sure that the OnTimeout for this timer has completed before // retruning from Stop() function, if (isCurrentTimer) { timerList->inTimeoutMutex.Wait(); timerList->inTimeoutMutex.Signal(); }}void PTimer::Pause(){ timerList->processingMutex.Wait(); if (IsRunning()) state = Paused; timerList->processingMutex.Signal();}void PTimer::Resume(){ timerList->processingMutex.Wait(); if (state == Paused) state = Starting; timerList->processingMutex.Signal();}void PTimer::Reset(){ timerList->processingMutex.Wait(); StartRunning(oneshot);}void PTimer::OnTimeout(){ if (!callback.IsNULL()) callback(*this, IsRunning());}void PTimer::Process(const PTimeInterval & delta, PTimeInterval & minTimeLeft){ /*Ideally there should be a processingMutex for each individual timer, but that seems incredibly profligate of system resources as there can be a LOT of PTimer instances about. So use one one mutex for all. */ timerList->processingMutex.Wait(); switch (state) { case Starting : state = Running; if (resetTime < minTimeLeft) minTimeLeft = resetTime; break; case Running : operator-=(delta); if (milliseconds > 0) { if (milliseconds < minTimeLeft.GetMilliSeconds()) minTimeLeft = *this; } else { if (oneshot) { milliseconds = 0; state = Stopped; } else { PTimeInterval::operator=(resetTime); if (resetTime < minTimeLeft) minTimeLeft = resetTime; } timerList->processingMutex.Signal(); /* This must be outside the mutex or if OnTimeout() changes the timer value (quite plausible) it deadlocks. */ OnTimeout(); return; } break; default : // Stopped or Paused, do nothing. break; } timerList->processingMutex.Signal();}///////////////////////////////////////////////////////////////////////////////// PTimerListPTimerList::PTimerList(){ DisallowDeleteObjects(); currentTimer = NULL;}PTimeInterval PTimerList::Process(){ PINDEX i; PTimeInterval minTimeLeft = PMaxTimeInterval; listMutex.Wait(); PTimeInterval now = PTimer::Tick(); PTimeInterval sampleTime; if (lastSample == 0) sampleTime = 0; else { sampleTime = now - lastSample; if (now < lastSample) sampleTime += PMaxTimeInterval; } lastSample = now; for (i = 0; i < GetSize(); i++) { currentTimer = (PTimer *)GetAt(i); inTimeoutMutex.Wait(); listMutex.Signal(); currentTimer->Process(sampleTime, minTimeLeft); listMutex.Wait(); inTimeoutMutex.Signal(); } currentTimer = NULL; listMutex.Signal(); return minTimeLeft;}///////////////////////////////////////////////////////////////////////////////// PArgListPArgList::PArgList(const char * theArgStr, const char * theArgumentSpec, BOOL optionsBeforeParams){ // get the program arguments if (theArgStr != NULL) SetArgs(theArgStr); // if we got an argument spec - so process them if (theArgumentSpec != NULL) Parse(theArgumentSpec, optionsBeforeParams);}PArgList::PArgList(const PString & theArgStr, const char * argumentSpecPtr, BOOL optionsBeforeParams){ // get the program arguments SetArgs(theArgStr); // if we got an argument spec - so process them if (argumentSpecPtr != NULL) Parse(argumentSpecPtr, optionsBeforeParams);}PArgList::PArgList(const PString & theArgStr, const PString & argumentSpecStr, BOOL optionsBeforeParams){ // get the program arguments SetArgs(theArgStr); // if we got an argument spec - so process them Parse(argumentSpecStr, optionsBeforeParams);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -