void LanguageHook::clearLanguageHook() { LanguageHook* lh = addonLanguageHookTls.get(); addonLanguageHookTls.set(NULL); if (lh) lh->Release(); }
TraceGuard::TraceGuard() :function(NULL) { parent = tlParent.get(); depth = parent == NULL ? 0 : parent->depth + 1; tlParent.set(this); // silent }
TraceGuard::TraceGuard(const char* _function) :function(_function) { parent = tlParent.get(); depth = parent == NULL ? 0 : parent->depth + 1; tlParent.set(this); CLog::Log(LOGDEBUG, "%sNEWADDON Entering %s", spaces[depth], function); }
namespace XBMCAddon { // just need a place for the vtab LanguageHook::~LanguageHook() {} static XbmcThreads::ThreadLocal<LanguageHook> addonLanguageHookTls; static bool threadLocalInitilialized = false; static xbmcutil::InitFlag initer(threadLocalInitilialized); void LanguageHook::setLanguageHook(LanguageHook* languageHook) { TRACE; languageHook->Acquire(); addonLanguageHookTls.set(languageHook); } LanguageHook* LanguageHook::getLanguageHook() { return threadLocalInitilialized ? addonLanguageHookTls.get() : NULL; } void LanguageHook::clearLanguageHook() { LanguageHook* lh = addonLanguageHookTls.get(); addonLanguageHookTls.set(NULL); if (lh) lh->Release(); } }
TraceGuard::~TraceGuard() { if (function) CLog::Log(LOGDEBUG, "%sNEWADDON Leaving %s", spaces[depth], function); // need to pop the stack tlParent.set(this->parent); }
THREADFUNC CThread::staticThread(void* data) { CThread* pThread = (CThread*)(data); std::string name; ThreadIdentifier id; bool autodelete; if (!pThread) { CLog::Log(LOGERROR,"%s, sanity failed. thread is NULL.",__FUNCTION__); return 1; } name = pThread->m_ThreadName; id = pThread->m_ThreadId; autodelete = pThread->m_bAutoDelete; pThread->SetThreadInfo(); CLog::Log(LOGNOTICE,"Thread %s start, auto delete: %s", name.c_str(), (autodelete ? "true" : "false")); currentThread.set(pThread); pThread->m_StartEvent.Set(); pThread->OnStartup(); pThread->Process(); pThread->OnExit(); // lock during termination CSingleLock lock(pThread->m_CriticalSection); pThread->m_ThreadId = 0; pThread->m_TermEvent.Set(); pThread->TermHandler(); lock.Leave(); if (autodelete) { CLog::Log(LOGDEBUG,"Thread %s %"PRIu64" terminating (autodelete)", name.c_str(), (uint64_t)id); delete pThread; pThread = NULL; } else CLog::Log(LOGDEBUG,"Thread %s %"PRIu64" terminating", name.c_str(), (uint64_t)id); return 0; }
void CThread::term_handler (int signum) { CLog::Log(LOGERROR,"thread 0x%lx (%lu) got signal %d. calling OnException and terminating thread abnormally.", (long unsigned int)pthread_self(), (long unsigned int)pthread_self(), signum); CThread* curThread = currentThread.get(); if (curThread) { curThread->m_bStop = TRUE; curThread->m_StopEvent.Set(); curThread->OnException(); if( curThread->IsAutoDelete() ) delete curThread; } pthread_exit(NULL); }
namespace XBMCAddonUtils { //*********************************************************** // Some simple helpers void guiLock() { g_graphicsContext.Lock(); } void guiUnlock() { g_graphicsContext.Unlock(); } //*********************************************************** static char defaultImage[1024]; const char *getDefaultImage(char* cControlType, char* cTextureType, char* cDefault) { // create an xml block so that we can resolve our defaults // <control type="type"> // <description /> // </control> TiXmlElement control("control"); control.SetAttribute("type", cControlType); TiXmlElement filler("description"); control.InsertEndChild(filler); g_SkinInfo->ResolveIncludes(&control); // ok, now check for our texture type TiXmlElement *pTexture = control.FirstChildElement(cTextureType); if (pTexture) { // found our textureType TiXmlNode *pNode = pTexture->FirstChild(); if (pNode && pNode->Value()[0] != '-') { strncpy(defaultImage, pNode->Value(), sizeof(defaultImage)); defaultImage[sizeof(defaultImage) - 1] = '\0'; return defaultImage; } } return cDefault; } #ifdef ENABLE_XBMC_TRACE_API static XbmcThreads::ThreadLocal<TraceGuard> tlParent; static char** getSpacesArray(int size) { char** ret = new char*[size]; for (int i = 0; i < size; i++) { ret[i] = new char[i + 1]; int j; for (j = 0; j < i; j++) ret[i][j] = ' '; ret[i][j] = 0; } return ret; } static char** spaces = getSpacesArray(256); const char* TraceGuard::getSpaces() { return spaces[depth]; } TraceGuard::TraceGuard(const char* _function) :function(_function) { parent = tlParent.get(); depth = parent == NULL ? 0 : parent->depth + 1; tlParent.set(this); CLog::Log(LOGDEBUG, "%sNEWADDON Entering %s", spaces[depth], function); } TraceGuard::TraceGuard() :function(NULL) { parent = tlParent.get(); depth = parent == NULL ? 0 : parent->depth + 1; tlParent.set(this); // silent } TraceGuard::~TraceGuard() { if (function) CLog::Log(LOGDEBUG, "%sNEWADDON Leaving %s", spaces[depth], function); // need to pop the stack tlParent.set(this->parent); } #endif }
CThread* CThread::GetCurrentThread() { return currentThread.get(); }
DWORD WINAPI CThread::staticThread(LPVOID* data) #endif { CThread* pThread = (CThread*)(data); if (!pThread) { CLog::Log(LOGERROR,"%s, sanity failed. thread is NULL.",__FUNCTION__); return 1; } if (pThread->m_ThreadName.empty()) pThread->m_ThreadName = pThread->GetTypeName(); pThread->SetDebugCallStackName(pThread->m_ThreadName.c_str()); CLog::Log(LOGDEBUG,"Thread %s start, auto delete: %d", pThread->m_ThreadName.c_str(), pThread->IsAutoDelete()); currentThread.set(pThread); #ifndef _LINUX /* install win32 exception translator */ win32_exception::install_handler(); #else struct sigaction action; action.sa_handler = term_handler; sigemptyset (&action.sa_mask); action.sa_flags = 0; //sigaction (SIGABRT, &action, NULL); //sigaction (SIGSEGV, &action, NULL); #endif try { pThread->OnStartup(); } #ifndef _LINUX catch (const win32_exception &e) { e.writelog(__FUNCTION__); if( pThread->IsAutoDelete() ) { delete pThread; _endthreadex(123); return 0; } } #endif catch(...) { CLog::Log(LOGERROR, "%s - thread %s, Unhandled exception caught in thread startup, aborting. auto delete: %d", __FUNCTION__, pThread->m_ThreadName.c_str(), pThread->IsAutoDelete()); if( pThread->IsAutoDelete() ) { delete pThread; #ifndef _LINUX _endthreadex(123); #endif return 0; } } try { pThread->Process(); } #ifndef _LINUX catch (const access_violation &e) { e.writelog(__FUNCTION__); } catch (const win32_exception &e) { e.writelog(__FUNCTION__); } #endif catch(...) { CLog::Log(LOGERROR, "%s - thread %s, Unhandled exception caught in thread process, attemping cleanup in OnExit", __FUNCTION__, pThread->m_ThreadName.c_str()); } try { pThread->OnExit(); } #ifndef _LINUX catch (const access_violation &e) { e.writelog(__FUNCTION__); } catch (const win32_exception &e) { e.writelog(__FUNCTION__); } #endif catch(...) { CLog::Log(LOGERROR, "%s - thread %s, Unhandled exception caught in thread exit", __FUNCTION__, pThread->m_ThreadName.c_str()); } if ( pThread->IsAutoDelete() ) { CLog::Log(LOGDEBUG,"Thread %s %"PRIu64" terminating (autodelete)", pThread->m_ThreadName.c_str(), (uint64_t)CThread::GetCurrentThreadId()); delete pThread; pThread = NULL; } else CLog::Log(LOGDEBUG,"Thread %s %"PRIu64" terminating", pThread->m_ThreadName.c_str(), (uint64_t)CThread::GetCurrentThreadId()); // DXMERGE - this looks like it might have used to have been useful for something... // g_graphicsContext.DeleteThreadContext(); #ifndef _LINUX _endthreadex(123); #endif return 0; }
LanguageHook* LanguageHook::getLanguageHook() { return threadLocalInitilialized ? addonLanguageHookTls.get() : NULL; }
void LanguageHook::setLanguageHook(LanguageHook* languageHook) { TRACE; languageHook->Acquire(); addonLanguageHookTls.set(languageHook); }