Example #1
0
boost::shared_ptr<ProtocolPluginInstance>
ProtocolPlugin::createInstance(int id, const Licq::UserId& ownerId,
                               void (*callback)(const PluginInstance&))
{
  PluginThread::Ptr thread;
  if (myMainThread)
    thread.swap(myMainThread);
  else
    thread = boost::make_shared<PluginThread>();

  ProtocolPluginInstance::Ptr instance =
      boost::make_shared<ProtocolPluginInstance>(
          id, ownerId,
          boost::dynamic_pointer_cast<ProtocolPlugin>(shared_from_this()),
          thread);

  if (instance->create(callback))
    registerInstance(instance);
  else
    instance.reset();

  return instance;
}
Example #2
0
GeneralPlugin::Ptr PluginManager::loadGeneralPlugin(
    const std::string& name, int argc, char** argv, bool keep)
{
  PluginThread::Ptr pluginThread;
  if (myGuiThread && name.find("-gui") != std::string::npos)
  {
    gLog.debug("Running %s in GUI thread", name.c_str());
    pluginThread.swap(myGuiThread);
  }
  else
    pluginThread.reset(new PluginThread);

  DynamicLibrary::Ptr lib = loadPlugin(pluginThread, name, "licq");
  if (!lib)
    return GeneralPlugin::Ptr();

  try
  {
    // Get plugin data from library
    struct Licq::GeneralPluginData* pluginData;
    lib->getSymbol("LicqGeneralPluginData", &pluginData);

    // Verify plugin data
    if (pluginData == NULL ||
        pluginData->licqMagic[0] != 'L' || pluginData->licqMagic[1] != 'i' ||
        pluginData->licqMagic[2] != 'c' || pluginData->licqMagic[3] != 'q')
    {
      gLog.error(tr("Library %s does not contain a Licq plugin"), name.c_str());
      return GeneralPlugin::Ptr();
    }

    // Make sure plugin version is supported
    // We expect plugin API to stay the same between releases of the same major/minor version
    if (pluginData->licqVersion / 10 != LICQ_VERSION / 10)
    {
      gLog.error(tr("Plugin in library %s was built for another Licq version (%i.%i.%i)"),
          name.c_str(), Licq::extractMajorVersion(pluginData->licqVersion),
          Licq::extractMinorVersion(pluginData->licqVersion),
          Licq::extractReleaseVersion(pluginData->licqVersion));
      return GeneralPlugin::Ptr();
    }

    // Generate an ID for the plugin
    int pluginId;
    {
      // Lock both plugin mutexes to avoid race for myNextPluginId
      MutexLocker generalLocker(myGeneralPluginsMutex);
      MutexLocker protocolLocker(myProtocolPluginsMutex);
      pluginId = myNextPluginId++;
    }

    // Create main plugin object
    GeneralPlugin::Params pluginParams(pluginId, lib, pluginThread);
    GeneralPlugin::Ptr plugin(pluginData->pluginFactory(pluginParams), deleteGeneralPlugin);

    // Let the plugin initialize itself
    if (!plugin->basePrivate()->callInit(argc, argv, &initPluginCallback))
    {
      gLog.error(tr("Failed to initialize plugin (%s)"),
          plugin->name().c_str());
      throw std::exception();
    }

    if (keep)
    {
      MutexLocker generalLocker(myGeneralPluginsMutex);
      myGeneralPlugins.push_back(plugin);
    }

    return plugin;
  }
  catch (const DynamicLibrary::Exception& ex)
  {
    std::string error = ex.getSystemError();
    gLog.error(tr("Failed to load plugin (%s): %s"),
        name.c_str(), error.c_str());
  }
  catch (const std::exception&)
  {
    // Empty
  }

  return GeneralPlugin::Ptr();
}
Example #3
0
 ~GeneralPluginFixture()
 {
   myThread->cancel();
 }