MGR: async GUI RPCs: Suspend RPC thread when not in use.

svn path=/workspaces/charlief/; revision=15720
This commit is contained in:
Charlie Fenton 2008-07-31 01:35:17 +00:00
parent b7b281f8c2
commit 9bde2e1b44
5 changed files with 17 additions and 37 deletions

View File

@ -6188,7 +6188,9 @@ David 30 July 2008
Charlie 30 July 2008
- MGR: async GUI RPCs: under SimpleGUI, call acct_mgr_info RPC
every 10 minutes.
- MGR: async GUI RPCs: Suspend RPC thread when not in use.
clientgui/
AsyncRPC.cpp
MainDocument.cpp,.h
sg_ProjectsComponent.cpp

View File

@ -135,7 +135,7 @@ void *RPCThread::Entry() {
if (! m_Doc->GetCurrentRPCRequest()->isActive) {
// Wait until CMainDocument issues next RPC request
Yield();
Pause();
continue;
}
@ -145,11 +145,14 @@ void *RPCThread::Entry() {
}
retval = ProcessRPCRequest();
// RPC_done_event.SetInt(retval);
wxPostEvent( wxTheApp, RPC_done_event );
}
// Use a critical section to prevent a crash during
// manager shutdown due to a rare race condition
m_Doc->m_critsect.Enter();
m_Doc->m_critsect.Leave();
return NULL;
}
@ -379,18 +382,9 @@ int RPCThread::ProcessRPCRequest() {
break;
}
#if USE_CRITICAL_SECTIONS_FOR_ASYNC_RPCS
m_Doc->m_critsect.Enter();
current_request->retval = retval;
current_request->isActive = false;
m_Doc->m_critsect.Leave();
#else
// Deactivation is an atomic operation
current_request->retval = retval;
current_request->isActive = false;
#endif
return retval;
}
@ -434,17 +428,11 @@ int CMainDocument::RequestRPC(ASYNC_RPC_REQUEST& request, bool hasPriority) {
// Start this RPC if no other RPC is already in progress.
if (RPC_requests.size() == 1) {
#if USE_CRITICAL_SECTIONS_FOR_ASYNC_RPCS
m_critsect.Enter();
current_rpc_request = request;
current_rpc_request.isActive = true;
m_critsect.Leave();
#else
// Make sure activation is an atomic operation
request.isActive = false;
current_rpc_request = request;
current_rpc_request.isActive = true;
#endif
m_RPCThread->Resume();
}
// If no completion event specified, this is a user-initiated event so
@ -506,19 +494,11 @@ int CMainDocument::RequestRPC(ASYNC_RPC_REQUEST& request, bool hasPriority) {
// start a new RPC thread.
if (current_rpc_request.isActive) {
current_rpc_request.isActive = false;
#if USE_CRITICAL_SECTIONS_FOR_ASYNC_RPCS
// Killing a thread while it is in a critical section
// usually causes an unrecoverable deadlock situation
m_critsect.Enter();
#endif
m_RPCThread->Pause(); // Needed on Windows
rpcClient.close();
m_RPCThread->Kill();
#ifdef __WXMSW__
m_RPCThread->Delete(); // Needed on Windows, crashes on Mac/Linux
#endif
#if USE_CRITICAL_SECTIONS_FOR_ASYNC_RPCS
m_critsect.Leave();
#endif
m_RPCThread = NULL;
RPC_requests.clear();
@ -719,17 +699,11 @@ void CMainDocument::OnRPCComplete(CRPCFinishedEvent& event) {
// Start the next RPC request.
if (RPC_requests.size() > 0) {
#if USE_CRITICAL_SECTIONS_FOR_ASYNC_RPCS
m_critsect.Enter();
current_rpc_request = RPC_requests[0];
current_rpc_request.isActive = true;
m_critsect.Leave();
#else
// Make sure activation is an atomic operation
RPC_requests[0].isActive = false;
current_rpc_request = RPC_requests[0];
current_rpc_request.isActive = true;
#endif
m_RPCThread->Resume();
}
if (! stillWaitingForPendingRequests) {

View File

@ -32,7 +32,6 @@
//#include "gui_rpc_client.h"
#define USE_RPC_DLG_TIMER 0
#define USE_CRITICAL_SECTIONS_FOR_ASYNC_RPCS 0
class CBOINCGUIApp; // Forward declaration
class CMainDocument; // Forward declaration

View File

@ -426,7 +426,14 @@ int CMainDocument::OnExit() {
}
if (m_RPCThread) {
// Use a critical section to prevent a crash during
// manager shutdown due to a rare race condition
m_critsect.Enter();
m_RPCThread->Delete();
// On some platforms, Delete() takes effect only when thread calls TestDestroy()
m_RPCThread->Resume();
m_critsect.Leave();
wxStopWatch ThreadDeleteTimer = wxStopWatch();
// RPC thread sets m_RPCThread to NULL when it exits
while (m_RPCThread) {

View File

@ -181,9 +181,7 @@ public:
ASYNC_RPC_REQUEST* GetCurrentRPCRequest() { return &current_rpc_request; };
void TestAsyncRPC(); // TEMPORARY -- CAF
RPCThread* m_RPCThread;
#if USE_CRITICAL_SECTIONS_FOR_ASYNC_RPCS
wxCriticalSection m_critsect;
#endif
private:
ASYNC_RPC_REQUEST current_rpc_request;