Do load and unload of modules on the main thread. Added the possibility of replacing themain loop of the engine.

git-svn-id: http://voip.null.ro/svn/yate@4999 acf43c95-373e-0410-b603-e72c3f656dc1
This commit is contained in:
oana 2012-04-06 15:27:35 +00:00
parent d3510a2ab7
commit 962647b836
6 changed files with 65 additions and 38 deletions

View File

@ -46,25 +46,20 @@ public:
void EngineThread::run() void EngineThread::run()
{ {
Engine::engineRun(); Engine::self()->run();
Debug(DebugAll,"Engine stopped running"); Debug(DebugAll,"Engine stopped running");
} }
void EngineThread::cleanup() void EngineThread::cleanup()
{ {
Debug(DebugAll,"EngineThread::cleanup() [%p]",this); Debug(DebugAll,"EngineThread::cleanup() [%p]",this);
if (QtClient::self())
QtClient::self()->quit();
s_engineThread = 0; s_engineThread = 0;
} }
static int mainLoop()
extern "C" int main(int argc, const char** argv, const char** envp)
{ {
TelEngine::Engine::extraPath("qt4");
// parse arguments
int retcode = TelEngine::Engine::main(argc,argv,envp,TelEngine::Engine::ClientMainThread);
if (retcode)
return retcode;
// create engine from this thread // create engine from this thread
Engine::self(); Engine::self();
s_engineThread = new EngineThread; s_engineThread = new EngineThread;
@ -73,20 +68,25 @@ extern "C" int main(int argc, const char** argv, const char** envp)
// build client if the driver didn't // build client if the driver didn't
if (!QtClient::self()) if (!QtClient::self())
new QtClient(); QtClient::setSelf(new QtClient());
// run the client // run the client
QtClient::self()->run(); if (!Engine::exiting())
QtClient::self()->run();
// the client finished running, do cleanup // the client finished running, do cleanup
QtClient::self()->cleanup(); QtClient::self()->cleanup();
// wait for the engine to halt
Engine::halt(0); Engine::halt(0);
unsigned long count = WAIT_ENGINE / Thread::idleMsec(); unsigned long count = WAIT_ENGINE / Thread::idleMsec();
while (s_engineThread && count--) while (s_engineThread && count--)
Thread::idle(); Thread::idle();
Thread::killall();
return retcode; return 0;
}
extern "C" int main(int argc, const char** argv, const char** envp)
{
TelEngine::Engine::extraPath("qt4");
return TelEngine::Engine::main(argc,argv,envp,TelEngine::Engine::Client,&mainLoop);
} }
/* vi: set ts=8 sw=4 sts=4 noet: */ /* vi: set ts=8 sw=4 sts=4 noet: */

View File

@ -3308,7 +3308,8 @@ void QtClient::cleanup()
Client::save(s_save); Client::save(s_save);
QtWindow::clearUICache(); QtWindow::clearUICache();
m_app->quit(); m_app->quit();
delete m_app; if (!m_app->startingUp())
delete m_app;
} }
void QtClient::run() void QtClient::run()
@ -3333,12 +3334,15 @@ void QtClient::run()
// Create events proxy // Create events proxy
m_events.append(new QtEventProxy(QtEventProxy::Timer)); m_events.append(new QtEventProxy(QtEventProxy::Timer));
m_events.append(new QtEventProxy(QtEventProxy::AllHidden,m_app)); m_events.append(new QtEventProxy(QtEventProxy::AllHidden,m_app));
if (Engine::exiting())
return;
Client::run(); Client::run();
} }
void QtClient::main() void QtClient::main()
{ {
m_app->exec(); if (!Engine::exiting())
m_app->exec();
} }
void QtClient::lock() void QtClient::lock()
@ -4293,7 +4297,7 @@ void QtDriver::initialize()
s_device = Engine::config().getValue("client","device",DEFAULT_DEVICE); s_device = Engine::config().getValue("client","device",DEFAULT_DEVICE);
if (!QtClient::self()) { if (!QtClient::self()) {
debugCopy(); debugCopy();
new QtClient; QtClient::setSelf(new QtClient);
if (m_clientThread) if (m_clientThread)
QtClient::self()->startup(); QtClient::self()->startup();
} }

View File

@ -918,8 +918,6 @@ Client::Client(const char *name)
: m_initialized(false), m_line(0), m_oneThread(true), : m_initialized(false), m_line(0), m_oneThread(true),
m_defaultLogic(0), m_clientThread(0) m_defaultLogic(0), m_clientThread(0)
{ {
s_client = this;
// Set default options // Set default options
for (unsigned int i = 0; i < OptCount; i++) for (unsigned int i = 0; i < OptCount; i++)
m_toggles[i] = false; m_toggles[i] = false;

View File

@ -755,14 +755,17 @@ static bool logFileOpen()
} }
return false; return false;
} }
static int engineRun(EngineLoop loop = 0)
int Engine::engineRun()
{ {
time_t t = ::time(0); time_t t = ::time(0);
s_startMsg << "Yate (" << ::getpid() << ") is starting " << ::ctime(&t); s_startMsg << "Yate (" << ::getpid() << ") is starting " << ::ctime(&t);
s_startMsg.trimSpaces(); s_startMsg.trimSpaces();
Output("%s",s_startMsg.c_str()); Output("%s",s_startMsg.c_str());
int retcode = Engine::self()->run(); int retcode = Engine::self()->engineInit();
if (!retcode)
retcode = (loop ? loop() : Engine::self()->run());
if (!retcode)
retcode = Engine::self()->engineCleanup();
t = ::time(0); t = ::time(0);
Output("Yate (%u) is stopping %s",::getpid(),::ctime(&t)); Output("Yate (%u) is stopping %s",::getpid(),::ctime(&t));
return retcode; return retcode;
@ -832,7 +835,7 @@ static void serviceMain(DWORD argc, LPTSTR* argv)
return; return;
} }
setStatus(SERVICE_START_PENDING); setStatus(SERVICE_START_PENDING);
Engine::engineRun(); engineRun();
} }
static SERVICE_TABLE_ENTRY dispatchTable[] = static SERVICE_TABLE_ENTRY dispatchTable[] =
@ -1164,7 +1167,7 @@ Engine::~Engine()
s_self = 0; s_self = 0;
} }
int Engine::run() int Engine::engineInit()
{ {
#ifdef _WINDOWS #ifdef _WINDOWS
// In Windows we must initialize the socket library very early because even trivial // In Windows we must initialize the socket library very early because even trivial
@ -1289,7 +1292,6 @@ int Engine::run()
Debug(DebugAll,"Engine dispatching start message"); Debug(DebugAll,"Engine dispatching start message");
dispatch("engine.start",true); dispatch("engine.start",true);
setStatus(SERVICE_RUNNING); setStatus(SERVICE_RUNNING);
long corr = 0;
#ifndef _WINDOWS #ifndef _WINDOWS
::signal(SIGHUP,sighandler); ::signal(SIGHUP,sighandler);
::signal(SIGQUIT,sighandler); ::signal(SIGQUIT,sighandler);
@ -1306,6 +1308,14 @@ int Engine::run()
} }
Output("Yate%s engine is initialized and starting up%s%s", Output("Yate%s engine is initialized and starting up%s%s",
clientMode() ? " client" : "",s_node.null() ? "" : " on " ,s_node.safe()); clientMode() ? " client" : "",s_node.null() ? "" : " on " ,s_node.safe());
return 0;
}
int Engine::run()
{
// engine loop
long corr = 0;
int stops = MAX_STOP; int stops = MAX_STOP;
while (s_haltcode == -1 || ((--stops >= 0) && dispatch("engine.stop",true))) { while (s_haltcode == -1 || ((--stops >= 0) && dispatch("engine.stop",true))) {
if (s_cmds) { if (s_cmds) {
@ -1395,6 +1405,11 @@ int Engine::run()
Thread::yield(); Thread::yield();
} }
s_haltcode &= 0xff; s_haltcode &= 0xff;
return 0;
}
int Engine::engineCleanup()
{
Output("Yate engine is shutting down with code %d",s_haltcode); Output("Yate engine is shutting down with code %d",s_haltcode);
CapturedEvent::capturing(false); CapturedEvent::capturing(false);
setStatus(SERVICE_STOP_PENDING); setStatus(SERVICE_STOP_PENDING);
@ -1850,7 +1865,7 @@ static void version()
::fprintf(stdout,"Yate " YATE_VERSION " " YATE_STATUS YATE_RELEASE "\n"); ::fprintf(stdout,"Yate " YATE_VERSION " " YATE_STATUS YATE_RELEASE "\n");
} }
int Engine::main(int argc, const char** argv, const char** env, RunMode mode, bool fail) int Engine::main(int argc, const char** argv, const char** env, RunMode mode, EngineLoop loop, bool fail)
{ {
#ifdef _WINDOWS #ifdef _WINDOWS
int service = 0; int service = 0;
@ -1858,9 +1873,6 @@ int Engine::main(int argc, const char** argv, const char** env, RunMode mode, bo
bool daemonic = false; bool daemonic = false;
bool supervised = false; bool supervised = false;
#endif #endif
bool noStart = (mode == ClientMainThread);
if (noStart)
mode = Client;
bool client = (mode == Client); bool client = (mode == Client);
Debugger::Formatting tstamp = Debugger::None; Debugger::Formatting tstamp = Debugger::None;
bool colorize = false; bool colorize = false;
@ -2311,7 +2323,7 @@ int Engine::main(int argc, const char** argv, const char** env, RunMode mode, bo
} }
else else
#endif #endif
retcode = noStart ? 0 : engineRun(); retcode = engineRun(loop);
return retcode; return retcode;
} }

View File

@ -1276,6 +1276,8 @@ public:
{ return m_initialized; } { return m_initialized; }
inline static Client* self() inline static Client* self()
{ return s_client; } { return s_client; }
inline static void setSelf(Client* client)
{ s_client = client; }
/** /**
* Check if the client object still exists and the client or engine is not exiting * Check if the client object still exists and the client or engine is not exiting

View File

@ -800,6 +800,11 @@ public:
static void setChecker(EngineCheck* ptr = 0); static void setChecker(EngineCheck* ptr = 0);
}; };
/**
* Prototype for engine main loop callback
*/
typedef int (*EngineLoop)();
/** /**
* This class holds global information about the engine. * This class holds global information about the engine.
* Note: this is a singleton class. * Note: this is a singleton class.
@ -821,7 +826,6 @@ public:
Server = 2, Server = 2,
Client = 3, Client = 3,
ClientProxy = 4, ClientProxy = 4,
ClientMainThread = 5,
}; };
enum CallAccept { enum CallAccept {
@ -849,11 +853,12 @@ public:
* @param argv Argument array * @param argv Argument array
* @param env Environment variables * @param env Environment variables
* @param mode Mode the engine must run as - Console, Client or Server * @param mode Mode the engine must run as - Console, Client or Server
* @param loop Callback function to the main thread's loop
* @param fail Fail and return after parsing command line arguments * @param fail Fail and return after parsing command line arguments
* @return Program exit code * @return Program exit code
*/ */
static int main(int argc, const char** argv, const char** env, static int main(int argc, const char** argv, const char** env,
RunMode mode = Console, bool fail = false); RunMode mode = Console, EngineLoop loop = 0, bool fail = false);
/** /**
* Display the help information on console * Display the help information on console
@ -862,6 +867,18 @@ public:
*/ */
static void help(bool client, bool errout = false); static void help(bool client, bool errout = false);
/**
* Initialize the engine
* @return Error code, 0 for success
*/
int engineInit();
/**
* Do engine cleanup
* @return Error code, 0 for success
*/
int engineCleanup();
/** /**
* Run the engine. * Run the engine.
* @return Error code, 0 for success * @return Error code, 0 for success
@ -1153,12 +1170,6 @@ public:
*/ */
static void clearEvents(const String& type); static void clearEvents(const String& type);
/**
* Start running the engine
* @return The code with which the engine has stopped
*/
static int engineRun();
protected: protected:
/** /**
* Destroys the engine and everything. You must not call it directly, * Destroys the engine and everything. You must not call it directly,