//------------------------------------------------------------------------------------------------------------------------------------ // Helper for ErrorMessenger. //------------------------------------------------------------------------------------------------------------------------------------ LogMgr::ErrorDialogResult LogMgr::Error(const std::string& errorMessage, bool isFatal, const char* funcName, const char* sourceFile, unsigned int lineNum) { string tag = ((isFatal) ? ("FATAL") : ("ERROR")); // buffer for our final output string string buffer; GetOutputBuffer(buffer, tag, errorMessage, funcName, sourceFile, lineNum); // write the final buffer to all the various logs m_tagCriticalSection.Lock(); Tags::iterator findIt = m_tags.find(tag); if (findIt != m_tags.end()) OutputFinalBufferToLogs(buffer, findIt->second); m_tagCriticalSection.Unlock(); // show the dialog box int result = ::MessageBoxA(NULL, buffer.c_str(), tag.c_str(), MB_ABORTRETRYIGNORE|MB_ICONERROR|MB_DEFBUTTON3); // act upon the choice switch (result) { case IDIGNORE : return LogMgr::LOGMGR_ERROR_IGNORE; case IDABORT : __debugbreak(); return LogMgr::LOGMGR_ERROR_RETRY; // assembly language instruction to break into the debugger case IDRETRY : return LogMgr::LOGMGR_ERROR_RETRY; default : return LogMgr::LOGMGR_ERROR_RETRY; } }
AsyncStream::~AsyncStream(void) { // Before we destroy ourselves... must remove ourselves from the linked list... // TODO: currently we don't wait for the server thread to flush any remaining data, // so in theory when a thread is destoryed it is possible to lose some data in // the outbound stream!!!!! g_listlock.Lock(); if(s_head == this) { // We our the head element... simply replace the head with the next one... s_head = m_next; } else { // Search for the element before us and set its next to our next... for(AsyncStream *curr=s_head; curr; curr=curr->m_next) { if(curr->m_next == this) { curr->m_next = m_next; break; } } } g_listlock.Unlock(); if(m_cacheBegin) free(m_cacheBegin); if(m_flushBegin) free(m_flushBegin); }
/////////////////////////////////////////////////////////////////////////////////////////////////////// // this function builds up the log string and outputs it to various places based on display flags /////////////////////////////////////////////////////////////////////////////////////////////////////// void LogMgr::Log(const string& tag, const string& message, const char* func, const char* source, unsigned int line) { _tag_critical_section.Lock(); Tags::iterator it = _tags.find(tag); if(it != _tags.end()) { _tag_critical_section.Unlock(); string buffer; GetOutputBuffer(buffer, tag, message, func, source, line); OutputFinalBufferToLogs(buffer, it->second); } else { //critical section is exited in the if above, so need to do it here if above wasnt executed _tag_critical_section.Unlock(); } }
//------------------------------------------------------------------------------------------------------------------------------------ // This function builds up the log string and outputs it to various places based on the display flags (m_displayFlags). //------------------------------------------------------------------------------------------------------------------------------------ void LogMgr::Log(const string& tag, const string& message, const char* funcName, const char* sourceFile, unsigned int lineNum) { m_tagCriticalSection.Lock(); Tags::iterator findIt = m_tags.find(tag); if (findIt != m_tags.end()) { m_tagCriticalSection.Unlock(); string buffer; GetOutputBuffer(buffer, tag, message, funcName, sourceFile, lineNum); OutputFinalBufferToLogs(buffer, findIt->second); } else { // Critical section is exited in the if statement above, so we need to exit it here if that didn't // get executed. m_tagCriticalSection.Unlock(); } } // end LogMgr::Log()
// Flush all existing thread streams... returns false on socket error bool AsyncStream::FlushAll(Socket &s) { OVR_CAPTURE_CPU_ZONE(AsyncStream_FlushAll); bool okay = true; g_listlock.Lock(); for(AsyncStream *curr=s_head; curr; curr=curr->m_next) { okay = curr->Flush(s); if(!okay) break; } g_listlock.Unlock(); return okay; }
void FindContacts_Threaded(void *fc) { static CriticalSection cs; ContactFinder *cf = (ContactFinder*)fc; map<ArbiterKey, Arbiter> &arbitersf = *cf->_arbiters; cf->last = min(cf->last, (i32)cf->potentials->size()); for(int i=cf->first;i<cf->last;++i) { World::PotentiallyColliding pc = cf->potentials->at(i); Arbiter arb(pc.body1, pc.body2); ArbiterKey arbKey(pc.body1, pc.body2); if(arb.DoCollision()) { ArbIter iter = arbitersf.find(arbKey); if(iter != arbitersf.end()) { iter->second.Update(arb.contacts, arb.numContacts); } else { cs.Lock(); cf->addList->push_back(Arbiter_ADD(arb, arbKey)); cs.Unlock(); } } else { cs.Lock(); cf->eraseList->push_back(Arbiter_ERASE(arbKey)); cs.Unlock(); } } };
//------------------------------------------------------------------------------------------------------------------------------------ // Sets one or more display flags //------------------------------------------------------------------------------------------------------------------------------------ void LogMgr::SetDisplayFlags(const std::string& tag, unsigned char flags) { m_tagCriticalSection.Lock(); if (flags != 0) { Tags::iterator findIt = m_tags.find(tag); if (findIt == m_tags.end()) m_tags.insert(std::make_pair(tag, flags)); else findIt->second = flags; } else { m_tags.erase(tag); } m_tagCriticalSection.Unlock(); }
/////////////////////////////////////////////////////////////////////////////////////// // sets one or more display flags /////////////////////////////////////////////////////////////////////////////////////// void LogMgr::SetDisplayFlags(const std::string& tag, unsigned char flags) { _tag_critical_section.Lock(); if(flags != 0) { Tags::iterator it = _tags.find(tag); if(it == _tags.end()) _tags.insert(std::make_pair(tag, flags)); else it->second = flags; } else { _tags.erase(tag); } _tag_critical_section.Unlock(); }
AsyncStream::AsyncStream(void) { m_bufferLock = 0; #if defined(OVR_CAPTURE_POSIX) OVR_CAPTURE_STATIC_ASSERT(sizeof(pid_t) <= sizeof(UInt32)); union { UInt32 i; pid_t t; }; i = 0; t = gettid(); m_threadID = i; #elif defined(OVR_CAPTURE_WINDOWS) m_threadID = static_cast<UInt32>(GetCurrentThreadId()); #else #error UNKNOWN PLATFORM! #endif m_cacheBegin = (UInt8*)malloc(s_bufferSize); m_cacheTail = m_cacheBegin; m_cacheEnd = m_cacheBegin + s_bufferSize; m_flushBegin = (UInt8*)malloc(s_bufferSize); m_flushTail = m_flushBegin; m_flushEnd = m_flushBegin + s_bufferSize; // Make sure we are open by default... we don't close until we fill the buffer... m_gate.Open(); // when we are finally initialized... add ourselves to the linked list... g_listlock.Lock(); m_next = s_head; s_head = this; g_listlock.Unlock(); // Try and acquire thread name... SendThreadName(); }
////////////////////////////////////////////////////////////////////////////////////////////// //helper for ErrorMessenger ///////////////////////////////////////////////////////////////////////////////////////////// LogMgr::ErrorDialogResult LogMgr::Error(const std::string& error_message, bool is_fatal, const char* func, const char* source, unsigned int line) { string tag = ((is_fatal) ? ("FATAL") : ("ERROR")); //buffer for final output string string buffer; GetOutputBuffer(buffer, tag, error_message, func, source, line); //write final buffer to various logs _tag_critical_section.Lock(); Tags::iterator it = _tags.find(tag); if(it != _tags.end()) OutputFinalBufferToLogs(buffer, it->second); _tag_critical_section.Unlock(); //show the dialog box int result = ::MessageBoxA(NULL, buffer.c_str(), tag.c_str(), MB_ABORTRETRYIGNORE|MB_ICONERROR|MB_DEFBUTTON3); switch(result) { case IDIGNORE: return LogMgr::LOGMGR_ERROR_IGNORE; case IDABORT: __debugbreak(); return LogMgr::LOGMGR_ERROR_ABORT; case IDRETRY: return LogMgr::LOGMGR_ERROR_RETRY; default: return LogMgr::LOGMGR_ERROR_RETRY; } }
//------------------------------------------------------------------------------------------------------------------------------------ // Adds an error messenger to the list //------------------------------------------------------------------------------------------------------------------------------------ void LogMgr::AddErrorMessenger(Logger::ErrorMessenger* pMessenger) { m_messengerCriticalSection.Lock(); m_errorMessengers.push_back(pMessenger); m_messengerCriticalSection.Unlock(); }
~AutoCriticalSection() { m_pCS->Unlock(); }
void Unlock() { m_CriSection.Unlock(); }
//////////////////////////////////////////////////////////////////////////////////////////////// // adds error message to list //////////////////////////////////////////////////////////////////////////////////////////////// void LogMgr::AddErrorMessenger(Logger::ErrorMessenger* messenger) { _messenger_critical_section.Lock(); _error_messengers.push_back(messenger); _messenger_critical_section.Unlock(); }