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()
{
Engine::engineRun();
Engine::self()->run();
Debug(DebugAll,"Engine stopped running");
}
void EngineThread::cleanup()
{
Debug(DebugAll,"EngineThread::cleanup() [%p]",this);
if (QtClient::self())
QtClient::self()->quit();
s_engineThread = 0;
}
extern "C" int main(int argc, const char** argv, const char** envp)
static int mainLoop()
{
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
Engine::self();
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
if (!QtClient::self())
new QtClient();
QtClient::setSelf(new QtClient());
// run the client
QtClient::self()->run();
if (!Engine::exiting())
QtClient::self()->run();
// the client finished running, do cleanup
QtClient::self()->cleanup();
// wait for the engine to halt
Engine::halt(0);
unsigned long count = WAIT_ENGINE / Thread::idleMsec();
while (s_engineThread && count--)
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: */

View File

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

View File

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

View File

@ -755,14 +755,17 @@ static bool logFileOpen()
}
return false;
}
int Engine::engineRun()
static int engineRun(EngineLoop loop = 0)
{
time_t t = ::time(0);
s_startMsg << "Yate (" << ::getpid() << ") is starting " << ::ctime(&t);
s_startMsg.trimSpaces();
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);
Output("Yate (%u) is stopping %s",::getpid(),::ctime(&t));
return retcode;
@ -832,7 +835,7 @@ static void serviceMain(DWORD argc, LPTSTR* argv)
return;
}
setStatus(SERVICE_START_PENDING);
Engine::engineRun();
engineRun();
}
static SERVICE_TABLE_ENTRY dispatchTable[] =
@ -1164,7 +1167,7 @@ Engine::~Engine()
s_self = 0;
}
int Engine::run()
int Engine::engineInit()
{
#ifdef _WINDOWS
// 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");
dispatch("engine.start",true);
setStatus(SERVICE_RUNNING);
long corr = 0;
#ifndef _WINDOWS
::signal(SIGHUP,sighandler);
::signal(SIGQUIT,sighandler);
@ -1306,6 +1308,14 @@ int Engine::run()
}
Output("Yate%s engine is initialized and starting up%s%s",
clientMode() ? " client" : "",s_node.null() ? "" : " on " ,s_node.safe());
return 0;
}
int Engine::run()
{
// engine loop
long corr = 0;
int stops = MAX_STOP;
while (s_haltcode == -1 || ((--stops >= 0) && dispatch("engine.stop",true))) {
if (s_cmds) {
@ -1395,6 +1405,11 @@ int Engine::run()
Thread::yield();
}
s_haltcode &= 0xff;
return 0;
}
int Engine::engineCleanup()
{
Output("Yate engine is shutting down with code %d",s_haltcode);
CapturedEvent::capturing(false);
setStatus(SERVICE_STOP_PENDING);
@ -1850,7 +1865,7 @@ static void version()
::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
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 supervised = false;
#endif
bool noStart = (mode == ClientMainThread);
if (noStart)
mode = Client;
bool client = (mode == Client);
Debugger::Formatting tstamp = Debugger::None;
bool colorize = false;
@ -2311,7 +2323,7 @@ int Engine::main(int argc, const char** argv, const char** env, RunMode mode, bo
}
else
#endif
retcode = noStart ? 0 : engineRun();
retcode = engineRun(loop);
return retcode;
}

View File

@ -1276,6 +1276,8 @@ public:
{ return m_initialized; }
inline static Client* self()
{ 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

View File

@ -800,6 +800,11 @@ public:
static void setChecker(EngineCheck* ptr = 0);
};
/**
* Prototype for engine main loop callback
*/
typedef int (*EngineLoop)();
/**
* This class holds global information about the engine.
* Note: this is a singleton class.
@ -821,7 +826,6 @@ public:
Server = 2,
Client = 3,
ClientProxy = 4,
ClientMainThread = 5,
};
enum CallAccept {
@ -849,11 +853,12 @@ public:
* @param argv Argument array
* @param env Environment variables
* @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
* @return Program exit code
*/
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
@ -862,6 +867,18 @@ public:
*/
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.
* @return Error code, 0 for success
@ -1153,12 +1170,6 @@ public:
*/
static void clearEvents(const String& type);
/**
* Start running the engine
* @return The code with which the engine has stopped
*/
static int engineRun();
protected:
/**
* Destroys the engine and everything. You must not call it directly,