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:
parent
241e65a97f
commit
edf4c2fc7a
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
28
yatecbase.h
28
yatecbase.h
|
@ -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;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue