void CScopeInfo_Base::x_ResetLock(void) { //_ASSERT(x_Check(fForceZero|fAllowInfo)); _ASSERT(!IsDetached()); m_ObjectInfo.Reset(); m_TSE_Handle.Reset(); //_ASSERT(x_Check(fForceZero|fForbidInfo)); }
ISocketHandler& Socket::Handler() const { #ifdef ENABLE_DETACH if (IsDetached()) return *m_slave_handler; #endif return m_handler; }
//////////////// // Thread entry wxThread::ExitCode FontsCollectorThread::Entry() { // Collect Collect(); collector->CloseButton->Enable(true); // Return if (IsDetached()) Delete(); return 0; }
void CScopeInfo_Base::x_AttachTSE(CTSE_ScopeInfo* tse) { _ASSERT(tse); _ASSERT(!m_TSE_ScopeInfo); _ASSERT(IsDetached()); _ASSERT(x_Check(fAllowZero|fForbidInfo)); m_TSE_ScopeInfo = tse; _ASSERT(x_Check(fAllowZero|fForbidInfo)); }
wxThread::ExitCode wxThread::Wait() { // although under Windows we can wait for any thread, it's an error to // wait for a detached one in wxWin API wxCHECK_MSG( !IsDetached(), (ExitCode)-1, wxT("can't wait for detached thread") ); ExitCode rc = (ExitCode)-1; (void)Delete(&rc); return(rc); }
void CScopeInfo_Base::x_DetachTSE(CTSE_ScopeInfo* tse) { _ASSERT(tse); _ASSERT(!IsDetached()); _ASSERT(m_TSE_ScopeInfo == tse); //_ASSERT(x_Check(fForceZero|fForbidInfo)); _ASSERT(!m_TSE_Handle); m_TSE_ScopeInfo = 0; //_ASSERT(x_Check(fForceZero|fForbidInfo)); }
void CScopeInfo_Base::x_ForgetTSE(CTSE_ScopeInfo* tse) { _ASSERT(tse); _ASSERT(!IsDetached()); _ASSERT(m_TSE_ScopeInfo == tse); _ASSERT(x_Check(fAllowZero)); m_ObjectInfo.Reset(); m_TSE_Handle.Reset(); m_TSE_ScopeInfo = 0; _ASSERT(x_Check(fForceZero|fForbidInfo)); }
wxThreadError wxThread::Kill() { if (!IsRunning()) return wxTHREAD_NOT_RUNNING; ::DosKillThread(m_internal->GetHandle()); if (IsDetached()) { delete this; } return wxTHREAD_NO_ERROR; }
void CChan::Clone(CChan& chan) { // We assume that m_sName and m_pNetwork are equal SetBufferCount(chan.GetBufferCount(), true); SetKeepBuffer(chan.KeepBuffer()); SetKey(chan.GetKey()); SetDefaultModes(chan.GetDefaultModes()); if (IsDetached() != chan.IsDetached()) { // Only send something if it makes sense // (= Only detach if client is on the channel // and only attach if we are on the channel) if (IsOn()) { if (IsDetached()) { JoinUser(false, ""); } else { DetachUser(); } } SetDetached(chan.IsDetached()); } }
void CScopeInfo_Base::x_SetLock(const CTSE_ScopeUserLock& tse, const CTSE_Info_Object& info) { _ASSERT(x_Check(fAllowZero|fAllowInfo)); _ASSERT(!IsDetached()); _ASSERT(tse); _ASSERT(&*tse == m_TSE_ScopeInfo); _ASSERT(!m_TSE_Handle || &m_TSE_Handle.x_GetScopeInfo() == &*tse); _ASSERT(!m_ObjectInfo || &GetObjectInfo_Base() == &info); m_TSE_Handle = tse; m_ObjectInfo = &reinterpret_cast<const CObject&>(info); _ASSERT(x_Check(fAllowZero|fForceInfo)); }
CString CChan::GetOptions() const { CString sRet; if (IsDetached()) { sRet += (sRet.empty()) ? "Detached" : ", Detached"; } if (KeepBuffer()) { sRet += (sRet.empty()) ? "KeepBuffer" : ", KeepBuffer"; } return sRet; }
wxThread::ExitCode wxThread::Wait() { // although under MacOS we can wait for any thread, it's an error to // wait for a detached one in wxWin API wxCHECK_MSG( !IsDetached(), (ExitCode)-1, _T("can't wait for detached thread") ); ExitCode rc = (ExitCode)-1; (void)Delete(&rc); m_internal->Free(); return rc; }
CConfig CChan::ToConfig() { CConfig config; CUser *pUser = m_pNetwork->GetUser(); if (pUser->GetBufferCount() != GetBufferCount()) config.AddKeyValuePair("Buffer", CString(GetBufferCount())); if (pUser->KeepBuffer() != KeepBuffer()) config.AddKeyValuePair("KeepBuffer", CString(KeepBuffer())); if (IsDetached()) config.AddKeyValuePair("Detached", "true"); if (!GetKey().empty()) config.AddKeyValuePair("Key", GetKey()); if (!GetDefaultModes().empty()) config.AddKeyValuePair("Modes", GetDefaultModes()); return config; }
void wxThread::Exit(ExitCode status) { m_internal->Free(); if ( IsDetached() ) { delete this; } m_internal->SetResult( status ) ; /* #if defined(__VISUALC__) || (defined(__BORLANDC__) && (__BORLANDC__ >= 0x500)) _endthreadex((unsigned)status); #else // !VC++ ::ExitThread((DWORD)status); #endif // VC++/!VC++ */ wxFAIL_MSG(wxT("Couldn't return from ExitThread()!")); }
bool CChan::WriteConfig(CFile& File) { if (!InConfig()) { return false; } File.Write("\t<Chan " + GetName().FirstLine() + ">\n"); if (m_pUser->GetBufferCount() != GetBufferCount()) m_pUser->PrintLine(File, "\tBuffer", CString(GetBufferCount())); if (m_pUser->KeepBuffer() != KeepBuffer()) m_pUser->PrintLine(File, "\tKeepBuffer", CString(KeepBuffer())); if (IsDetached()) m_pUser->PrintLine(File, "\tDetached", "true"); if (!GetKey().empty()) m_pUser->PrintLine(File, "\tKey", GetKey()); if (!GetDefaultModes().empty()) m_pUser->PrintLine(File, "\tModes", GetDefaultModes()); File.Write("\t</Chan>\n"); return true; }
wxThreadError wxThread::Kill() { if ( !IsRunning() ) return wxTHREAD_NOT_RUNNING; // if ( !::TerminateThread(m_internal->GetHandle(), (DWORD)-1) ) { wxLogSysError(_("Couldn't terminate thread")); return wxTHREAD_MISC_ERROR; } m_internal->Free(); if ( IsDetached() ) { delete this; } return wxTHREAD_NO_ERROR; }
void CChan::JoinUser(bool bForce, const CString& sKey, CClient* pClient) { if (!bForce && (!IsOn() || !IsDetached())) { m_pNetwork->PutIRC("JOIN " + GetName() + " " + ((sKey.empty()) ? GetKey() : sKey)); SetDetached(false); return; } m_pNetwork->PutUser(":" + m_pNetwork->GetIRCNick().GetNickMask() + " JOIN :" + GetName(), pClient); if (!GetTopic().empty()) { m_pNetwork->PutUser(":" + m_pNetwork->GetIRCServer() + " 332 " + m_pNetwork->GetIRCNick().GetNick() + " " + GetName() + " :" + GetTopic(), pClient); m_pNetwork->PutUser(":" + m_pNetwork->GetIRCServer() + " 333 " + m_pNetwork->GetIRCNick().GetNick() + " " + GetName() + " " + GetTopicOwner() + " " + CString(GetTopicDate()), pClient); } CString sPre = ":" + m_pNetwork->GetIRCServer() + " 353 " + m_pNetwork->GetIRCNick().GetNick() + " " + GetModeForNames() + " " + GetName() + " :"; CString sLine = sPre; CString sPerm, sNick; vector<CClient*>& vpClients = m_pNetwork->GetClients(); for (vector<CClient*>::iterator it = vpClients.begin(); it != vpClients.end(); ++it) { CClient* pThisClient; if (!pClient) pThisClient = *it; else pThisClient = pClient; for (map<CString,CNick>::iterator a = m_msNicks.begin(); a != m_msNicks.end(); ++a) { if (pThisClient->HasNamesx()) { sPerm = a->second.GetPermStr(); } else { char c = a->second.GetPermChar(); sPerm = ""; if (c != '\0') { sPerm += c; } } if (pThisClient->HasUHNames() && !a->second.GetIdent().empty() && !a->second.GetHost().empty()) { sNick = a->first + "!" + a->second.GetIdent() + "@" + a->second.GetHost(); } else { sNick = a->first; } sLine += sPerm + sNick; if (sLine.size() >= 490 || a == (--m_msNicks.end())) { m_pNetwork->PutUser(sLine, pThisClient); sLine = sPre; } else { sLine += " "; } } if (pClient) // We only want to do this for one client break; } m_pNetwork->PutUser(":" + m_pNetwork->GetIRCServer() + " 366 " + m_pNetwork->GetIRCNick().GetNick() + " " + GetName() + " :End of /NAMES list.", pClient); m_bDetached = false; // Send Buffer SendBuffer(pClient); }
wxThreadError wxThread::Delete(ExitCode *pRc) { ExitCode rc = 0; // Delete() is always safe to call, so consider all possible states // has the thread started to run? bool shouldResume = FALSE; { wxCriticalSectionLocker lock(m_critsect); if ( m_internal->GetState() == STATE_NEW ) { // WinThreadStart() will see it and terminate immediately m_internal->SetState(STATE_EXITED); shouldResume = TRUE; } } // is the thread paused? if ( shouldResume || IsPaused() ) Resume(); // does is still run? if ( IsRunning() ) { if ( IsMain() ) { // set flag for wxIsWaitingForThread() gs_waitingForThread = TRUE; #if wxUSE_GUI wxBeginBusyCursor(); #endif // wxUSE_GUI } // ask the thread to terminate { wxCriticalSectionLocker lock(m_critsect); m_internal->Cancel(); } #if wxUSE_GUI // simply wait for the thread to terminate while( TestDestroy() ) { ::YieldToAnyThread() ; } #else // !wxUSE_GUI // simply wait for the thread to terminate while( TestDestroy() ) { ::YieldToAnyThread() ; } #endif // wxUSE_GUI/!wxUSE_GUI if ( IsMain() ) { gs_waitingForThread = FALSE; #if wxUSE_GUI wxEndBusyCursor(); #endif // wxUSE_GUI } } if ( IsDetached() ) { // if the thread exits normally, this is done in WinThreadStart, but in // this case it would have been too early because // MsgWaitForMultipleObject() would fail if the therad handle was // closed while we were waiting on it, so we must do it here delete this; } if ( pRc ) *pRc = rc; return rc == (ExitCode)-1 ? wxTHREAD_MISC_ERROR : wxTHREAD_NO_ERROR; }
wxThreadError wxThread::Delete(ExitCode *pRc) { ExitCode rc = 0; // Delete() is always safe to call, so consider all possible states // we might need to resume the thread, but we might also not need to cancel // it if it doesn't run yet bool shouldResume = false, shouldCancel = true, isRunning = false; // check if the thread already started to run { wxCriticalSectionLocker lock((wxCriticalSection &)m_critsect); if ( m_internal->GetState() == STATE_NEW ) { // WinThreadStart() will see it and terminate immediately, no need // to cancel the thread - but we still need to resume it to let it // run m_internal->SetState(STATE_EXITED); Resume(); // it knows about STATE_EXITED special case shouldCancel = false; isRunning = true; // shouldResume is correctly set to false here } else { shouldResume = IsPaused(); } } // resume the thread if it is paused if ( shouldResume ) Resume(); TID hThread = m_internal->GetHandle(); if ( isRunning || IsRunning()) { if (IsMain()) { // set flag for wxIsWaitingForThread() gs_bWaitingForThread = true; } // ask the thread to terminate if ( shouldCancel ) { wxCriticalSectionLocker lock(m_critsect); m_internal->Cancel(); } #if 0 // we can't just wait for the thread to terminate because it might be // calling some GUI functions and so it will never terminate before we // process the Windows messages that result from these functions DWORD result = 0; // suppress warnings from broken compilers do { if ( IsMain() ) { // give the thread we're waiting for chance to do the GUI call // it might be in if ( (gs_nWaitingForGui > 0) && wxGuiOwnedByMainThread() ) { wxMutexGuiLeave(); } } result = ::DosWaitThread(&hThread, DCWW_NOWAIT); // FIXME: We ought to have a message processing loop here!! switch ( result ) { case ERROR_INTERRUPT: case ERROR_THREAD_NOT_TERMINATED: break; case ERROR_INVALID_THREADID: case NO_ERROR: // thread we're waiting for just terminated // or even does not exist any more. result = NO_ERROR; break; default: wxFAIL_MSG(wxT("unexpected result of DosWaitThread")); } if ( IsMain() ) { // event processing - needed if we are the main thread // to give other threads a chance to do remaining GUI // processing and terminate cleanly. wxTheApp->HandleSockets(); if (wxTheApp->Pending()) if ( !wxTheApp->DoMessage() ) { // WM_QUIT received: kill the thread Kill(); return wxTHREAD_KILLED; } else wxUsleep(10); } else wxUsleep(10); } while ( result != NO_ERROR ); #else // !wxUSE_GUI // simply wait for the thread to terminate // // OTOH, even console apps create windows (in wxExecute, for WinSock // &c), so may be use MsgWaitForMultipleObject() too here? if ( ::DosWaitThread(&hThread, DCWW_WAIT) != NO_ERROR ) { wxFAIL_MSG(wxT("unexpected result of DosWaitThread")); } #endif // wxUSE_GUI/!wxUSE_GUI if ( IsMain() ) { gs_bWaitingForThread = false; } } #if 0 // although the thread might be already in the EXITED state it might not // have terminated yet and so we are not sure that it has actually // terminated if the "if" above hadn't been taken do { if ( !::GetExitCodeThread(hThread, (LPDWORD)&rc) ) { wxLogLastError(wxT("GetExitCodeThread")); rc = (ExitCode)-1; } } while ( (DWORD)rc == STILL_ACTIVE ); #endif if ( IsDetached() ) { // if the thread exits normally, this is done in WinThreadStart, but in // this case it would have been too early because // MsgWaitForMultipleObject() would fail if the thread handle was // closed while we were waiting on it, so we must do it here delete this; } if ( pRc ) *pRc = rc; return rc == (ExitCode)-1 ? wxTHREAD_MISC_ERROR : wxTHREAD_NO_ERROR; }