MGR: async GUI RPCs: disallow events while processing demand RPCs, wait 1250ms before Please Wait dialog.

svn path=/workspaces/charlief/; revision=15686
This commit is contained in:
Charlie Fenton 2008-07-27 01:06:01 +00:00
parent 9248a74e2f
commit 1830e05ad4
5 changed files with 99 additions and 20 deletions

View File

@ -5994,6 +5994,19 @@ Charlie 23 July 2008
BOINCGUIApp.cpp,.h
MainDocument.cpp,.h
David 24 July 2008
- web: fix profile rate
html/user/
profile_rate.php
David 24 July 2008
- client: report all errors in parsing app_info.xml files
Fixes #703
client/
cs_statefile.C
Charlie 24 July 2008
- MGR: async GUI RPCs: Get RPCs all working in separate thread;
temporarily ignore timer events which would do RPCs while
@ -6010,6 +6023,26 @@ Charlie 24 July 2008
sg_DlgMessages.cpp
sg_ProjectsComponent.cpp
Rom 25 July 2008
- Tag for 6.3.6 release, all platforms
boinc_core_release_6_3_6
/
configure.ac
version.h
David 25 July 2008
- back-end stuff to support Python MW (from Adam Kornafeld)
Not complete.
py/Boinc/
projectxml.py
sched/
assimilate_handler.h
assimilator.C
tools/
pymw_setup
Charlie 25 July 2008
- MGR: async GUI RPCs: Implement first Periodic RPCs called
from a timer event for CachedStateUpdate(), ForceCacheUpdate(),
@ -6021,3 +6054,15 @@ Charlie 25 July 2008
BOINCBaseFrame.cpp,.h
Events.h
MainDocument.cpp,.h
Charlie 26 July 2008
- MGR: async GUI RPCs: Simulate handling of CRPCFinishedEvent but
don't allow any other events (so allow no user activity) while
processing demand RPCs. This avoids the ugly "flashing" of
windows caused by wxSafeYield() disabling the controls.
Increase delay before displaying Please Wait dialog from 250
to 1250 milliseconds.
clientgui/
AsyncRPC.cpp,h
MainDocument.cpp,.h

View File

@ -31,7 +31,7 @@
#include "BOINCBaseFrame.h"
// Delay in milliseconds before showing AsyncRPCDlg
#define RPC_WAIT_DLG_DELAY 250
#define RPC_WAIT_DLG_DELAY 1500
bool LogRPCs = false; // TEMPORARY FOR TESTING ASYNC RPCs -- CAF
@ -55,7 +55,7 @@ void ASYNC_RPC_REQUEST::clear() {
event = NULL;
eventHandler = NULL;
completionTime = NULL;
result = NULL;
resultPtr = NULL;
isActive = false;
}
@ -74,7 +74,7 @@ bool ASYNC_RPC_REQUEST::isSameAs(ASYNC_RPC_REQUEST& otherRequest) {
}
if (eventHandler != otherRequest.eventHandler) return false;
if (completionTime != otherRequest.completionTime) return false;
if (result != otherRequest.result) return false;
if (resultPtr != otherRequest.resultPtr) return false;
// OK if isActive doesn't match.
return true;
}
@ -126,6 +126,7 @@ void RPCThread::OnExit() {
void *RPCThread::Entry() {
int retval;
CRPCFinishedEvent RPC_done_event( wxEVT_RPC_FINISHED );
while(true) {
// check if we were asked to exit
@ -145,9 +146,7 @@ void *RPCThread::Entry() {
retval = ProcessRPCRequest();
CRPCFinishedEvent RPC_done_event( wxEVT_RPC_FINISHED );
RPC_done_event.SetInt(retval);
// RPC_done_event.SetInt(retval);
wxPostEvent( wxTheApp, RPC_done_event );
}
@ -372,11 +371,15 @@ int RPCThread::ProcessRPCRequest() {
#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;
@ -401,8 +404,8 @@ int CMainDocument::RequestRPC(ASYNC_RPC_REQUEST& request, bool hasPriority) {
if (iter->isSameAs(request)) return 0;
}
if ((request.event == NULL) && (request.result == NULL)) {
request.result = &retval;
if ((request.event == NULL) && (request.resultPtr == NULL)) {
request.resultPtr = &retval;
}
if (hasPriority) {
@ -456,8 +459,24 @@ int CMainDocument::RequestRPC(ASYNC_RPC_REQUEST& request, bool hasPriority) {
m_RPCWaitDlg = new AsyncRPCDlg();
do {
// ::wxSafeYield(pFrame, true); // Continue processing events
#if 0 // Yield allows user activity which can cause problems with long values of RPC_WAIT_DLG_DELAY
wxTheApp->Yield(true); // Continue processing events
// wxSafeYield prevents user activity but causes ugly disabling of coontrols
// ::wxSafeYield(pFrame, true); // Continue processing events
#else // Simulate handling of CRPCFinishedEvent but don't allow any other events (so no user activity)
// usleep(1); ///// ???? SwitchToThread() on Windows? nanosleep() on UNIX ????
#ifdef __WXMSW__
SwitchToThread();
#else
// TODO: is there a way for main UNIX thread to yield wih no minimum delay?
timespec ts = {0, 1}; /// 1 nanosecond
nanosleep(&ts, NULL); /// 1 nanosecond or less
///// ???? SwitchToThread() on Windows? nanosleep() on UNIX ????
#endif
if (!current_rpc_request.isActive) {
HandleCompletedRPC();
}
#endif
// OnRPCComplete() clears m_bWaitingForRPC if RPC completed
if (! m_bWaitingForRPC) {
// inUserRequest = false;
@ -522,11 +541,23 @@ int CMainDocument::RequestRPC(ASYNC_RPC_REQUEST& request, bool hasPriority) {
void CMainDocument::OnRPCComplete(CRPCFinishedEvent& event) {
int retval = event.GetInt();
HandleCompletedRPC();
return;
}
void CMainDocument::HandleCompletedRPC() {
int retval;
int i, n;
std::vector<ASYNC_RPC_REQUEST> completed_RPC_requests;
bool stillWaitingForPendingRequests = false;
if(current_rpc_request.isActive) return;
// We can get here either via a CRPCFinishedEvent event posted
// by the RPC thread or by a call from RequestRPC. If we were
// called from RequestRPC, the CRPCFinishedEvent will still be
// on the event queue, so we get called twice. Check for this here.
if (current_rpc_request.which_rpc == 0) return; // already handled by a call from RequestRPC
// Move all requests for the completed RPC to our local vector
// We do this in reverse order so we can remove them from queue
n = RPC_requests.size();
@ -541,7 +572,8 @@ void CMainDocument::OnRPCComplete(CRPCFinishedEvent& event) {
}
}
}
retval = current_rpc_request.retval;
current_rpc_request.clear();
// Start the next RPC request while we process the one just completed.
@ -565,8 +597,8 @@ void CMainDocument::OnRPCComplete(CRPCFinishedEvent& event) {
if (completed_RPC_requests[i].completionTime) {
*(completed_RPC_requests[i].completionTime) = wxDateTime::Now();
}
if (completed_RPC_requests[i].result) {
*(completed_RPC_requests[i].result) = retval;
if (completed_RPC_requests[i].resultPtr) {
*(completed_RPC_requests[i].resultPtr) = retval;
}
#if 1 // Post-processing
@ -827,7 +859,7 @@ void CMainDocument::TestAsyncRPC() { // TEMPORARY FOR TESTING ASYNC RPCs
request.eventHandler = NULL;
request.completionTime = &completionTime;
// request.result = NULL;
request.result = &m_iGet_state_RPC_retval; // TEMPORARY FOR TESTING ASYNC RPCs -- CAF
request.resultPtr = &m_iGet_state_RPC_retval; // TEMPORARY FOR TESTING ASYNC RPCs -- CAF
request.isActive = false;
//retval = rpcClient.get_all_projects_list(pl);

View File

@ -104,7 +104,8 @@ struct ASYNC_RPC_REQUEST {
wxEvent *event;
wxEvtHandler *eventHandler;
wxDateTime *completionTime;
int *result;
int *resultPtr;
int retval;
bool isActive;
ASYNC_RPC_REQUEST();

View File

@ -580,6 +580,7 @@ int CMainDocument::FrameShutdownDetected() {
int CMainDocument::GetCoreClientStatus(CC_STATUS& ccs, bool bForce) {
wxString strMachine = wxEmptyString;
int iRetVal = 0;
if (IsConnected()) {
if (bForce) {
m_dtCachedCCStatusTimestamp = wxDateTime::Now();
@ -671,7 +672,7 @@ void CMainDocument::RunPeriodicRPCs() {
request.exchangeBuf = &status;
request.event = (wxEvent*)-1;
request.completionTime = &m_dtCachedCCStatusTimestamp;
request.result = &cc_status_rpc_result;
request.resultPtr = &cc_status_rpc_result;
RequestRPC(request);
}
@ -686,7 +687,7 @@ void CMainDocument::RunPeriodicRPCs() {
request.arg1 = &state_altbuf;
request.exchangeBuf = &state;
request.event = (wxEvent*)-1;
request.result = &cc_state_rpc_result;
request.resultPtr = &cc_state_rpc_result;
RequestRPC(request);
@ -698,7 +699,7 @@ void CMainDocument::RunPeriodicRPCs() {
request.exchangeBuf = &host;
request.event = (wxEvent*)-1;
request.completionTime = &m_dtCachedStateTimestamp;
request.result = &host_info_rpc_result;
request.resultPtr = &host_info_rpc_result;
RequestRPC(request);
}

View File

@ -144,7 +144,6 @@ public:
bool IsConnected();
bool IsReconnecting();
int GetCoreClientStatus(CC_STATUS&, bool bForce = false);
int SetActivityRunMode(int iMode, int iTimeout);
int SetNetworkRunMode(int iMode, int iTimeout);
@ -176,6 +175,7 @@ public:
public:
int RequestRPC(ASYNC_RPC_REQUEST& request, bool hasPriority = false);
void OnRPCComplete(CRPCFinishedEvent& event);
void HandleCompletedRPC();
ASYNC_RPC_REQUEST* GetCurrentRPCRequest() { return &current_rpc_request; };
void TestAsyncRPC(); // TEMPORARY -- CAF
RPCThread* m_RPCThread;