Commit b7740bd1 authored by Guillaume Roguez's avatar Guillaume Roguez Committed by Anthony Léonard

remove some deprecated files

These files comes from sflphone ages, are not relevant, not working and
may confuse people who read them.

Change-Id: I8186c35a36665ef077df38d508e6977e1f833bc9
Reviewed-by: default avatarAnthony Léonard <anthony.leonard@savoirfairelinux.com>
parent f1f0608f
......@@ -111,11 +111,6 @@ libring_la_SOURCES = \
utf8_utils.cpp \
ice_transport.cpp \
ice_transport.h \
plugin_manager.cpp \
plugin_loader_dl.cpp \
ring_plugin.h \
plugin_loader.h \
plugin_manager.h \
threadloop.h \
thread_pool.h \
conference.h \
......
......@@ -34,7 +34,6 @@
#include "logger.h"
#include "account_schema.h"
#include "plugin_manager.h"
#include "thread_pool.h"
#include "fileutils.h"
......@@ -349,8 +348,6 @@ struct Manager::ManagerPimpl
*/
std::unique_ptr<RingBufferPool> ringbufferpool_;
std::unique_ptr<PluginManager> pluginManager_;
std::map<uintptr_t, Manager::EventHandler> eventHandlerMap_;
decltype(eventHandlerMap_)::iterator nextEventHandler_;
......@@ -388,7 +385,6 @@ Manager::ManagerPimpl::ManagerPimpl(Manager& base)
, waitingCallsMutex_()
, path_()
, ringbufferpool_(new RingBufferPool)
, pluginManager_(new PluginManager)
, conferenceMap_()
, ice_tf_()
#ifdef RING_VIDEO
......
/*
* Copyright (C) 2004-2018 Savoir-faire Linux Inc.
*
* Author: Guillaume Roguez <guillaume.roguez@savoirfairelinux.com>
*
* This program 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.
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef PLUGIN_LOADER_H
#define PLUGIN_LOADER_H
#include "ring_plugin.h"
#include <string>
namespace ring {
class Plugin
{
public:
virtual ~Plugin() = default;
static Plugin* load(const std::string& path, std::string& error);
virtual void* getSymbol(const char* name) const = 0;
virtual RING_PluginInitFunc getInitFunction() const {
return reinterpret_cast<RING_PluginInitFunc>(getSymbol(RING_DYN_INIT_FUNC_NAME));
};
protected:
Plugin() = default;
};
} // namespace ring
#endif /* PLUGIN_LOADER_H */
/*
* Copyright (C) 2004-2018 Savoir-faire Linux Inc.
*
* Author: Guillaume Roguez <guillaume.roguez@savoirfairelinux.com>
*
* This program 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.
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "plugin_loader.h"
#include <dlfcn.h>
#include <memory>
namespace ring {
class DLPlugin : public Plugin
{
public:
DLPlugin(void* handle) : handle_(handle, ::dlclose) {};
void* getSymbol(const char* name) const;
private:
std::unique_ptr<void, int(*)(void*)> handle_;
};
void*
DLPlugin::getSymbol(const char* name) const
{
if (!handle_)
return nullptr;
return ::dlsym(handle_.get(), name);
}
Plugin*
Plugin::load(const std::string& path, std::string& error)
{
if (path.empty()) {
error = "Empty path";
return nullptr;
}
// Clear any existing error
::dlerror();
void* handle = ::dlopen(path.c_str(), RTLD_NOW);
if (!handle) {
error += "Failed to load \"" + path + '"';
std::string dlError = ::dlerror();
if(dlError.size())
error += " (" + dlError + ")";
return nullptr;
}
return new DLPlugin(handle);
}
} // namespace ring
/*
* Copyright (C) 2004-2018 Savoir-faire Linux Inc.
*
* Author: Guillaume Roguez <guillaume.roguez@savoirfairelinux.com>
*
* This program 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.
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "plugin_manager.h"
#include "plugin_loader.h"
#include "logger.h"
#include <utility>
namespace ring {
PluginManager::PluginManager()
{
pluginApi_.context = reinterpret_cast<void*>(this);
}
PluginManager::~PluginManager()
{
for (auto func : exitFuncVec_) {
try {
(*func)();
} catch (...) {
RING_WARN("Exception caught during plugin exit");
}
}
dynPluginMap_.clear();
exactMatchMap_.clear();
wildCardVec_.clear();
exitFuncVec_.clear();
}
bool
PluginManager::load(const std::string& path)
{
// TODO: Resolve symbolic links and make path absolute
// Don't load the same dynamic library twice
if (dynPluginMap_.find(path) != dynPluginMap_.end()) {
RING_WARN("plugin: already loaded");
return true;
}
std::string error;
std::unique_ptr<Plugin> plugin(Plugin::load(path, error));
if (!plugin) {
RING_ERR("plugin: %s", error.c_str());
return false;
}
const auto& init_func = plugin->getInitFunction();
if (!init_func) {
RING_ERR("plugin: no init symbol");
return false;
}
if (!registerPlugin(init_func))
return false;
dynPluginMap_[path] = std::move(plugin);
return true;
}
bool
PluginManager::registerPlugin(RING_PluginInitFunc initFunc)
{
RING_PluginExitFunc exitFunc = nullptr;
try {
exitFunc = initFunc(&pluginApi_);
} catch (const std::runtime_error& e) {
RING_ERR("%s", e.what());
}
if (!exitFunc) {
tempExactMatchMap_.clear();
tempWildCardVec_.clear();
RING_ERR("plugin: init failed");
return false;
}
exitFuncVec_.push_back(exitFunc);
exactMatchMap_.insert(tempExactMatchMap_.begin(),
tempExactMatchMap_.end());
wildCardVec_.insert(wildCardVec_.end(),
tempWildCardVec_.begin(),
tempWildCardVec_.end());
return true;
}
bool
PluginManager::registerService(const std::string& name,
ServiceFunction&& func)
{
services_[name] = std::forward<ServiceFunction>(func);
return true;
}
void
PluginManager::unRegisterService(const std::string& name)
{
services_.erase(name);
}
int32_t
PluginManager::invokeService(const std::string& name, void* data)
{
const auto& iterFunc = services_.find(name);
if (iterFunc == services_.cend()) {
RING_ERR("Services not found: %s", name.c_str());
return -1;
}
const auto& func = iterFunc->second;
try {
return func(data);
} catch (const std::runtime_error &e) {
RING_ERR("%s", e.what());
return -1;
}
}
/* WARNING: exposed to plugins through RING_PluginAPI */
bool
PluginManager::registerObjectFactory(const char* type,
const RING_PluginObjectFactory& factoryData)
{
if (!type)
return false;
if (!factoryData.create || !factoryData.destroy)
return false;
// Strict compatibility on ABI
if (factoryData.version.abi != pluginApi_.version.abi)
return false;
// Backward compatibility on API
if (factoryData.version.api < pluginApi_.version.api)
return false;
const std::string key(type);
auto deleter = [factoryData](void* o) {
factoryData.destroy(o, factoryData.closure);
};
ObjectFactory factory = {factoryData, deleter};
// wildcard registration?
if (key == "*") {
wildCardVec_.push_back(factory);
return true;
}
// fails on duplicate for exactMatch map
if (exactMatchMap_.find(key) != exactMatchMap_.end())
return false;
exactMatchMap_[key] = factory;
return true;
}
std::unique_ptr<void, PluginManager::ObjectDeleter>
PluginManager::createObject(const std::string& type)
{
if (type == "*")
return {nullptr, nullptr};
RING_PluginObjectParams op = {
/*.pluginApi = */&pluginApi_,
/*.type = */type.c_str(),
};
// Try to find an exact match
const auto& factoryIter = exactMatchMap_.find(type);
if (factoryIter != exactMatchMap_.end()) {
const auto& factory = factoryIter->second;
auto object = factory.data.create(&op, factory.data.closure);
if (object)
return {object, factory.deleter};
}
// Try to find a wildcard match
for (const auto& factory : wildCardVec_)
{
auto object = factory.data.create(&op, factory.data.closure);
if (object) {
// promote registration to exactMatch_
// (but keep also wildcard registration for other object types)
int32_t res = registerObjectFactory(op.type, factory.data);
if (res < 0) {
RING_ERR("failed to register object %s", op.type);
return {nullptr, nullptr};
}
return {object, factory.deleter};
}
}
return {nullptr, nullptr};
}
/* WARNING: exposed to plugins through RING_PluginAPI */
int32_t
PluginManager::registerObjectFactory_(const RING_PluginAPI* api,
const char* type, void* data)
{
auto manager = reinterpret_cast<PluginManager*>(api->context);
if (!manager) {
RING_ERR("registerObjectFactory called with null plugin API");
return -1;
}
if (!data) {
RING_ERR("registerObjectFactory called with null factory data");
return -1;
}
const auto factory = reinterpret_cast<RING_PluginObjectFactory*>(data);
return manager->registerObjectFactory(type, *factory) ? 0 : -1;
}
/* WARNING: exposed to plugins through RING_PluginAPI */
int32_t
PluginManager::invokeService_(const RING_PluginAPI* api, const char* name,
void* data)
{
auto manager = reinterpret_cast<PluginManager*>(api->context);
if (!manager) {
RING_ERR("invokeService called with null plugin API");
return -1;
}
return manager->invokeService(name, data);
}
} // namespace ring
/*
* Copyright (C) 2004-2018 Savoir-faire Linux Inc.
*
* Author: Guillaume Roguez <guillaume.roguez@savoirfairelinux.com>
*
* This program 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.
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef PLUGIN_MANAGER_H
#define PLUGIN_MANAGER_H
#include "ring_plugin.h"
#include "noncopyable.h"
#include <map>
#include <vector>
#include <memory>
#include <mutex>
#include <functional>
#include <string>
#include <inttypes.h>
namespace ring {
class Plugin;
class PluginManager
{
public:
using ObjectDeleter = std::function<void(void*)>;
using ServiceFunction = std::function<int32_t(void*)>;
private:
struct ObjectFactory {
RING_PluginObjectFactory data;
ObjectDeleter deleter;
};
using PluginMap = std::map<std::string, std::shared_ptr<Plugin>>;
using ExitFuncVec = std::vector<RING_PluginExitFunc>;
using ObjectFactoryVec = std::vector<ObjectFactory>;
using ObjectFactoryMap = std::map<std::string, ObjectFactory>;
public:
PluginManager();
~PluginManager();
/**
* Load a dynamic plugin by filename.
*
* @param path fully qualified pathname on a loadable plugin binary
* @return true if success
*/
bool load(const std::string& path);
/**
* Register a plugin.
*
* @param initFunc plugin init function
* @return true if success
*/
bool registerPlugin(RING_PluginInitFunc initFunc);
/**
* Register a new service for plugin.
*
* @param name The service name
* @param func The function called by Ring_PluginAPI.invokeService
* @return true if success
*/
bool registerService(const std::string& name, ServiceFunction&& func);
void unRegisterService(const std::string& name);
/**
* Register a new public objects factory.
*
* @param type unique identifier of the object
* @param params object factory details
* @return true if success
*
* Note: type can be the string "*" meaning that the factory
* will be called if no exact match factories are found for a given type.
*/
bool registerObjectFactory(const char* type,
const RING_PluginObjectFactory& factory);
/**
* Create a new plugin's exported object.
*
* @param type unique identifier of the object to create.
* @return unique pointer on created object.
*/
std::unique_ptr<void, ObjectDeleter> createObject(const std::string& type);
const RING_PluginAPI& getPluginAPI() const {
return pluginApi_;
}
private:
NON_COPYABLE(PluginManager);
/**
* Implements RING_PluginAPI.registerObjectFactory().
* Must be C accessible.
*/
static int32_t registerObjectFactory_(const RING_PluginAPI* api,
const char* type,
void* data);
/**
* Implements RING_PluginAPI.invokeService().
* Must be C accessible.
*/
static int32_t invokeService_(const RING_PluginAPI* api,
const char* name,
void* data);
int32_t invokeService(const std::string& name, void* data);
std::mutex mutex_ {};
RING_PluginAPI pluginApi_ = {
{ RING_PLUGIN_ABI_VERSION, RING_PLUGIN_API_VERSION },
nullptr, // set by PluginManager constructor
registerObjectFactory_, invokeService_,
};
PluginMap dynPluginMap_ {}; // Only dynamic loaded plugins
ExitFuncVec exitFuncVec_ {};
ObjectFactoryMap exactMatchMap_ {};
ObjectFactoryVec wildCardVec_ {};
// Storage used during plugin initialisation.
// Will be copied into previous ones only if the initialisation success.
ObjectFactoryMap tempExactMatchMap_ {};
ObjectFactoryVec tempWildCardVec_ {};
// registered services
std::map<std::string, ServiceFunction> services_ {};
};
} // namespace ring
#endif /* PLUGIN_MANAGER_H */
/*
* Copyright (C) 2004-2018 Savoir-faire Linux Inc.
*
* Author: Guillaume Roguez <guillaume.roguez@savoirfairelinux.com>
*
* This program 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.
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef RING_PLUGIN_H
#define RING_PLUGIN_H
#include <inttypes.h>
#ifdef __cplusplus
# define EXTERNAL_C_LINKAGE extern "C"
# define C_INTERFACE_START EXTERNAL_C_LINKAGE {
# define C_INTERFACE_END }
#else
# define C_LINKAGE
# define C_INTERFACE_START
# define C_INTERFACE_END
#endif
#define RING_PLUGIN_ABI_VERSION 1 /* 0 doesn't exist, considered as error */
#define RING_PLUGIN_API_VERSION 1 /* 0 doesn't exist, considered as error */
C_INTERFACE_START;
typedef struct RING_PluginVersion {
/* plugin is not loadable if this number differs from one
* stored in the plugin loader */
uint32_t abi;
/* a difference on api number may be acceptable, see the loader code */
uint32_t api;
} RING_PluginVersion;
struct RING_PluginAPI;
/* RING_PluginCreateFunc parameters */
typedef struct RING_PluginObjectParams {
const RING_PluginAPI* pluginApi; /* this API */
const char* type;
} RING_PluginObjectParams;
typedef void* (*RING_PluginCreateFunc)(RING_PluginObjectParams* params, void* closure);
typedef void (*RING_PluginDestroyFunc)(void *object, void* closure);
/* RING_PluginAPI.registerObjectFactory data */
typedef struct RING_PluginObjectFactory {
RING_PluginVersion version;
void* closure; /* closure for create */
RING_PluginCreateFunc create;
RING_PluginDestroyFunc destroy;
} RING_PluginObjectFactory;
/* Plugins exposed API prototype */
typedef int32_t (*RING_PluginFunc)(const RING_PluginAPI* api,
const char* name,
void* data);
/* RING_PluginInitFunc parameters.
* This structure is filled by the Plugin manager.
* For backware compatibility, never c
*/
typedef struct RING_PluginAPI {
RING_PluginVersion version; /* structure version, always the first data */
void* context; /* opaque structure used by next functions */
/* API usable by plugin implementors */
RING_PluginFunc registerObjectFactory;
RING_PluginFunc invokeService;
} RING_PluginAPI;
typedef void (*RING_PluginExitFunc)(void);
typedef RING_PluginExitFunc (*RING_PluginInitFunc)(const RING_PluginAPI *api);
C_INTERFACE_END;
#define RING_DYN_INIT_FUNC_NAME "RING_dynPluginInit"
#define RING_PLUGIN_INIT_STATIC(fname, pname) RING_PLUGIN_INIT(fname, pname)
#define RING_PLUGIN_INIT_DYNAMIC(pname) RING_PLUGIN_INIT(RING_dynPluginInit, pname)
/* Define here platform dependent way to export a declaration x to the dynamic
* loading system.
*/
/* Default case (like POSIX/.so) */
#define RING_PLUGIN_INIT(fname, pname) \
EXTERNAL_C_LINKAGE RING_PluginExitFunc fname(const RING_PluginAPI *pname)
#define RING_PLUGIN_EXIT(fname) \
EXTERNAL_C_LINKAGE void fname(void)
#endif /* RING_PLUGIN_H */
#!/bin/sh
#
# Copyright 2014 Savoir-faire Linux Inc.
# Author: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
# Licensed under the terms of the GNU GPL v3, or at your option, any later version.
#
# You can install this script as a Git subcommand with one of the 2 methods below:
#
# 1) git config alias.gerrit '!tools/git-gerrit'
# 2) or put this script in your $PATH
usage () {
echo "Usage:"
echo " $0 <url|open|fetch> [<git-rev>]"
echo " $0 help"
echo
echo "Examples:"
echo " git gerrit open"
echo " git gerrit url HEAD~2"
echo " git gerrit fetch ; git diff FETCH_HEAD"
}
test $# -ge 1 -a $# -le 2 || {
echo "Invalid syntax."
usage
exit 1
}
test "$1" = "help" && {
usage
exit
}
GERRIT_USER=`git config gerrit.user`
GERRIT_HOST=`git config gerrit.host`
GERRIT_PORT=`git config gerrit.port`
test -n "$GERRIT_USER" -a -n "$GERRIT_HOST" -a -n "$GERRIT_PORT" || {
echo "You must configure your Gerrit host, e.g.:"
echo
echo " git config gerrit.user vivien"
echo " git config gerrit.host gerrit-ring.savoirfairelinux.com"
echo " git config gerrit.port 29420"
echo
exit 1
}
alias _gerrit="ssh -p $GERRIT_PORT $GERRIT_HOST gerrit query"
CHANGE_ID=`git show --summary --format=%b $2 | perl -n -e '/^Change-Id: (I[0-9a-f]+)$/ && print $1'`
test -n "$CHANGE_ID" || {
echo "no Change ID!"
exit 1
}
test "$1" = "fetch" && {
GERRIT_REMOTE=`git config gerrit.remote`
test -n "$GERRIT_REMOTE" || {
echo "You must specify the Git remote pointing to Gerrit, e.g.:"
echo
echo " git config gerrit.remote origin"
echo
exit 1
}
_gerrit --current-patch-set $CHANGE_ID | awk '/ref:/ { print $2 }' | while read ref ; do
git fetch $GERRIT_REMOTE $ref:$ref
done
exit
}
URL=`_gerrit $CHANGE_ID | awk '/url:/ { print $2 }'`