[Devel] lv2_descriptor() considered harmful

David Robillard d at drobilla.net
Sun Oct 9 17:23:01 PDT 2011

Hi all,

The discovery mechanism we inherited from LADSPA has some problems, and
I think it should be replaced in the next core release.

The main problems with the lv2_descriptor() approach are:

 * Dependence on non-portable magic library constructor/destructor

 * Missing bundle_path parameter, making more "dynamic" plugin bundles
effectively impossible (e.g. any bundle that needs to run some code at
init time to see what plugins it can make available, such as plugins
defined in some data file.  Think plugins in Faust or Ingen patches)

The former is annoying and in practise has resulted in the overwhelming
majority of plugin libraries just leaking memory rather than bother to
clean up.

The latter is a roadblock for some cool things people want to do.
Including me. :)

I propose we replace the hidden magic library state with explicit state
so all the details of library discovery, initialisation, and cleanup,
are explicitly defined in a straightforward portable C API, like
everything else in LV2.  Something like this:

typedef void* LV2_Lib_Data;

   Descriptor for a plugin library.

   Each plugin shared library has exactly one of these objects,
   accessed via the lv2_lib_descriptor() function in that library.
typedef struct {
	   Opaque library data which must be passed as the first
	   parameter to all the methods of this struct.
	LV2_Lib_Data lib_data;

	   Destroy this library descriptor.
	void (*cleanup)(LV2_Lib_Data lib_data);

	   Plugin accessor.

	   Plugins are accessed by index using values from 0 upwards.
	   Out of range indices MUST result in this function returning
	   NULL, so the host can enumerate plugins by increasing @a
	   index until NULL is returned.
	LV2_Descriptor const* (*descriptor)(LV2_Lib_Data lib_data,
	                                    uint32_t     index);
} LV2_Lib_Descriptor;

   Prototype for library accessor function.

   This is the entry point for a plugin library.  Hosts load this
   symbol from the library and call this function to obtain a
   library descriptor which can be used to access all the UIs
   contained in this library.  The returned object must not be
   destroyed (using LV2_Lib_Descriptor::cleanup()) until all
   plugins loaded from that library have been destroyed.
LV2_Lib_Descriptor const*
lv2_lib_descriptor(const char*                bundle_path,
                   const LV2_Feature *const * features);

   Type of the lv2_lib_descriptor() function in an LV2 library.
typedef LV2_Lib_Descriptor const*
(*LV2_Lib_Descriptor_Func)(const char*                bundle_path,
                           const LV2_Feature *const * features);

The main thing being achieved here is that the library can read files in
the bundle to determine which plugins are available in the bundle.  The
host can also pass any other data which might be needed by fancier
dynamic libraries in the future, via the features array.


(Naturally, if this goes in, the old lv2_descriptor will stick around
for quite some times)


More information about the Devel mailing list