Hi all, This is my first post in this forum so I hope it will help.
I have written a Qt based (4.8.3) GUI client that is used to configure a remote network switch. The GUI consists of a main thread that processes all the UI and a worker thread used to communicate with the server. All communication with the server is done using a bespoke API that in turn uses an RPC type protocol to communicate with the remote server. All API calls return an error code
So for example the client (GUI) may issue the following command
err = initializePhyPort(0)
The InitialisePhyPort API call is spawned from the main thread via a button press for example and is queued for execution by the worker thread which communicates with the server. Once the worker thread has executed the command the results are passed back to the main thread so that the GUI can be updated. here is the code for a API spawn operation:
The pre-processor constant WORKER_THREAD enables or disables the use of the worker thread
altr_ret_status_e api_operation_manager_t::add_new_and_wait(const api_data_t api_data)
{
m_mutex.lock();
m_api_op = new api_operation_t(api_data, false, false);
m_flush = false;
m_operations_pnd.push_back(m_api_op);
m_mutex.unlock();
backhaul_gui::set_wait_cursor();
backhaul_gui::set_status_busy();
altr_ret_status_e err = ALTR_RET_SUCCESS;
m_wait_op_busy = true;
#ifndef WORKER_THREAD
// This can take some time!!
run();
#endif
// Wait for the operation to complete - Note this may spawn further 'silent' ops
// Note that it is possible for the client to disconnect during this loop. In which case flush will be called
while(m_api_op->status() < OP_STATE_DONE)
{
Sleep(1);
}
// Process any pending events (usually a MSG_BOX_EVENT_TYPE)
if (m_api_op->m_event)
{
}
err = m_api_op->m_err;
// Remove anything in the done queue
m_mutex.lock();
for (api_vec_t::iterator it = m_operations_done.begin(); it != m_operations_done.end(); ++it)
{
delete *it;
}
m_operations_done.clear();
m_api_op = &m_default_op;
m_mutex.unlock();
// Signal that we are done
op_completed();
m_wait_op_busy = false;
return err;
}
altr_ret_status_e api_operation_manager_t::add_new_and_wait(const api_data_t api_data)
{
m_mutex.lock();
m_api_op = new api_operation_t(api_data, false, false);
m_flush = false;
m_operations_pnd.push_back(m_api_op);
m_mutex.unlock();
backhaul_gui::set_wait_cursor();
backhaul_gui::set_status_busy();
altr_ret_status_e err = ALTR_RET_SUCCESS;
m_wait_op_busy = true;
#ifndef WORKER_THREAD
// This can take some time!!
run();
#endif
// Wait for the operation to complete - Note this may spawn further 'silent' ops
// Note that it is possible for the client to disconnect during this loop. In which case flush will be called
while(m_api_op->status() < OP_STATE_DONE)
{
Sleep(1);
QApplication::processEvents();
}
// Process any pending events (usually a MSG_BOX_EVENT_TYPE)
if (m_api_op->m_event)
{
QCoreApplication::postEvent(g_gui, m_api_op->m_event);
}
err = m_api_op->m_err;
// Remove anything in the done queue
m_mutex.lock();
for (api_vec_t::iterator it = m_operations_done.begin(); it != m_operations_done.end(); ++it)
{
delete *it;
}
m_operations_done.clear();
m_api_op = &m_default_op;
m_mutex.unlock();
// Signal that we are done
op_completed();
m_wait_op_busy = false;
return err;
}
To copy to clipboard, switch view to plain text mode
So (in multi-threaded mode) the main thread will wait in a loop calling processEvents until the worker thread has done its thing. It will then return the error code. My problem is that under Linux I am seeing, very occasionaly, X-Server errors and I am almost certain, but not 100%, that the cause is due to the processEvents loop. When I run in single thread mode I do not see any X-Server errors.
Sorry for the somewhat long initial thread.
SJ
Bookmarks