Client does not inherit Thread anymore. Use separte thread to run the client on.

git-svn-id: http://voip.null.ro/svn/yate@4987 acf43c95-373e-0410-b603-e72c3f656dc1
This commit is contained in:
oana 2012-04-04 09:42:06 +00:00
parent 241e65a97f
commit edf4c2fc7a
4 changed files with 108 additions and 17 deletions

View File

@ -3398,6 +3398,11 @@ void QtClient::loadWindows(const char* file)
}
}
bool QtClient::isUIThread()
{
return (QApplication::instance() && QApplication::instance()->thread() == QThread::currentThread());
}
// Open a file open dialog window
// Parameters that can be specified include 'caption',
// 'dir', 'filter', 'selectedfilter', 'confirmoverwrite', 'choosedir'
@ -4271,8 +4276,8 @@ void QtClient::setWidgetHeight(QWidget* w, const String& height)
/**
* QtDriver
*/
QtDriver::QtDriver()
: m_init(false)
QtDriver::QtDriver(bool buildClientThread)
: m_init(false), m_clientThread(buildClientThread)
{
qInstallMsgHandler(qtMsgHandler);
}
@ -4289,7 +4294,8 @@ void QtDriver::initialize()
if (!QtClient::self()) {
debugCopy();
new QtClient;
QtClient::self()->startup();
if (m_clientThread)
QtClient::self()->startup();
}
if (!m_init) {
m_init = true;

View File

@ -152,8 +152,7 @@ public:
virtual void quit() {
if (m_app)
m_app->quit();
else
Engine::halt(0);
Engine::halt(0);
}
/**
@ -546,6 +545,7 @@ public:
protected:
virtual void loadWindows(const char* file = 0);
virtual bool isUIThread();
private:
QApplication* m_app;
ObjList m_events; // Proxy events objects
@ -554,11 +554,12 @@ private:
class YQT4_API QtDriver : public ClientDriver
{
public:
QtDriver();
QtDriver(bool buildClientThread = true);
virtual ~QtDriver();
virtual void initialize();
private:
bool m_init; // Already initialized flag
bool m_clientThread; // does the client need a thread to run on?
};
class YQT4_API QtWindow : public QWidget, public Window

View File

@ -155,6 +155,52 @@ private:
TrayIconDef() : NamedPointer("") {} // No default constructor
};
namespace { // anonymous
/**
* Helper class providing a thread on which the Client to run on
* A thread for the client
*/
class ClientThread : public Thread
{
public:
/**
* Constructor
* @param name Static name of the thread (for debugging purpose only)
* @param prio Thread priority
*/
ClientThread(Client* client, Priority prio = Normal)
: Thread("Client",prio),
m_client(client)
{ }
/**
* Destructor
*/
inline ~ClientThread()
{}
/**
* Run thread, inherited from Thread
*/
virtual void run()
{
m_client->run();
}
/**
* Clean up, inherited from Thread
*/
virtual void cleanup()
{
m_client->cleanup();
m_client->setThread(0);
}
private:
Client* m_client;
};
}; // anonymous namespace
/**
* Static classes/function/data
@ -869,8 +915,8 @@ bool ClientThreadProxy::execute()
*/
// Constructor
Client::Client(const char *name)
: Thread(name), m_initialized(false), m_line(0), m_oneThread(true),
m_defaultLogic(0)
: m_initialized(false), m_line(0), m_oneThread(true),
m_defaultLogic(0), m_clientThread(0)
{
s_client = this;
@ -912,6 +958,28 @@ Client::~Client()
Engine::halt(0);
}
bool Client::startup()
{
DDebug(ClientDriver::self(),DebugAll,"Client::startup() [%p]",this);
if (m_clientThread) {
Debug(ClientDriver::self(),DebugNote,"Trying to build a client thread when you already have one '%s' [%p]",
m_clientThread->name(),m_clientThread);
return true;
}
else {
m_clientThread = new ClientThread(this);
if (!m_clientThread->startup()) {
Debug(ClientDriver::self(),DebugWarn,"Failed to startup the client thread '%s' [%p]",m_clientThread->name(),m_clientThread);
delete static_cast<ClientThread*>(m_clientThread);
m_clientThread = 0;
return false;
}
Debug(ClientDriver::self(),DebugInfo,"Starting up client thread '%s' [%p]",m_clientThread->name(),m_clientThread);
return true;
}
return false;
}
// Cleanup before halting
void Client::cleanup()
{
@ -2116,7 +2184,7 @@ bool Client::received(Message& msg, int id)
// Postpone messages to be redispatched from UI thread
bool Client::postpone(const Message& msg, int id, bool copyUserData)
{
if (isCurrent())
if (isUIThread())
return false;
PostponedMessage* postponed = new PostponedMessage(msg,id,copyUserData);
s_postponeMutex.lock();
@ -2323,14 +2391,14 @@ bool Client::driverLock(long maxwait)
bool Client::driverLockLoop()
{
if (!(isCurrent() && ClientDriver::self()))
if (!(isUIThread() && ClientDriver::self()))
return false;
while (!driverLock()) {
if (Engine::exiting() || !ClientDriver::self())
return false;
idleActions();
yield();
Thread::yield();
}
return true;
}

View File

@ -762,10 +762,10 @@ private:
};
/**
* Singleton class that holds the User Interface's main thread and methods
* @short Thread that runs the User Interface
* Singleton class that holds the User Interface's main methods
* @short Class that runs the User Interface
*/
class YATE_API Client : public Thread, public MessageReceiver
class YATE_API Client : public MessageReceiver
{
friend class Window;
friend class ClientChannel;
@ -843,7 +843,13 @@ public:
virtual ~Client();
/**
* Run the client's thread
* Start up the client thread
* @return True if the client thread is started, false otherwise
*/
virtual bool startup();
/**
* Run the client's main loop
*/
virtual void run();
@ -879,6 +885,13 @@ public:
inline void unlockOther()
{ if (!m_oneThread) unlock(); }
/**
* Set the client's thread
* @param th The thread on which the client will run on
*/
inline void setThread(Thread* th)
{ m_clientThread = th; }
/**
* Handle all windows closed event from UI
*/
@ -1269,7 +1282,7 @@ public:
* @return True if the client is valid (running) or the method is called from client's thread
*/
static inline bool valid()
{ return self() && (self() == Thread::current() || !(exiting() || Engine::exiting())); }
{ return self() && (self()->isUIThread() || !(exiting() || Engine::exiting())); }
/**
* Check if a message is sent by the client
@ -1712,8 +1725,10 @@ protected:
virtual void initClient();
virtual void exitClient()
{}
virtual bool isUIThread()
{ return Thread::current() == m_clientThread; }
inline bool needProxy() const
{ return m_oneThread && !isCurrent(); }
{ return m_oneThread && !(Client::self() && Client::self()->isUIThread()); }
bool driverLockLoop();
static bool driverLock(long maxwait = 0);
static void driverUnlock();
@ -1731,6 +1746,7 @@ protected:
static int s_changing;
static ObjList s_logics;
static bool s_idleLogicsTick; // Call logics' timerTick()
Thread* m_clientThread;
};
/**