{
callback_func_t *cf;
- cf = c_head_get_root (read_heap);
+ cf = c_heap_get_root (read_heap);
if (cf == NULL)
break;
*list = llist_create ();
if (*list == NULL)
{
- ERROR ("plugin: create_register_callback: "
+ ERROR ("plugin: register_callback: "
"llist_create failed.");
destroy_callback (cf);
return (-1);
key = strdup (name);
if (key == NULL)
{
- ERROR ("plugin: create_register_callback: strdup failed.");
+ ERROR ("plugin: register_callback: strdup failed.");
destroy_callback (cf);
return (-1);
}
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);
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);
}
* 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);
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 ();
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)
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;
/* 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);
}
#define BUFSIZE 512
-int plugin_load (const char *type)
+int plugin_load (const char *type, uint32_t flags)
{
DIR *dh;
const char *dir;
continue;
}
- if (plugin_load_file (filename) == 0)
+ if (plugin_load_file (filename, flags) == 0)
{
/* success */
ret = 0;
{
read_func_t *rf;
- rf = c_head_get_root (read_heap);
+ rf = c_heap_get_root (read_heap);
if (rf == NULL)
break;
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;
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)
{