X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=src%2Fplugin.c;h=5ff21c668d4637ed2720d6a13dbdcd56d7439d6e;hb=d48a9456e42af4ab5881ab055c95ceab71819bc1;hp=11a0ef6eadbada45aad092f7116c879aeef9dfdd;hpb=8be9c73cc216609a54a1b997aad8a3d646a0a43f;p=collectd.git diff --git a/src/plugin.c b/src/plugin.c index 11a0ef6e..5ff21c66 100644 --- a/src/plugin.c +++ b/src/plugin.c @@ -151,7 +151,7 @@ static void destroy_read_heap (void) /* {{{ */ { callback_func_t *cf; - cf = c_head_get_root (read_heap); + cf = c_heap_get_root (read_heap); if (cf == NULL) break; @@ -173,7 +173,7 @@ static int register_callback (llist_t **list, /* {{{ */ *list = llist_create (); if (*list == NULL) { - ERROR ("plugin: create_register_callback: " + ERROR ("plugin: register_callback: " "llist_create failed."); destroy_callback (cf); return (-1); @@ -183,7 +183,7 @@ static int register_callback (llist_t **list, /* {{{ */ key = strdup (name); if (key == NULL) { - ERROR ("plugin: create_register_callback: strdup failed."); + ERROR ("plugin: register_callback: strdup failed."); destroy_callback (cf); return (-1); } @@ -194,7 +194,7 @@ static int register_callback (llist_t **list, /* {{{ */ le = llentry_create (key, cf); if (le == NULL) { - ERROR ("plugin: create_register_callback: " + ERROR ("plugin: register_callback: " "llentry_create failed."); free (key); destroy_callback (cf); @@ -210,6 +210,10 @@ static int register_callback (llist_t **list, /* {{{ */ old_cf = le->value; le->value = cf; + WARNING ("plugin: register_callback: " + "a callback named `%s' already exists - " + "overwriting the old entry!", name); + destroy_callback (old_cf); sfree (key); } @@ -270,7 +274,7 @@ static int plugin_unregister (llist_t *list, const char *name) /* {{{ */ * object, but it will bitch about a shared object not having a * ``module_register'' symbol.. */ -static int plugin_load_file (char *file) +static int plugin_load_file (char *file, uint32_t flags) { lt_dlhandle dlh; void (*reg_handle) (void); @@ -280,7 +284,24 @@ static int plugin_load_file (char *file) lt_dlinit (); lt_dlerror (); /* clear errors */ - if ((dlh = lt_dlopen (file)) == NULL) +#if LIBTOOL_VERSION == 2 + if (flags & PLUGIN_FLAGS_GLOBAL) { + lt_dladvise advise; + lt_dladvise_init(&advise); + lt_dladvise_global(&advise); + dlh = lt_dlopenadvise(file, advise); + lt_dladvise_destroy(&advise); + } else { + dlh = lt_dlopen (file); + } +#else /* if LIBTOOL_VERSION == 1 */ + if (flags & PLUGIN_FLAGS_GLOBAL) + ERROR ("plugin_load_file: The global flag is not supported, " + "libtool 2 is required for this."); + dlh = lt_dlopen (file); +#endif + + if (dlh == NULL) { const char *error = lt_dlerror (); @@ -302,6 +323,13 @@ static int plugin_load_file (char *file) return (0); } +static _Bool timeout_reached(struct timespec timeout) +{ + struct timeval now; + gettimeofday(&now, NULL); + return (now.tv_sec >= timeout.tv_sec && now.tv_usec >= (timeout.tv_nsec / 1000)); +} + static void *plugin_read_thread (void __attribute__((unused)) *args) { while (read_loop != 0) @@ -310,9 +338,10 @@ static void *plugin_read_thread (void __attribute__((unused)) *args) struct timeval now; int status; int rf_type; + int rc; /* Get the read function that needs to be read next. */ - rf = c_head_get_root (read_heap); + rf = c_heap_get_root (read_heap); if (rf == NULL) { struct timespec abstime; @@ -345,8 +374,16 @@ static void *plugin_read_thread (void __attribute__((unused)) *args) /* sleep until this entry is due, * using pthread_cond_timedwait */ pthread_mutex_lock (&read_lock); - pthread_cond_timedwait (&read_cond, &read_lock, + /* In pthread_cond_timedwait, spurious wakeups are possible + * (and really happen, at least on NetBSD with > 1 CPU), thus + * we need to re-evaluate the condition every time + * pthread_cond_timedwait returns. */ + rc = 0; + while (!timeout_reached(rf->rf_next_read) && rc == 0) { + rc = pthread_cond_timedwait (&read_cond, &read_lock, &rf->rf_next_read); + } + /* Must hold `real_lock' when accessing `rf->rf_type'. */ rf_type = rf->rf_type; pthread_mutex_unlock (&read_lock); @@ -535,7 +572,7 @@ void plugin_set_dir (const char *dir) } #define BUFSIZE 512 -int plugin_load (const char *type) +int plugin_load (const char *type, uint32_t flags) { DIR *dh; const char *dir; @@ -597,7 +634,7 @@ int plugin_load (const char *type) continue; } - if (plugin_load_file (filename) == 0) + if (plugin_load_file (filename, flags) == 0) { /* success */ ret = 0; @@ -1036,7 +1073,7 @@ int plugin_read_all_once (void) { read_func_t *rf; - rf = c_head_get_root (read_heap); + rf = c_heap_get_root (read_heap); if (rf == NULL) break; @@ -1443,14 +1480,6 @@ void plugin_log (int level, const char *format, ...) va_list ap; llentry_t *le; - if (list_log == NULL) - { - va_start (ap, format); - vfprintf (stderr, format, ap); - va_end (ap); - return; - } - #if !COLLECT_DEBUG if (level >= LOG_DEBUG) return; @@ -1461,6 +1490,12 @@ void plugin_log (int level, const char *format, ...) msg[sizeof (msg) - 1] = '\0'; va_end (ap); + if (list_log == NULL) + { + fprintf (stderr, "%s\n", msg); + return; + } + le = llist_head (list_log); while (le != NULL) {