[REP Index] [REP Source]

REP:116
Title:Extend pluginlib
Author:Dirk Thomas
Status:Final
Type:Standards Track
Content-Type:text/x-rst
Created:7-Oct-2011
ROS-Version:Fuerte
Post-History:7-Oct-2011

Abstract

This REP extends pluginlib with additional features. It proposes to enable unloading of libraries, checking if the library binary actually exists, refreshing the list of available plugins during runtime and to provide the necessary information to access the plugin manifest.

Motivation

The pluginlib is used to find plugins in the ROS package system.

When plugins are used (especially in long running applications) it is useful to unload plugins if they are no longer used. But currently unloading functionality is not exposed to the developer but only performed on destruction of the ClassLoader instance. Unloading plugins does not only reduce the memory footprint but also enables a use case like: load -> unload -> recompile plugin -> reload updated plugin.

For a long running application it would also be useful to be able to refresh the list of discovered plugins. But currently when a new plugin is made available (either by creating it or adding another location to the package path) it is not available instantly. The ClassLoader discovers plugins only once at construction time.

The discovery of plugins is performed based on the manifest files of the package system. Currently it is not possible (without trying to load the plugin) to decide if the plugin's binary does really exist.

The manifest for a plugin usually contains only the information necessary to instantiate the plugin. But the XML file could be used to store additional meta data for a plugin which should be available without loading the plugin (e.g. to provide a label, description, icon). But currently this information can not be accessed since neither the location of the XML file nor the section in it relevant for the specific plugin are exposed.

Use Cases

Manually trigger unloading of a plugin when it is no longer used.

Refresh the list of plugins if new plugins have been provided.

Determine if a plugin binary actually exists.

Access the plugin's manifest to retrieve additional information from the XML.

All use cases apply to the current development of ROS GUI [1].

Implementation

A patch implementing the aforementioned features is attached to the ticket #4887 [2]. The patch includes the following changes:

Added public API:

  • pluginlib::LibraryUnloadException : public PluginlibException Symmetric to pluginlib::LibraryLoadException. Returns the number of pending unloads until the library is removed from memory.
  • int ClassLoader::unloadLibraryForClass(const std::string&) Symmetric to ClassLoader::loadLibraryForClass(..)
  • void ClassLoader::refreshDeclaredClasses() Enables to update the list of available classes.
  • std::string ClassLoader::getPluginManifestPath(const std::string&) Returns the path to the plugin manifest.

Changed visibility from private to pulic:

  • std::string getClassLibraryPath(const std::string&) Enables checking if the library exists.

Further notes about non-public changes:

  • The implementation of the constructor is moved to the new method std::map<std::string, ClassDesc> ClassLoader::determineAvailableClasses()
  • The generation of the error string is moved to the new method std::string ClassLoader::getErrorStringForUnknownClass(const std::string&)
  • ClassDesc is extended with a member containing the path to the plugin mainfest.
  • Added method int ClassLoader::unloadClassLibraryInternal(const std::string&) Symmetric to ClassLoader::loadClassLibraryInternal(..)
  • Added missing pluginlib::LibraryLoadException to the documentation of the ClassLoader constructor.

Backwards Compatibility

The currently available functionality will stay untouched. The proposed additional features require to add several public functions to pluginlib::ClassLoader. Implementing them might break ABI.

References

[1]SIG: ROS GUI (http://www.ros.org/wiki/fuerte/Planning/ROS%20GUI)
[2]Ticket #4887: Extend pluginlib with more info and explicit unloading (https://code.ros.org/trac/ros-pkg/ticket/4887)