MT#7347 added reference counting to plug-in interfaces.

Fixes crash on restart. Included upstream commits:

commit b9cda79c435fc002c259b5430e61c45d8e94aa2c
Author: Raphael Coeffic <rco@iptel.org>
Date:   Sun Apr 28 14:27:27 2013 +0200

    sip: add reference counting to transport sockets

    allows for dynamic socket creation/deletion.

commit 73490566761bb0fb09a6ebd74566d7f2b789c62f
Author: Raphael Coeffic <rco@iptel.org>
Date:   Tue Nov 20 15:33:35 2012 +0100

    c/f: correcting some strange scope issues encountered with GCC & clang on osx.

commit 0b2c8068a980058ff34655bc4928aeaedbe527d7
Author: Stefan Sayer <stefan.sayer@googlemail.com>
Date:   Thu Jan 5 22:10:52 2012 +0100

    b/f: don't delete registered app objects, e.g. DSM apps

    fixes bug #68
    https://bugtracker.iptel.org/view.php?id=68
1.4.3+spce2.8
Andrew Pogrebennyk 12 years ago
parent a7164113fb
commit 9f66f9def9

@ -157,6 +157,11 @@ class DBRegAgent
int onLoad();
// atomic_ref_cnt interface
void on_destroy() {
onUnload();
}
void onUnload();
RegistrationTimer registration_scheduler;

@ -41,7 +41,9 @@
#include <dirent.h>
#include <set>
#include <string>
using std::set;
using std::string;
#define PYFILE_REGEX "(.+)\\.(py|pyc|pyo)$"
@ -461,7 +463,7 @@ int IvrFactory::onLoad()
DBG("directory '%s' opened\n",script_path.c_str());
set<string> unique_entries;
std::set<string> unique_entries;
regmatch_t pmatch[2];
struct dirent* entry=0;
@ -479,7 +481,7 @@ int IvrFactory::onLoad()
regfree(&reg);
AmPlugIn* plugin = AmPlugIn::instance();
for(set<string>::iterator it = unique_entries.begin();
for(std::set<string>::iterator it = unique_entries.begin();
it != unique_entries.end(); it++) {
if(loadScript(*it)){

@ -35,6 +35,7 @@
#include "AmConfigReader.h"
#include "AmArg.h"
#include "AmEventQueue.h"
#include "atomic_types.h"
#include <stdarg.h>
@ -63,6 +64,7 @@ class AmDynInvoke
* \brief Base interface for plugin factories
*/
class AmPluginFactory
: public virtual atomic_ref_cnt
{
string plugin_name;
@ -81,12 +83,6 @@ class AmPluginFactory
* @return 1 on error.
*/
virtual int onLoad()=0;
/**
* Enables the plug-in to deinitialize once the server is stopped.
*/
virtual void onUnload() { };
};
/**

@ -108,26 +108,17 @@ AmPlugIn::AmPlugIn()
{
}
static std::set<AmPluginFactory*> deleted_factories;
static std::set<string> deleted_factories_names;
static void delete_plugin_factory(std::pair<string, AmPluginFactory*> pf)
{
if ((deleted_factories.find(pf.second) == deleted_factories.end()) &&
(deleted_factories_names.find(pf.first) == deleted_factories_names.end())) {
DBG("onUnload of plugin '%s'\n", pf.first.c_str());
pf.second->onUnload();
DBG("decreasing reference to plug-in factory: %s\n", pf.first.c_str());
dec_ref(pf.second);
DBG("deleting plug-in factory: %s\n", pf.first.c_str());
deleted_factories.insert(pf.second);
deleted_factories_names.insert(pf.first);
delete pf.second;
}
}
AmPlugIn::~AmPlugIn()
{
std::for_each(name2app.begin(), name2app.end(), delete_plugin_factory);
std::for_each(module_objects.begin(), module_objects.end(), delete_plugin_factory);
std::for_each(name2seh.begin(), name2seh.end(), delete_plugin_factory);
std::for_each(name2base.begin(), name2base.end(), delete_plugin_factory);
std::for_each(name2di.begin(), name2di.end(), delete_plugin_factory);
@ -566,6 +557,11 @@ int AmPlugIn::loadAppPlugIn(AmPluginFactory* f)
name2app.insert(std::make_pair(sf->getName(),sf));
DBG("application '%s' loaded.\n",sf->getName().c_str());
inc_ref(sf);
if(!module_objects.insert(std::make_pair(sf->getName(),sf)).second){
// insertion failed
dec_ref(sf);
}
name2app_mut.unlock();
return 0;
@ -584,7 +580,8 @@ int AmPlugIn::loadSehPlugIn(AmPluginFactory* f)
ERROR("session component '%s' already loaded !\n",sf->getName().c_str());
goto error;
}
inc_ref(sf);
name2seh.insert(std::make_pair(sf->getName(),sf));
DBG("session component '%s' loaded.\n",sf->getName().c_str());
@ -596,7 +593,11 @@ int AmPlugIn::loadSehPlugIn(AmPluginFactory* f)
int AmPlugIn::loadBasePlugIn(AmPluginFactory* f)
{
name2base.insert(std::make_pair(f->getName(),f));
inc_ref(f);
if(!name2base.insert(std::make_pair(f->getName(),f)).second){
// insertion failed
dec_ref(f);
}
return 0;
}
@ -812,7 +813,7 @@ AmSessionFactory* AmPlugIn::findSessionFactory(AmSipRequest& req)
ERROR(comp_name "'%s' already registered !\n", param_name.c_str()); \
return false; \
} \
\
inc_ref(f); \
instance()->map_name.insert(std::make_pair(param_name,f)); \
DBG(comp_name " '%s' registered.\n",param_name.c_str()); \
return true;

@ -101,6 +101,8 @@ class AmPlugIn : public AmPayloadProviderInterface
std::map<string,AmDynInvokeFactory*> name2di;
std::map<string,AmLoggingFacility*> name2logfac;
std::map<string,AmPluginFactory*> module_objects;
//AmCtrlInterfaceFactory *ctrlIface;
int dynamic_pl; // range: 96->127, see RFC 1890

@ -198,6 +198,7 @@ protected:
: atomic_int() {}
virtual ~atomic_ref_cnt() {}
virtual void on_destroy() {}
friend void inc_ref(atomic_ref_cnt* rc);
friend void dec_ref(atomic_ref_cnt* rc);
@ -212,8 +213,10 @@ inline void inc_ref(atomic_ref_cnt* rc)
inline void dec_ref(atomic_ref_cnt* rc)
{
assert(rc);
if(rc->dec_and_test())
if(rc->dec_and_test()){
rc->on_destroy();
delete rc;
}
}

Loading…
Cancel
Save