mirror of https://github.com/BOINC/boinc.git
MGR: First round of changes for asycn GUI RPCs; includes temporary changes for testing
svn path=/workspaces/charlief/; revision=15633
This commit is contained in:
parent
6e64b3d350
commit
f3d4907bee
|
@ -5845,3 +5845,12 @@ David 17 July 2008
|
|||
|
||||
sched/
|
||||
sched_send.C
|
||||
|
||||
Charlie 18 July 2008
|
||||
- MGR: First round of changes for asycn GUI RPCs; includes temporary
|
||||
changes for testing.
|
||||
|
||||
clientgui/
|
||||
AsyncRPC.cpp,.h
|
||||
BOINCBaseFrame.cpp,.h
|
||||
MainDocument.cpp,.h
|
||||
|
|
|
@ -0,0 +1,407 @@
|
|||
// Berkeley Open Infrastructure for Network Computing
|
||||
// http://boinc.berkeley.edu
|
||||
// Copyright (C) 2005 University of California
|
||||
//
|
||||
// This is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
// License as published by the Free Software Foundation;
|
||||
// either version 2.1 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This software is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
// See the GNU Lesser General Public License for more details.
|
||||
//
|
||||
// To view the GNU Lesser General Public License visit
|
||||
// http://www.gnu.org/copyleft/lesser.html
|
||||
// or write to the Free Software Foundation, Inc.,
|
||||
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
#if defined(__GNUG__) && !defined(__APPLE__)
|
||||
#pragma implementation "AsyncRPC.h"
|
||||
#endif
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "stdwx.h"
|
||||
//#include "wx/artprov.h"
|
||||
#include "BOINCGUIApp.h"
|
||||
#include "MainDocument.h"
|
||||
#include "AsyncRPC.h"
|
||||
//#include "BOINCClientManager.h"
|
||||
|
||||
// Delay in milliseconds before showing AsyncRPCDlg
|
||||
#define RPC_WAIT_DLG_DELAY 250
|
||||
|
||||
ASYNC_RPC_REQUEST::ASYNC_RPC_REQUEST() {
|
||||
clear();
|
||||
}
|
||||
|
||||
|
||||
ASYNC_RPC_REQUEST::~ASYNC_RPC_REQUEST() {
|
||||
clear();
|
||||
}
|
||||
|
||||
|
||||
void ASYNC_RPC_REQUEST::clear() {
|
||||
which_rpc = (RPC_SELECTOR) 0;
|
||||
inBuf = NULL;
|
||||
exchangeBuf = NULL;
|
||||
outBuf = NULL;
|
||||
event = NULL;
|
||||
eventHandler = NULL;
|
||||
completionTime = NULL;
|
||||
isActive = false;
|
||||
}
|
||||
|
||||
|
||||
bool ASYNC_RPC_REQUEST::isSameAs(ASYNC_RPC_REQUEST& otherRequest) {
|
||||
if (which_rpc != otherRequest.which_rpc) return false;
|
||||
if (inBuf != otherRequest.inBuf) return false;
|
||||
if (exchangeBuf != otherRequest.exchangeBuf) return false;
|
||||
if (outBuf != otherRequest.outBuf) return false;
|
||||
if (event != otherRequest.event) {
|
||||
if (event->GetEventType() != (otherRequest.event)->GetEventType()) return false;
|
||||
if (event->GetId() != (otherRequest.event)->GetId()) return false;
|
||||
if (event->GetEventObject() != (otherRequest.event)->GetEventObject()) return false;
|
||||
}
|
||||
if (eventHandler != otherRequest.eventHandler) return false;
|
||||
if (completionTime != otherRequest.completionTime) return false;
|
||||
// OK if isActive doesn't match.
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
RPCThread::RPCThread(CMainDocument *pDoc)
|
||||
: wxThread() {
|
||||
m_Doc = pDoc;
|
||||
}
|
||||
|
||||
|
||||
void RPCThread::OnExit() {
|
||||
}
|
||||
|
||||
|
||||
// We don't need critical sections because:
|
||||
// 1. CMainDocument never modifies mDoc->current_rpc_request while the
|
||||
// async RPC thread is using it.
|
||||
// 2. The async RPC thread never modifies either mDoc->current_rpc_request
|
||||
// or the vector of requests mDoc->RPC_requests.
|
||||
|
||||
void *RPCThread::Entry() {
|
||||
int retval;
|
||||
|
||||
while(true) {
|
||||
// check if we were asked to exit
|
||||
if ( TestDestroy() )
|
||||
break;
|
||||
|
||||
if (! m_Doc->GetCurrentRPCRequest()->isActive) {
|
||||
// Wait until CMainDocument issues next RPC request
|
||||
Yield();
|
||||
continue;
|
||||
}
|
||||
|
||||
retval = ProcessRPCRequest();
|
||||
|
||||
// TODO: Do we need a critical section here and in CBOINCGUIApp::SetActiveGUI()?
|
||||
// We need to get the frame each time, in case it was
|
||||
// changed by a call to CBOINCGUIApp::SetActiveGUI().
|
||||
CBOINCBaseFrame* pFrame = wxGetApp().GetFrame();
|
||||
wxASSERT(wxDynamicCast(pFrame, CBOINCBaseFrame));
|
||||
|
||||
CRPCFinishedEvent RPC_done_event( wxEVT_RPC_FINISHED, pFrame );
|
||||
RPC_done_event.SetInt(retval);
|
||||
|
||||
wxPostEvent( pFrame, RPC_done_event );
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
int RPCThread::ProcessRPCRequest() {
|
||||
int retval = 0;
|
||||
ASYNC_RPC_REQUEST *current_request;
|
||||
|
||||
current_request = m_Doc->GetCurrentRPCRequest();
|
||||
|
||||
switch (current_request->which_rpc) {
|
||||
case RPC_GET_RESULTS:
|
||||
if (current_request->inBuf == NULL) return -1;
|
||||
// TODO: Confirm if the following is correct
|
||||
retval = (m_Doc->rpc).get_results((RESULTS&)*(RESULTS*)(current_request->inBuf));
|
||||
break;
|
||||
case RPC_GET_ALL_PROJECTS_LIST:
|
||||
if (current_request->inBuf == NULL) return -1;
|
||||
// Sleep(5000); // TEMPORARY FOR TESTING ASYNC RPCs -- CAF
|
||||
retval = (m_Doc->rpc).get_all_projects_list((ALL_PROJECTS_LIST&)*(ALL_PROJECTS_LIST*)(current_request->inBuf));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
#if USE_CRITICAL_SECTIONS_FOR_ASYNC_RPCS
|
||||
m_Doc->m_critsect.Enter();
|
||||
current_request->isActive = false;
|
||||
m_Doc->m_critsect.Leave();
|
||||
#else
|
||||
// Deactivation is an atomic operation
|
||||
current_request->isActive = false;
|
||||
#endif
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
// We don't need critical sections because:
|
||||
// 1. CMainDocument never modifies mDoc->current_rpc_request while the
|
||||
// async RPC thread is using it.
|
||||
// 2. The async RPC thread never modifies either mDoc->current_rpc_request
|
||||
// or the vector of requests mDoc->RPC_requests.
|
||||
|
||||
// TODO: combine RPC requests for different buffers, then just copy the buffer.
|
||||
|
||||
int CMainDocument::RequestRPC(ASYNC_RPC_REQUEST& request) {
|
||||
static bool inUserRequest = false;
|
||||
std::vector<ASYNC_RPC_REQUEST>::iterator iter;
|
||||
int retval = 0;
|
||||
|
||||
// Check if a duplicate request is already on the queue
|
||||
for (iter=RPC_requests.begin(); iter!=RPC_requests.end(); iter++) {
|
||||
if (iter->isSameAs(request)) return 0;
|
||||
}
|
||||
|
||||
if (request.event == NULL) {
|
||||
// If no completion event specified, this is a user-initiated event.
|
||||
// Since the user is waiting, insert this at head of request queue
|
||||
iter = RPC_requests.insert(RPC_requests.begin(), request);
|
||||
} else {
|
||||
RPC_requests.push_back(request);
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
// If no completion event specified, this is a user-initiated event so
|
||||
// wait for completion but show a dialog allowing the user to cancel.
|
||||
if ((request.event == NULL) && !inUserRequest) {
|
||||
inUserRequest = true;
|
||||
// Don't show dialog if RPC completes before RPC_WAIT_DLG_DELAY
|
||||
wxStopWatch Dlgdelay = wxStopWatch();
|
||||
m_RPCWaitDlg = new AsyncRPCDlg();
|
||||
do {
|
||||
// OnRPCComplete() sets m_RPCWaitDlg to NULL if RPC completed
|
||||
if (! m_RPCWaitDlg) {
|
||||
inUserRequest = false;
|
||||
return retval;
|
||||
}
|
||||
::wxSafeYield(NULL, true); // Continue processing events
|
||||
} while (Dlgdelay.Time() < RPC_WAIT_DLG_DELAY);
|
||||
|
||||
// TODO: ****** Cancel RPC if user pressed Cancel. ********
|
||||
// TODO: ****** Because buffer may have been on stack! ********
|
||||
if (m_RPCWaitDlg) {
|
||||
// GetCurrentProcess(&psn);
|
||||
// SetFrontProcess(&psn); // Shows process if hidden
|
||||
if (m_RPCWaitDlg->ShowModal() != wxID_OK) retval = -1;
|
||||
if (m_RPCWaitDlg)
|
||||
m_RPCWaitDlg->Destroy();
|
||||
m_RPCWaitDlg = NULL;
|
||||
}
|
||||
inUserRequest = false;
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
void CMainDocument::OnRPCComplete(CRPCFinishedEvent& event) {
|
||||
int retval = event.GetInt();
|
||||
int i, n;
|
||||
std::vector<ASYNC_RPC_REQUEST> completed_RPC_requests;
|
||||
|
||||
// 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();
|
||||
for (i=n-1; i>=0; --i) {
|
||||
if (RPC_requests[i].which_rpc == current_rpc_request.which_rpc) {
|
||||
completed_RPC_requests.push_back(RPC_requests[i]);
|
||||
RPC_requests[i].event = NULL; // Is this needed to prevent calling event's destructor?
|
||||
RPC_requests.erase(RPC_requests.begin()+i);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
current_rpc_request.clear();
|
||||
|
||||
// Start the next RPC request while we process the one just completed.
|
||||
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
|
||||
}
|
||||
|
||||
// Now process the requests we have satisfied.
|
||||
n = completed_RPC_requests.size();
|
||||
for (i=n-1; i>=0; --i) {
|
||||
if (completed_RPC_requests[i].completionTime) {
|
||||
*(completed_RPC_requests[i].completionTime) = wxDateTime::Now();
|
||||
}
|
||||
|
||||
switch (completed_RPC_requests[i].which_rpc) {
|
||||
case RPC_GET_RESULTS:
|
||||
m_iGet_results_RPC_retval = retval;
|
||||
if (completed_RPC_requests[i].exchangeBuf) {
|
||||
RESULTS* inBuf = (RESULTS*)completed_RPC_requests[i].inBuf;
|
||||
RESULTS* exchangeBuf = (RESULTS*)completed_RPC_requests[i].exchangeBuf;
|
||||
inBuf->results.swap(exchangeBuf->results);
|
||||
}
|
||||
break;
|
||||
case RPC_GET_ALL_PROJECTS_LIST:
|
||||
m_iGet_results_RPC_retval = retval;
|
||||
if (completed_RPC_requests[i].exchangeBuf) {
|
||||
ALL_PROJECTS_LIST* inBuf = (ALL_PROJECTS_LIST*)completed_RPC_requests[i].inBuf;
|
||||
ALL_PROJECTS_LIST* exchangeBuf = (ALL_PROJECTS_LIST*)completed_RPC_requests[i].exchangeBuf;
|
||||
inBuf->projects.swap(exchangeBuf->projects);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (completed_RPC_requests[i].event) {
|
||||
if (completed_RPC_requests[i].eventHandler) {
|
||||
completed_RPC_requests[i].eventHandler->ProcessEvent(*completed_RPC_requests[i].event);
|
||||
} else {
|
||||
CBOINCBaseFrame* pFrame = wxGetApp().GetFrame();
|
||||
wxASSERT(wxDynamicCast(pFrame, CBOINCBaseFrame));
|
||||
pFrame->ProcessEvent(*completed_RPC_requests[i].event);
|
||||
}
|
||||
delete completed_RPC_requests[i].event;
|
||||
completed_RPC_requests[i].event = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_RPCWaitDlg) {
|
||||
if (m_RPCWaitDlg->IsShown()) {
|
||||
m_RPCWaitDlg->EndModal(wxID_OK);
|
||||
} else {
|
||||
m_RPCWaitDlg->Destroy();
|
||||
m_RPCWaitDlg = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
IMPLEMENT_CLASS(AsyncRPCDlg, wxDialog)
|
||||
|
||||
AsyncRPCDlg::AsyncRPCDlg() : wxDialog( NULL, wxID_ANY, wxT(""), wxDefaultPosition ) {
|
||||
|
||||
wxString message = wxString(_("Communicating with BOINC client. Please wait ..."));
|
||||
|
||||
wxBoxSizer *topsizer = new wxBoxSizer( wxVERTICAL );
|
||||
wxBoxSizer *icon_text = new wxBoxSizer( wxHORIZONTAL );
|
||||
|
||||
// wxBitmap bitmap = wxArtProvider::GetIcon(wxART_INFORMATION, wxART_MESSAGE_BOX);
|
||||
// wxStaticBitmap *icon = new wxStaticBitmap(this, wxID_ANY, bitmap);
|
||||
// icon_text->Add( icon, 0, wxCENTER );
|
||||
|
||||
icon_text->Add( CreateTextSizer( message ), 0, wxALIGN_CENTER | wxLEFT, 10 );
|
||||
topsizer->Add( icon_text, 1, wxCENTER | wxLEFT|wxRIGHT|wxTOP, 10 );
|
||||
|
||||
int center_flag = wxEXPAND;
|
||||
wxSizer *sizerBtn = CreateSeparatedButtonSizer(wxCANCEL|wxNO_DEFAULT);
|
||||
if ( sizerBtn )
|
||||
topsizer->Add(sizerBtn, 0, center_flag | wxALL, 10 );
|
||||
|
||||
SetAutoLayout( true );
|
||||
SetSizer( topsizer );
|
||||
|
||||
topsizer->SetSizeHints( this );
|
||||
topsizer->Fit( this );
|
||||
wxSize size( GetSize() );
|
||||
if (size.x < size.y*3/2)
|
||||
{
|
||||
size.x = size.y*3/2;
|
||||
SetSize( size );
|
||||
}
|
||||
|
||||
Centre( wxBOTH | wxCENTER_FRAME);
|
||||
|
||||
#if USE_RPC_DLG_TIMER
|
||||
m_pDlgDelayTimer = new wxTimer(this, wxID_ANY);
|
||||
wxASSERT(m_pDlgDelayTimer);
|
||||
|
||||
m_pDlgDelayTimer->Start(100, false);
|
||||
#endif // USE_RPC_DLG_TIMER
|
||||
}
|
||||
|
||||
|
||||
#if USE_RPC_DLG_TIMER
|
||||
BEGIN_EVENT_TABLE(AsyncRPCDlg, wxMessageDialog)
|
||||
EVT_TIMER(wxID_ANY, AsyncRPCDlg::OnRPCDlgTimer)
|
||||
END_EVENT_TABLE()
|
||||
|
||||
AsyncRPCDlg::~AsyncRPCDlg() {
|
||||
if (m_pDlgDelayTimer) {
|
||||
m_pDlgDelayTimer->Stop();
|
||||
delete m_pDlgDelayTimer;
|
||||
m_pDlgDelayTimer = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void AsyncRPCDlg::OnRPCDlgTimer(wxTimerEvent& WXUNUSED(event)) {
|
||||
::wxWakeUpIdle();
|
||||
}
|
||||
#endif // USE_RPC_DLG_TIMER
|
||||
|
||||
/// For testing: triggered by Advanced / Options menu item.
|
||||
ALL_PROJECTS_LIST pl;
|
||||
|
||||
void CMainDocument::TestAsyncRPC() { // TEMPORARY FOR TESTING ASYNC RPCs -- CAF
|
||||
ASYNC_RPC_REQUEST request;
|
||||
wxDateTime completionTime;
|
||||
int retval = 0;
|
||||
|
||||
completionTime.ResetTime();
|
||||
|
||||
request.which_rpc = RPC_GET_ALL_PROJECTS_LIST;
|
||||
request.inBuf = &pl;
|
||||
request.exchangeBuf = NULL;
|
||||
request.outBuf = NULL;
|
||||
request.event = NULL;
|
||||
request.eventHandler = NULL;
|
||||
request.completionTime = &completionTime;
|
||||
request.isActive = false;
|
||||
|
||||
//retval = rpc.get_all_projects_list(pl);
|
||||
|
||||
retval = RequestRPC(request);
|
||||
|
||||
wxString s = completionTime.Format("%T");
|
||||
printf("Completion time = %s\n", s.c_str());
|
||||
printf("RequestRPC returned %d\n", retval);
|
||||
}
|
||||
|
|
@ -0,0 +1,165 @@
|
|||
// Berkeley Open Infrastructure for Network Computing
|
||||
// http://boinc.berkeley.edu
|
||||
// Copyright (C) 2005 University of California
|
||||
//
|
||||
// This is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
// License as published by the Free Software Foundation;
|
||||
// either version 2.1 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This software is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
// See the GNU Lesser General Public License for more details.
|
||||
//
|
||||
// To view the GNU Lesser General Public License visit
|
||||
// http://www.gnu.org/copyleft/lesser.html
|
||||
// or write to the Free Software Foundation, Inc.,
|
||||
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
#ifndef _ASYNCRPC_H_
|
||||
#define _ASYNCRPC_H_
|
||||
|
||||
#if defined(__GNUG__) && !defined(__APPLE__)
|
||||
#pragma interface "AsyncRPC.cpp"
|
||||
#endif
|
||||
|
||||
#include "wx/thread.h"
|
||||
|
||||
#include "BOINCBaseFrame.h"
|
||||
|
||||
//#include "common_defs.h"
|
||||
//#include "gui_rpc_client.h"
|
||||
|
||||
#define USE_RPC_DLG_TIMER 0
|
||||
#define USE_CRITICAL_SECTIONS_FOR_ASYNC_RPCS 0
|
||||
|
||||
class CMainDocument; // Forward declaration
|
||||
|
||||
|
||||
enum RPC_SELECTOR {
|
||||
RPC_INIT_POLL = 1,
|
||||
RPC_AUTHORIZE,
|
||||
RPC_INIT_ASYNCH,
|
||||
RPC_EXCHANGE_VERSIONS,
|
||||
RPC_GET_STATE,
|
||||
RPC_GET_HOST_INFO,
|
||||
RPC_GET_CC_STATUS,
|
||||
RPC_GET_PROJECT_STATUS,
|
||||
RPC_GET_RESULTS,
|
||||
RPC_GET_MESSAGES,
|
||||
RPC_GET_FILE_TRANSFERS,
|
||||
RPC_GET_DISK_USAGE,
|
||||
RPC_GET_STATISTICS,
|
||||
RPC_GET_PROXY_SETTINGS,
|
||||
RPC_GET_SIMPLE_GUI_INFO,
|
||||
RPC_SET_RUN_MODE,
|
||||
RPC_SET_NETWORK_MODE,
|
||||
RPC_RUN_BENCHMARKS,
|
||||
RPC_QUIT,
|
||||
RPC_SET_PROXY_SETTINGS,
|
||||
RPC_PROJECT_OP,
|
||||
RPC_RESULT_OP,
|
||||
RPC_SHOW_GRAPHICS,
|
||||
RPC_FILE_TRANSFER_OP,
|
||||
RPC_ACCT_MGR_RPC,
|
||||
RPC_ACCT_MGR_RPC_POLL,
|
||||
RPC_GET_PROJECT_CONFIG,
|
||||
RPC_GET_PROJECT_CONFIG_POLL,
|
||||
RPC_ACCT_MGR_INFO,
|
||||
RPC_READ_GLOBAL_PREFS_OVERRIDE,
|
||||
RPC_READ_CC_CONFIG,
|
||||
RPC_NETWORK_AVAILABLE,
|
||||
RPC_GET_PROJECT_INIT_STATUS,
|
||||
RPC_INIT,
|
||||
RPC_GET_GLOBAL_PREFS_WORKING_STRUCT,
|
||||
RPC_GET_GLOBAL_PREFS_OVERRIDE_STRUCT,
|
||||
RPC_SET_GLOBAL_PREFS_OVERRIDE_STRUCT,
|
||||
RPC_CREATE_ACCOUNT,
|
||||
RPC_CREATE_ACCOUNT_POLL,
|
||||
RPC_LOOKUP_ACCOUNT,
|
||||
RPC_LOOKUP_ACCOUNT_POLL,
|
||||
RPC_PROJECT_ATTACH,
|
||||
RPC_PROJECT_ATTACH_FROM_FILE,
|
||||
RPC_PROJECT_ATTACH_POLL,
|
||||
RPC_GET_ALL_PROJECTS_LIST
|
||||
};
|
||||
|
||||
|
||||
struct ASYNC_RPC_REQUEST {
|
||||
RPC_SELECTOR which_rpc;
|
||||
void *inBuf;
|
||||
void *exchangeBuf;
|
||||
void *outBuf;
|
||||
wxEvent *event;
|
||||
wxEvtHandler *eventHandler;
|
||||
wxDateTime *completionTime;
|
||||
bool isActive;
|
||||
|
||||
ASYNC_RPC_REQUEST();
|
||||
~ASYNC_RPC_REQUEST();
|
||||
|
||||
void clear();
|
||||
bool isSameAs(ASYNC_RPC_REQUEST& otherRequest);
|
||||
};
|
||||
|
||||
|
||||
class RPCThread : public wxThread
|
||||
{
|
||||
public:
|
||||
RPCThread(CMainDocument *pDoc);
|
||||
virtual void *Entry();
|
||||
virtual void OnExit();
|
||||
|
||||
private:
|
||||
int ProcessRPCRequest();
|
||||
|
||||
CMainDocument *m_Doc;
|
||||
};
|
||||
|
||||
|
||||
class AsyncRPCDlg : public wxDialog
|
||||
{
|
||||
DECLARE_DYNAMIC_CLASS( AsyncRPCDlg )
|
||||
|
||||
public:
|
||||
AsyncRPCDlg();
|
||||
void OnRPCDlgTimer(wxTimerEvent &event);
|
||||
|
||||
#if USE_RPC_DLG_TIMER
|
||||
~AsyncRPCDlg();
|
||||
private:
|
||||
wxTimer* m_pDlgDelayTimer;
|
||||
|
||||
DECLARE_EVENT_TABLE()
|
||||
#endif // USE_RPC_DLG_TIMER
|
||||
};
|
||||
|
||||
|
||||
class CRPCFinishedEvent : public wxEvent
|
||||
{
|
||||
public:
|
||||
CRPCFinishedEvent(wxEventType evtType, CBOINCBaseFrame *pFrame)
|
||||
: wxEvent(-1, evtType)
|
||||
{
|
||||
SetEventObject(pFrame);
|
||||
}
|
||||
|
||||
virtual wxEvent * Clone() const { return new CRPCFinishedEvent(*this); }
|
||||
|
||||
void SetInt(int i) { m_retval = i; }
|
||||
int GetInt() const { return m_retval; }
|
||||
private:
|
||||
int m_retval;
|
||||
};
|
||||
|
||||
BEGIN_DECLARE_EVENT_TYPES()
|
||||
DECLARE_EVENT_TYPE( wxEVT_RPC_FINISHED, -1 )
|
||||
END_DECLARE_EVENT_TYPES()
|
||||
|
||||
#define EVT_RPC_FINISHED(fn) \
|
||||
DECLARE_EVENT_TABLE_ENTRY(wxEVT_RPC_FINISHED, -1, -1, (wxObjectEventFunction) (wxEventFunction) &fn, NULL),
|
||||
|
||||
|
||||
|
||||
#endif // _ASYNCRPC_H_
|
|
@ -45,6 +45,7 @@ DEFINE_EVENT_TYPE(wxEVT_FRAME_INITIALIZED)
|
|||
DEFINE_EVENT_TYPE(wxEVT_FRAME_REFRESHVIEW)
|
||||
DEFINE_EVENT_TYPE(wxEVT_FRAME_UPDATESTATUS)
|
||||
DEFINE_EVENT_TYPE(wxEVT_FRAME_RELOADSKIN)
|
||||
DEFINE_EVENT_TYPE(wxEVT_RPC_FINISHED)
|
||||
|
||||
|
||||
IMPLEMENT_DYNAMIC_CLASS(CBOINCBaseFrame, wxFrame)
|
||||
|
@ -56,6 +57,7 @@ BEGIN_EVENT_TABLE (CBOINCBaseFrame, wxFrame)
|
|||
EVT_FRAME_ALERT(CBOINCBaseFrame::OnAlert)
|
||||
EVT_CLOSE(CBOINCBaseFrame::OnClose)
|
||||
EVT_MENU(ID_FILECLOSEWINDOW, CBOINCBaseFrame::OnCloseWindow)
|
||||
EVT_RPC_FINISHED(CBOINCBaseFrame::OnRPCFinished)
|
||||
END_EVENT_TABLE ()
|
||||
|
||||
|
||||
|
@ -289,6 +291,16 @@ void CBOINCBaseFrame::OnCloseWindow(wxCommandEvent& WXUNUSED(event)) {
|
|||
}
|
||||
|
||||
|
||||
void CBOINCBaseFrame::OnRPCFinished( CRPCFinishedEvent& event ) {
|
||||
CMainDocument* pDoc = wxGetApp().GetDocument();
|
||||
|
||||
wxASSERT(pDoc);
|
||||
wxASSERT(wxDynamicCast(pDoc, CMainDocument));
|
||||
|
||||
pDoc->OnRPCComplete(event);
|
||||
}
|
||||
|
||||
|
||||
void CBOINCBaseFrame::OnExit(wxCommandEvent& WXUNUSED(event)) {
|
||||
wxLogTrace(wxT("Function Start/End"), wxT("CAdvancedFrame::OnExit - Function Begin"));
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
class CFrameEvent;
|
||||
class CFrameAlertEvent;
|
||||
class CBOINCDialUpManager;
|
||||
class CRPCFinishedEvent;
|
||||
|
||||
enum FrameAlertEventType {
|
||||
AlertNormal = 0,
|
||||
|
@ -61,6 +62,7 @@ public:
|
|||
virtual void OnClose( wxCloseEvent& event );
|
||||
virtual void OnCloseWindow( wxCommandEvent& event );
|
||||
virtual void OnExit( wxCommandEvent& event );
|
||||
virtual void OnRPCFinished( CRPCFinishedEvent& event );
|
||||
|
||||
int GetReminderFrequency() { return m_iReminderFrequency; }
|
||||
wxString GetDialupConnectionName() { return m_strNetworkDialupConnectionName; }
|
||||
|
|
|
@ -64,7 +64,7 @@ CNetworkConnection::CNetworkConnection(CMainDocument* pDocument) :
|
|||
m_bUsedDefaultPassword = false;
|
||||
m_iPort = GUI_RPC_PORT,
|
||||
m_iReadGUIRPCAuthFailure = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
CNetworkConnection::~CNetworkConnection() {
|
||||
|
@ -378,6 +378,16 @@ int CMainDocument::OnInit() {
|
|||
m_pClientManager = new CBOINCClientManager();
|
||||
wxASSERT(m_pClientManager);
|
||||
|
||||
m_RPCWaitDlg = NULL;
|
||||
|
||||
m_RPCThread = new RPCThread(this);
|
||||
wxASSERT(m_RPCThread);
|
||||
|
||||
iRetVal = m_RPCThread->Create();
|
||||
wxASSERT(iRetVal);
|
||||
|
||||
m_RPCThread->Run();
|
||||
|
||||
return iRetVal;
|
||||
}
|
||||
|
||||
|
@ -956,6 +966,7 @@ int CMainDocument::CachedResultsStatusUpdate() {
|
|||
m_dtResultsTimestamp = wxDateTime::Now();
|
||||
|
||||
iRetVal = rpc.get_results(results);
|
||||
iRetVal = m_iGet_results_RPC_retval;
|
||||
if (iRetVal) {
|
||||
wxLogTrace(wxT("Function Status"), wxT("CMainDocument::CachedResultsStatusUpdate - Get Result Status Failed '%d'"), iRetVal);
|
||||
ForceCacheUpdate();
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include <vector>
|
||||
#include "common_defs.h"
|
||||
#include "gui_rpc_client.h"
|
||||
#include "asyncRPC.h"
|
||||
|
||||
typedef struct {
|
||||
int slot;
|
||||
|
@ -159,6 +160,23 @@ public:
|
|||
HOST_INFO host;
|
||||
wxDateTime m_dtCachedStateTimestamp;
|
||||
|
||||
//
|
||||
// Async RPC support
|
||||
//
|
||||
public:
|
||||
int RequestRPC(ASYNC_RPC_REQUEST& request);
|
||||
void OnRPCComplete(CRPCFinishedEvent& event);
|
||||
ASYNC_RPC_REQUEST* GetCurrentRPCRequest() { return ¤t_rpc_request; };
|
||||
void TestAsyncRPC(); // TEMPORARY -- CAF
|
||||
#if USE_CRITICAL_SECTIONS_FOR_ASYNC_RPCS
|
||||
wxCriticalSection m_critsect;
|
||||
#endif
|
||||
|
||||
private:
|
||||
RPCThread* m_RPCThread;
|
||||
ASYNC_RPC_REQUEST current_rpc_request;
|
||||
AsyncRPCDlg* m_RPCWaitDlg;
|
||||
std::vector<ASYNC_RPC_REQUEST> RPC_requests;
|
||||
|
||||
//
|
||||
// Project Tab
|
||||
|
@ -210,6 +228,8 @@ private:
|
|||
|
||||
public:
|
||||
RESULTS results;
|
||||
RESULTS async_results_buf;
|
||||
int m_iGet_results_RPC_retval;
|
||||
RESULT* result(unsigned int);
|
||||
RESULT* result(const wxString& name, const wxString& project_url);
|
||||
|
||||
|
|
Loading…
Reference in New Issue