/* Copyright 2008,2009,2010 Edwin Eefting (edwin@datux.nl)
This file is part of Synapse.
Synapse is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Synapse is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Synapse. If not, see . */
#include "cmodule.h"
#include "clog.h"
#include
#include
#include
namespace synapse
{
Cmodule::Cmodule()
{
maxThreads=1;
currentThreads=0;
broadcastMulti=false;
broadcastCookie=false;
soHandle=NULL;
defaultSessionId=SESSION_DISABLED;
soDefaultHandler=NULL;
readySession=SESSION_DISABLED;
}
Cmodule::~Cmodule()
{
//unload the module on destruction.
//Destruction only happens when nobody is using the Cmodule object anymore, since we only
//use shared_ptrs.
if (soHandle)
{
DEB(name << " is unused - auto unloading");
unload();
}
}
/*!
\fn Cmodule::startThread()
*/
bool Cmodule::startThread()
{
if (currentThreads=0);
}
/*!
\fn Cmodule::load(string name)
*/
bool Cmodule::load(string path)
{
this->name=getName(path);
this->path=path;
INFO("Loading module " << name << " from: " << path );
soHandle=dlopen(path.c_str(),RTLD_NOW);
if (soHandle==NULL)
{
ERROR("Error loading module " << name << ": " << dlerror());
}
else
{
//check api version of the module
FsoVersion version;
version=(FsoVersion)resolve("synapseVersion");
if (version!=NULL)
{
if (version()!=SYNAPSE_API_VERSION)
{
ERROR("Module " << name << " has API version " << version() << " instead of : " << SYNAPSE_API_VERSION);
}
else
{
//init function is MANDATORY
soInit=(FsoInit)resolve("synapseInit");
if (soInit!=NULL)
{
INFO("Module loading of " << name << " complete.");
return true;
}
}
}
DEB("Unloading because of previous error");
dlclose(soHandle);
soHandle=NULL;
}
return false;
}
/*!
\fn Cmodule::unload()
*/
bool Cmodule::unload()
{
if (soHandle!=NULL)
{
INFO("Unloading module " << name);
FsoCleanup soCleanup;
soCleanup=(FsoCleanup)resolve("synapseCleanup");
if (soCleanup!=NULL)
{
DEB("Calling cleanup");
soCleanup();
}
DEB("Calling dlclose on " << soHandle);
if (dlclose(soHandle))
{
ERROR("Error unloading module " << name << ": " << dlerror());
}
DEB("Unload success");
}
return true;
}
/*!
\fn Cmodule::getHandler(string name)
*/
FsoHandler Cmodule::getHandler(string eventName)
{
ChandlerHashMap::iterator handlerI;
handlerI=handlers.find(eventName);
//not found?
if (handlerI==handlers.end())
{
//return default handler
return(soDefaultHandler);
}
else
{
return (handlerI->second);
}
}
bool Cmodule::setHandler(const string & eventName, const string & functionName)
{
FsoHandler soHandler;
soHandler=(FsoHandler)resolve("synapse_"+functionName);
if (soHandler!=NULL)
{
DEB(eventName << " -> " << functionName << "@" << name );
handlers[eventName]=soHandler;
return true;
}
return false;
}
bool Cmodule::setDefaultHandler(const string & functionName)
{
FsoHandler soHandler;
soHandler=(FsoHandler)resolve("synapse_"+functionName);
if (soHandler!=NULL)
{
DEB("(default handler) -> " << functionName << "@" << name );
soDefaultHandler=soHandler;
return true;
}
return false;
}
/*!
\fn Cmodule::resolve(const string * functionName)
*/
void * Cmodule::resolve(const string & functionName)
{
if (soHandle==NULL)
{
ERROR("Cannot resolve function " << functionName << ". There is no module loaded! (yet?)");
return NULL;
}
void * function;
function=dlsym(soHandle, functionName.c_str());
if (function==NULL)
{
ERROR("Could not find function " << functionName << " in module " << name << ": " << dlerror());
}
return (function);
}
/*!
\fn Cmodule::isLoaded(string path)
*/
bool Cmodule::isLoaded(string path)
{
return (dlopen(path.c_str(),RTLD_NOW|RTLD_NOLOAD)!=NULL);
}
/*!
\fn Cmodule::getName(string path)
*/
string Cmodule::getName(string path)
{
//calculate the name from a module path
regex expression(".*/lib(.*).so$");
cmatch what;
if(!regex_match(path.c_str(), what, expression))
{
ERROR("Cannot determine module name of path " << path);
return (path);
}
else
{
return (what[1]);
}
}
void Cmodule::getEvents(Cvar & var)
{
//traverse the events that have been created by calls to sendMessage
BOOST_FOREACH( ChandlerHashMap::value_type handler, handlers)
{
var[handler.first]=1;
}
}
}