use new errorhandling scheme
This commit is contained in:
parent
d36a38a56e
commit
e07dc59e78
5 changed files with 34 additions and 82 deletions
|
|
@ -29,6 +29,8 @@ AC_COPYRIGHT([
|
|||
AC_PROG_CC
|
||||
AC_PROG_CPP
|
||||
AC_PROG_CXX
|
||||
|
||||
AC_LIBTOOL_DLOPEN
|
||||
AC_PROG_LIBTOOL
|
||||
|
||||
#
|
||||
|
|
|
|||
|
|
@ -28,26 +28,18 @@
|
|||
|
||||
#include "plugin.h"
|
||||
|
||||
/*
|
||||
TODO cinelerra_xmalloc which aborts on allocation error
|
||||
or cinelerra_die() function
|
||||
|
||||
TODO move CINELERRA_DIE elsewhere (cinlib.h?)
|
||||
*/
|
||||
#define CINELERRA_DIE do{NOBUG_LOG(NOBUG_ON, LOG_EMERG, "aborting due fatal error"); abort();}while(0)
|
||||
|
||||
/* TODO should be set by the build system to the actual plugin path */
|
||||
#define CINELERRA_PLUGIN_PATH "~/.cinelerra3/plugins:/usr/local/lib/cinelerra3/plugins"
|
||||
#define CINELERRA_PLUGIN_PREFIX "lib"
|
||||
|
||||
NOBUG_DEFINE_FLAG (cinelerra_plugin);
|
||||
|
||||
/* errors */
|
||||
const char* CINELERRA_PLUGIN_SUCCESS = NULL;
|
||||
const char* CINELERRA_PLUGIN_EDLOPEN = "Could not open plugin";
|
||||
const char* CINELERRA_PLUGIN_EHOOK = "Hook function failed";
|
||||
const char* CINELERRA_PLUGIN_ENFOUND = "No such plugin";
|
||||
const char* CINELERRA_PLUGIN_ENIFACE = "No such interface";
|
||||
const char* CINELERRA_PLUGIN_EREVISION = "Interface revision too old";
|
||||
CINELERRA_ERROR_DEFINE(PLUGIN_DLOPEN, "Could not open plugin");
|
||||
CINELERRA_ERROR_DEFINE(PLUGIN_HOOK, "Hook function failed");
|
||||
CINELERRA_ERROR_DEFINE(PLUGIN_NFILE, "No such plugin");
|
||||
CINELERRA_ERROR_DEFINE(PLUGIN_NIFACE, "No such interface");
|
||||
CINELERRA_ERROR_DEFINE(PLUGIN_REVISION, "Interface revision too old");
|
||||
|
||||
/*
|
||||
supported (planned) plugin types and their file extensions
|
||||
|
|
@ -68,6 +60,7 @@ static const struct
|
|||
{
|
||||
{"plugin", CINELERRA_PLUGIN_DYNLIB},
|
||||
{"so", CINELERRA_PLUGIN_DYNLIB},
|
||||
{"o", CINELERRA_PLUGIN_DYNLIB},
|
||||
{"tcc", CINELERRA_PLUGIN_CSOURCE},
|
||||
{"c", CINELERRA_PLUGIN_CSOURCE},
|
||||
/* extend here */
|
||||
|
|
@ -103,16 +96,6 @@ void* cinelerra_plugin_registry = NULL;
|
|||
/* plugin operations are protected by one big mutex */
|
||||
pthread_mutex_t cinelerra_plugin_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
/* Thread local storage, for now only the error state */
|
||||
static pthread_key_t cinelerra_plugin_tls_error;
|
||||
static pthread_once_t cinelerra_plugin_initialized = PTHREAD_ONCE_INIT;
|
||||
|
||||
void
|
||||
cinelerra_plugin_tls_init (void)
|
||||
{
|
||||
pthread_key_create (&cinelerra_plugin_tls_error, NULL);
|
||||
}
|
||||
|
||||
/* the compare function for the registry tree */
|
||||
static int
|
||||
cinelerra_plugin_name_cmp (const void* a, const void* b)
|
||||
|
|
@ -121,22 +104,6 @@ cinelerra_plugin_name_cmp (const void* a, const void* b)
|
|||
}
|
||||
|
||||
|
||||
const char*
|
||||
cinelerra_plugin_error ()
|
||||
{
|
||||
pthread_once (&cinelerra_plugin_initialized, cinelerra_plugin_tls_init);
|
||||
|
||||
const char* err = pthread_getspecific (cinelerra_plugin_tls_error);
|
||||
pthread_setspecific (cinelerra_plugin_tls_error, CINELERRA_PLUGIN_SUCCESS);
|
||||
return err;
|
||||
}
|
||||
|
||||
static void
|
||||
cinelerra_plugin_error_set (const char* err)
|
||||
{
|
||||
pthread_setspecific (cinelerra_plugin_tls_error, err);
|
||||
}
|
||||
|
||||
int
|
||||
cinelerra_plugin_lookup (struct cinelerra_plugin* self, const char* path)
|
||||
{
|
||||
|
|
@ -160,7 +127,7 @@ cinelerra_plugin_lookup (struct cinelerra_plugin* self, const char* path)
|
|||
for (int i = 0; cinelerra_plugin_extensions[i].ext; ++i)
|
||||
{
|
||||
/* path/name.extension */
|
||||
int r = snprintf(pathname, 1024, "%s/%s.%s", tok, self->name, cinelerra_plugin_extensions[i].ext);
|
||||
int r = snprintf(pathname, 1024, CINELERRA_PLUGIN_PREFIX "%s/%s.%s", tok, self->name, cinelerra_plugin_extensions[i].ext);
|
||||
if (r >= 1024)
|
||||
return -1; /*TODO error handling, name too long*/
|
||||
|
||||
|
|
@ -170,7 +137,7 @@ cinelerra_plugin_lookup (struct cinelerra_plugin* self, const char* path)
|
|||
{
|
||||
/* got it */
|
||||
self->pathname = strdup (pathname);
|
||||
if (!self->pathname) CINELERRA_DIE;
|
||||
if (!self->pathname) CINELERRA_DIE("out of memory");
|
||||
self->type = cinelerra_plugin_extensions[i].type;
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -185,8 +152,6 @@ cinelerra_interface_open (const char* name, const char* interface, size_t min_re
|
|||
//REQUIRE (min_revision > sizeof(struct cinelerra_interface), "try to use an empty interface eh?");
|
||||
REQUIRE (interface, "interface name must be given");
|
||||
|
||||
pthread_once (&cinelerra_plugin_initialized, cinelerra_plugin_tls_init);
|
||||
|
||||
pthread_mutex_lock (&cinelerra_plugin_mutex);
|
||||
|
||||
struct cinelerra_plugin plugin;
|
||||
|
|
@ -195,7 +160,7 @@ cinelerra_interface_open (const char* name, const char* interface, size_t min_re
|
|||
plugin.name = name; /* for searching */
|
||||
|
||||
found = tsearch (&plugin, &cinelerra_plugin_registry, cinelerra_plugin_name_cmp);
|
||||
if (!found) CINELERRA_DIE;
|
||||
if (!found) CINELERRA_DIE("out of memory");
|
||||
|
||||
if (*found == &plugin)
|
||||
{
|
||||
|
|
@ -203,13 +168,13 @@ cinelerra_interface_open (const char* name, const char* interface, size_t min_re
|
|||
|
||||
/* now really create new item */
|
||||
*found = malloc (sizeof (struct cinelerra_plugin));
|
||||
if (!*found) CINELERRA_DIE;
|
||||
if (!*found) CINELERRA_DIE("out of memory");
|
||||
|
||||
if (name) /* NULL is main app, no lookup needed */
|
||||
{
|
||||
/*lookup for $CINELERRA_PLUGIN_PATH*/
|
||||
(*found)->name = strdup (name);
|
||||
if (!(*found)->name) CINELERRA_DIE;
|
||||
if (!(*found)->name) CINELERRA_DIE("out of memory");
|
||||
|
||||
if (!cinelerra_plugin_lookup (*found, getenv("CINELERRA_PLUGIN_PATH"))
|
||||
#ifdef CINELERRA_PLUGIN_PATH
|
||||
|
|
@ -218,7 +183,7 @@ cinelerra_interface_open (const char* name, const char* interface, size_t min_re
|
|||
#endif
|
||||
)
|
||||
{
|
||||
cinelerra_plugin_error_set (CINELERRA_PLUGIN_ENFOUND);
|
||||
cinelerra_error_set (CINELERRA_ERROR_PLUGIN_NFILE);
|
||||
goto elookup;
|
||||
}
|
||||
}
|
||||
|
|
@ -237,7 +202,7 @@ cinelerra_interface_open (const char* name, const char* interface, size_t min_re
|
|||
if (!(*found)->handle)
|
||||
{
|
||||
ERROR (cinelerra_plugin, "dlopen failed: %s", dlerror());
|
||||
cinelerra_plugin_error_set (CINELERRA_PLUGIN_EDLOPEN);
|
||||
cinelerra_error_set (CINELERRA_ERROR_PLUGIN_DLOPEN);
|
||||
goto edlopen;
|
||||
}
|
||||
|
||||
|
|
@ -246,7 +211,7 @@ cinelerra_interface_open (const char* name, const char* interface, size_t min_re
|
|||
if (init && init())
|
||||
{
|
||||
ERROR (cinelerra_plugin, "cinelerra_plugin_init failed: %s: %s", name, interface);
|
||||
cinelerra_plugin_error_set (CINELERRA_PLUGIN_EHOOK);
|
||||
cinelerra_error_set (CINELERRA_ERROR_PLUGIN_HOOK);
|
||||
goto einit;
|
||||
}
|
||||
}
|
||||
|
|
@ -258,7 +223,7 @@ cinelerra_interface_open (const char* name, const char* interface, size_t min_re
|
|||
if (!ret)
|
||||
{
|
||||
ERROR (cinelerra_plugin, "plugin %s doesnt provide interface %s", name, interface);
|
||||
cinelerra_plugin_error_set (CINELERRA_PLUGIN_ENIFACE);
|
||||
cinelerra_error_set (CINELERRA_ERROR_PLUGIN_NIFACE);
|
||||
goto edlsym;
|
||||
}
|
||||
|
||||
|
|
@ -266,7 +231,7 @@ cinelerra_interface_open (const char* name, const char* interface, size_t min_re
|
|||
if (ret->size < min_revision)
|
||||
{
|
||||
ERROR (cinelerra_plugin, "plugin %s provides older interface %s revision than required", name, interface);
|
||||
cinelerra_plugin_error_set (CINELERRA_PLUGIN_EREVISION);
|
||||
cinelerra_error_set (CINELERRA_ERROR_PLUGIN_REVISION);
|
||||
goto erevision;
|
||||
}
|
||||
|
||||
|
|
@ -276,7 +241,7 @@ cinelerra_interface_open (const char* name, const char* interface, size_t min_re
|
|||
if (ret->open && ret->open())
|
||||
{
|
||||
ERROR (cinelerra_plugin, "open hook indicated an error");
|
||||
cinelerra_plugin_error_set (CINELERRA_PLUGIN_EHOOK);
|
||||
cinelerra_error_set (CINELERRA_ERROR_PLUGIN_HOOK);
|
||||
goto eopen;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -30,6 +30,8 @@ extern "C" {
|
|||
#include <stdlib.h>
|
||||
#include <nobug.h>
|
||||
|
||||
#include "error.h"
|
||||
|
||||
NOBUG_DECLARE_FLAG (cinelerra_plugin);
|
||||
|
||||
/* tool macros*/
|
||||
|
|
@ -129,30 +131,11 @@ cinelerra_plugin_unload (const char* plugin);
|
|||
void
|
||||
cinelerra_plugin_expire (time_t age);
|
||||
|
||||
/**
|
||||
* Query and reset the error state.
|
||||
* report last error, reset error state. Errors are thread local.
|
||||
* Error strings are guaranteed to point to a C string with a unique comparable address.
|
||||
* Note that the error state gets cleared by calling this function. The application may store it temporary for further handling.
|
||||
* @return pointer to one of the error C-strings, NULL when no error happened.
|
||||
*/
|
||||
const char*
|
||||
cinelerra_plugin_error ();
|
||||
|
||||
/// success, NULL
|
||||
extern const char* CINELERRA_PLUGIN_SUCCESS;
|
||||
/// memory allocation error
|
||||
extern const char* CINELERRA_PLUGIN_EALLOC;
|
||||
/// dlopen failed
|
||||
extern const char* CINELERRA_PLUGIN_EDLOPEN;
|
||||
/// dlopen failed
|
||||
extern const char* CINELERRA_PLUGIN_EHOOK;
|
||||
/// Plugin not found
|
||||
extern const char* CINELERRA_PLUGIN_ENFOUND;
|
||||
/// no such interface
|
||||
extern const char* CINELERRA_PLUGIN_ENIFACE;
|
||||
/// revision not sufficient
|
||||
extern const char* CINELERRA_PLUGIN_EREVISION;
|
||||
CINELERRA_ERROR_DECLARE(PLUGIN_DLOPEN);
|
||||
CINELERRA_ERROR_DECLARE(PLUGIN_HOOK);
|
||||
CINELERRA_ERROR_DECLARE(PLUGIN_NFILE);
|
||||
CINELERRA_ERROR_DECLARE(PLUGIN_NIFACE);
|
||||
CINELERRA_ERROR_DECLARE(PLUGIN_REVISION);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
|
|
|
|||
|
|
@ -18,13 +18,14 @@
|
|||
examples_srcdir = $(top_srcdir)/tests/examples
|
||||
noinst_PROGRAMS += plugin_example
|
||||
|
||||
plugin_example_CFLAGS = $(CFLAGS) -std=gnu99 -Wall -Werror
|
||||
plugin_example_CPPFLAGS = $(CPPFLAGS) -std=gnu99 -Wall -Werror -I$(top_srcdir)/src/lib/
|
||||
plugin_example_CFLAGS = $(AM_CFLAGS) -std=gnu99 -Wall -Werror
|
||||
plugin_example_CPPFLAGS = $(AM_CPPFLAGS) -std=gnu99 -Wall -Werror -I$(top_srcdir)/src/lib/
|
||||
plugin_example_LDADD = $(builddir)/libcin3.a -lnobugmt -lpthread -ldl
|
||||
|
||||
plugin_example_SOURCES = $(examples_srcdir)/plugin_main.c
|
||||
noinst_HEADERS += $(examples_srcdir)/hello_interface.h
|
||||
|
||||
#noinst_LTLIBRARIES += example_plugin.la
|
||||
#example_plugin_la_CPPFLAGS = $(CPPFLAGS) -std=gnu99 -Wall -Werror -I$(top_srcdir)/src/lib/
|
||||
#example_plugin_la_SOURCES = $(examples_srcdir)/example_plugin.c
|
||||
check_LTLIBRARIES = example_plugin.la
|
||||
example_plugin_la_CPPFLAGS = $(AM_CPPFLAGS) -std=gnu99 -Wall -Werror -I$(top_srcdir)/src/lib/
|
||||
example_plugin_la_SOURCES = $(examples_srcdir)/example_plugin.c
|
||||
example_plugin_la_LDFLAGS = -module
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
int
|
||||
main(int argc, char** argv)
|
||||
{
|
||||
NOBUG_INIT;
|
||||
/*
|
||||
we have a plugin 'hello_1' which provides us 2 hello interfaces, one for english and one for german output,
|
||||
open both try them, close them.
|
||||
|
|
|
|||
Loading…
Reference in a new issue