]> sourceware.org Git - dm.git/commitdiff
o Added a lib to handle locking - the multilog lib attempts to load it,
authorAJ Lewis <alewis@redhat.com>
Wed, 4 May 2005 17:55:12 +0000 (17:55 +0000)
committerAJ Lewis <alewis@redhat.com>
Wed, 4 May 2005 17:55:12 +0000 (17:55 +0000)
   and if it fails because the binary wasn't compiled with pthread support
   it just uses NOP locking.  If it fails for any other reason, it fails
   adding locking.
 o added libmultilog_pthread_lock library that just does pthread mutex
   locking

configure
configure.in
multilog/Makefile.in
multilog/libmultilog.c
multilog/libmultilog.h
multilog/pthread_lock/.exported_symbols [new file with mode: 0644]
multilog/pthread_lock/Makefile.in [new file with mode: 0644]
multilog/pthread_lock/pthread_lock.c [new file with mode: 0644]
multilog/pthread_lock/pthread_lock.h [new file with mode: 0644]

index daa7a98500a4dc10f92c5f8a9ebde8014bc2aa4f..ae6c6096259719e657211d6a665858fa8a215a75 100755 (executable)
--- a/configure
+++ b/configure
@@ -4979,7 +4979,7 @@ fi
 
 
 ################################################################################
-ac_config_files="$ac_config_files Makefile make.tmpl include/Makefile dmeventd/Makefile dmsetup/Makefile lib/Makefile lib/event/Makefile lib/libdm-common.h kernel/Makefile man/Makefile multilog/Makefile multilog/async/Makefile multilog/tests/Makefile po/Makefile"
+ac_config_files="$ac_config_files Makefile make.tmpl include/Makefile dmeventd/Makefile dmsetup/Makefile lib/Makefile lib/event/Makefile lib/libdm-common.h kernel/Makefile man/Makefile multilog/Makefile multilog/async/Makefile multilog/pthread_lock/Makefile multilog/tests/Makefile po/Makefile"
 cat >confcache <<\_ACEOF
 # This file is a shell script that caches the results of configure
 # tests run on this system so they can be shared between configure
@@ -5489,6 +5489,7 @@ do
   "man/Makefile" ) CONFIG_FILES="$CONFIG_FILES man/Makefile" ;;
   "multilog/Makefile" ) CONFIG_FILES="$CONFIG_FILES multilog/Makefile" ;;
   "multilog/async/Makefile" ) CONFIG_FILES="$CONFIG_FILES multilog/async/Makefile" ;;
+  "multilog/pthread_lock/Makefile" ) CONFIG_FILES="$CONFIG_FILES multilog/pthread_lock/Makefile" ;;
   "multilog/tests/Makefile" ) CONFIG_FILES="$CONFIG_FILES multilog/tests/Makefile" ;;
   "po/Makefile" ) CONFIG_FILES="$CONFIG_FILES po/Makefile" ;;
   *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5
index 404a00d4c7bbbcf3d143b783d70be1d181c431dd..d8d64154a1381978ab1a310507ac11ca9385d1a1 100644 (file)
@@ -364,6 +364,7 @@ kernel/Makefile                                                             \
 man/Makefile                                                           \
 multilog/Makefile                                                      \
 multilog/async/Makefile                                                        \
+multilog/pthread_lock/Makefile                                         \
 multilog/tests/Makefile                                                        \
 po/Makefile                                                            \
 )
index 7ecaefbfcf53f93f8cb5344804a6a24fd04c9446..bfa65c33aa96b3bb8e7b530e0e1b92c33838422b 100644 (file)
@@ -16,7 +16,7 @@ top_srcdir = @top_srcdir@
 VPATH = @srcdir@
 interface = @interface@
 
-SUBDIRS += async
+SUBDIRS += async pthread_lock
 
 SOURCES = libmultilog.c
 
index 3302d81c67e2c7c07158aa860988e5d1e33d8b28..dd0c970a34869bdbe62676a253702f175b80643d 100644 (file)
@@ -13,7 +13,6 @@
  */
 
 #include <dlfcn.h>
-#include <pthread.h>
 #include <stdarg.h>
 #include <stdint.h>
 #include <stdio.h>
@@ -33,42 +32,89 @@ struct log_list {
        struct list list;
        enum log_type type;
        multilog_fn log;
-       void *data;
+       struct log_data *data;
 };
 
 /* FIXME: probably shouldn't do it this way, but... */
 static LIST_INIT(logs);
 
-/* Mutext for logs accesses. */
-static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
-static int (*lock_fn)(pthread_mutex_t *) = NULL;
-static int (*unlock_fn)(pthread_mutex_t *) = NULL;
+/* locking for log accesss */
+static void* (*init_lock_fn)(void) = NULL;
+static int (*lock_fn)(void *) = NULL;
+static int (*unlock_fn)(void *) = NULL;
+static void (*destroy_lock_fn)(void *) = NULL;
+void *lock_dlh = NULL;
+void *lock_handle = NULL;
 
-static void lock_mutex(void)
+static void *init_lock(void)
+{
+       return init_lock_fn ? init_lock_fn() : NULL;
+}
+
+static int lock_list(void *handle)
 {
        if (lock_fn)
-               (*lock_fn)(&mutex);
+               return !(*lock_fn)(handle);
+       return 0;
 }
 
-static void unlock_mutex(void)
+static int unlock_list(void *handle)
 {
        if (unlock_fn)
-               (*unlock_fn)(&mutex);
+               return !(*unlock_fn)(handle);
+       return 0;
+}
+
+static void destroy_lock(void *handle)
+{
+       if(destroy_lock_fn)
+               (*destroy_lock_fn)(handle);
+}
+
+static void *init_nop_lock(void)
+{
+       return NULL;
 }
 
-static int load_pthread_syms(struct log_data *data)
+static int nop_lock(void *handle)
+{
+       return 0;
+}
+
+static int nop_unlock(void *handle)
+{
+       return 0;
+}
+
+static void destroy_nop_lock(void *handle)
+{
+       return;
+}
+
+static int load_lock_syms(struct log_data *data)
 {
        void *dlh;
 
-       if (!(dlh = dlopen("libpthread.so", RTLD_NOW))) {
-               fprintf(stderr, "%s\n", dlerror());
-               return 0;
+       if (!(dlh = dlopen("libmultilog_pthread_lock.so", RTLD_NOW))) {
+               //fprintf(stderr, "%s\n", dlerror());
+               if(strstr(dlerror(), "undefined symbol: pthread")) {
+                       fprintf(stderr, "pthread library not linked in - using nop locking\n");
+                       init_lock_fn = init_nop_lock;
+                       lock_fn = nop_lock;
+                       unlock_fn = nop_unlock;
+                       destroy_lock_fn = destroy_nop_lock;
+                       return 1;
+               }
+               else
+                       return 0;
        }
 
-       data->info.threaded_syslog.pthread_dlh = dlh;
+       lock_dlh = dlh;
 
-       return (lock_fn = dlsym(dlh, "pthread_mutex_lock")) &&
-              (unlock_fn = dlsym(dlh, "pthread_mutex_unlock"));
+       return ((init_lock_fn = dlsym(dlh, "init_locking")) &&
+               (lock_fn = dlsym(dlh, "lock_fn")) &&
+               (unlock_fn = dlsym(dlh, "unlock_fn")) &&
+               (destroy_lock_fn = dlsym(dlh, "destroy_locking")));
 }
 
 
@@ -142,8 +188,7 @@ static int start_threaded_syslog(struct log_list *logl,
        log_fxn = dlsym(logdata->info.threaded_syslog.dlh, "write_to_buf");
        start_syslog = dlsym(logdata->info.threaded_syslog.dlh, "start_syslog_thread");
 
-       if (!log_fxn || !start_syslog ||
-           !load_pthread_syms(logdata)) {
+       if (!log_fxn || !start_syslog) {
                dlclose(logdata->info.threaded_syslog.dlh);
                return 0;
        }
@@ -161,6 +206,15 @@ int multilog_add_type(enum log_type type, struct log_data *data)
 {
        struct log_list *logl, *ll;
 
+       /* FIXME: Potential race here */
+       /* attempt to load locking protocol */
+       if(!init_lock_fn) {
+               if(!load_lock_syms(data)) {
+                       fprintf(stderr, "Unalbe to load locking\n");
+                       return 0;
+               }
+               lock_handle = init_lock();
+       }
        /*
         * Preallocate because we don't want to sleep holding a lock.
         */
@@ -172,19 +226,19 @@ int multilog_add_type(enum log_type type, struct log_data *data)
         * If the type has already been registered,
         * it doesn't need to be registered again.
         */
-       lock_mutex();
+       lock_list(lock_handle);
 
        list_iterate_items(ll, &logs) {
                if (ll->type == type) {
-                       unlock_mutex();
+                       unlock_list(lock_handle);
                        free(logl);
-
                        return 1;
                }
        }
-
        logl->type = type;
        logl->data = data;
+       list_add(&logs, &logl->list);
+       unlock_list(lock_handle);
 
        switch (type) {
        case standard:
@@ -200,7 +254,9 @@ int multilog_add_type(enum log_type type, struct log_data *data)
                break;
        case threaded_syslog:
                if (!start_threaded_syslog(logl, data)) {
-                       unlock_mutex();
+                       lock_list(lock_handle);
+                       list_del(&logl->list);
+                       unlock_list(lock_handle);
                        free(logl);
                        return 0;
                }
@@ -213,9 +269,6 @@ int multilog_add_type(enum log_type type, struct log_data *data)
                break;
        }
 
-       list_add(&logs, &logl->list);
-       unlock_mutex();
-
        return 1;
 }
 
@@ -230,24 +283,38 @@ void multilog_clear_logging(void)
        list_init(&ll);
 
        /* First step: move elements to temporary local list safely. */
-       lock_mutex();
+       lock_list(lock_handle);
 
        list_iterate_safe(tmp, next, &logs) {
                list_del(tmp);
                list_add(&ll, tmp);
        }
 
-       unlock_mutex();
+       unlock_list(lock_handle);
 
        /* Second step: delete them. */
        list_iterate_safe(tmp, next, &ll) {
                logl = list_item(tmp, struct log_list);
 
+               if(logl->type == threaded_syslog) {
+                       if(logl->data->info.threaded_syslog.dlh) {
+                               int (*stop_syslog) (struct log_data *log);
+                               stop_syslog = dlsym(logl->data->info.threaded_syslog.dlh,
+                                                   "stop_syslog_thread");
+                               stop_syslog(logl->data);
+                               dlclose(logl->data->info.threaded_syslog.dlh);
+                       }
+               }
+
                if (logl->data)
                        free(logl->data);
 
                list_del(tmp);
        }
+       /* FIXME: Not sure the destroy_lock call is really necessary */
+       destroy_lock(lock_handle);
+       dlclose(lock_dlh);
+
 }
 
 /* FIXME: Might want to have this return an error if we can't find the type */
@@ -257,7 +324,7 @@ void multilog_del_type(enum log_type type, struct log_data *data)
        struct log_list *logl, *ll = NULL;
 
        /* First delete type from list safely. */
-       lock_mutex();
+       lock_list(lock_handle);
 
        list_iterate_safe(tmp, next, &logs) {
                logl = list_item(tmp, struct log_list); 
@@ -269,7 +336,7 @@ void multilog_del_type(enum log_type type, struct log_data *data)
                }
        }
 
-       unlock_mutex();
+       unlock_list(lock_handle);
 
        if (ll) {
                if (ll->type == threaded_syslog) {
@@ -279,7 +346,6 @@ void multilog_del_type(enum log_type type, struct log_data *data)
                                stop_syslog(data);
 
                        dlclose(data->info.threaded_syslog.dlh);
-                       dlclose(data->info.threaded_syslog.pthread_dlh);
                }
 
                free(ll);
@@ -294,14 +360,14 @@ void multilog_custom(multilog_fn fn)
         * FIXME: Should we present an error if
         * we can't find a suitable target?
         */
-       lock_mutex();
+       lock_list(lock_handle);
 
        list_iterate_items(logl, &logs) {
                if (logl->type == custom && logl->log == nop_log)
                        logl->log = fn;
        }
 
-       unlock_mutex();
+       unlock_list(lock_handle);
 }
 
 
@@ -317,10 +383,10 @@ void multilog(int priority, const char *file, int line, const char *format, ...)
        vsnprintf(buf, 4096, format, args);
        va_end(args);
 
-       lock_mutex();
+       lock_list(lock_handle);
 
        list_iterate_items(logl, &logs)
                logl->log(logl->data, priority, file, line, buf);
 
-       unlock_mutex();
+       unlock_list(lock_handle);
 }
index cdd59ad3460c7a9c3fd47226867a9b2667ba4ad5..4c6414808c16a15c1829fc1166968ecfc9858a79 100644 (file)
@@ -34,7 +34,6 @@ struct file_log {
 struct threaded_syslog_log {
        pthread_t thread;
        void *dlh;
-       void *pthread_dlh;
 };
 
 union log_info {
diff --git a/multilog/pthread_lock/.exported_symbols b/multilog/pthread_lock/.exported_symbols
new file mode 100644 (file)
index 0000000..673b466
--- /dev/null
@@ -0,0 +1,4 @@
+init_locking
+lock_fn
+unlock_fn
+destroy_locking
\ No newline at end of file
diff --git a/multilog/pthread_lock/Makefile.in b/multilog/pthread_lock/Makefile.in
new file mode 100644 (file)
index 0000000..6d42bfa
--- /dev/null
@@ -0,0 +1,52 @@
+#
+# Copyright (C) 2005 Red Hat, Inc. All rights reserved.
+#
+# This file is part of the device-mapper userspace tools.
+#
+# This copyrighted material is made available to anyone wishing to use,
+# modify, copy, or redistribute it subject to the terms and conditions
+# of the GNU Lesser General Public License v.2.1.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+interface = @interface@
+
+SOURCES = pthread_lock.c
+
+LIB_STATIC = libmultilog_pthread_lock.a
+
+ifeq ("@LIB_SUFFIX@","dylib")
+  LIB_SHARED = libmultilog_pthread_lock.dylib
+else
+  LIB_SHARED = libmultilog_pthread_lock.so
+endif
+
+LDFLAGS += -ldl -ldevmapper -lpthread -L..
+
+include ../../make.tmpl
+
+.PHONY: install_dynamic install_static
+
+INSTALL_TYPE = install_dynamic
+
+ifeq ("@STATIC_LINK@", "yes")
+  INSTALL_TYPE += install_static
+endif
+
+install: $(INSTALL_TYPE)
+
+install_dynamic: libmultilog_pthread_lock.$(LIB_SUFFIX)
+       $(INSTALL) -D $(OWNER) $(GROUP) -m 555 $(STRIP) $< \
+               $(libdir)/libmultilog_pthread_lock.$(LIB_SUFFIX).$(LIB_VERSION)
+       $(LN_S) -f libmultilog_pthread_lock.$(LIB_SUFFIX).$(LIB_VERSION) \
+               $(libdir)/libmultilog_pthread_lock.$(LIB_SUFFIX)
+
+install_static: libmultilog_pthread_lock.a
+       $(INSTALL) -D $(OWNER) $(GROUP) -m 555 $(STRIP) $< \
+               $(libdir)/libmultilog_pthread_lock.a.$(LIB_VERSION)
+       $(LN_S) -f libmultilog_pthread_lock.a.$(LIB_VERSION) $(libdir)/libmultilog_pthread_lock.a
diff --git a/multilog/pthread_lock/pthread_lock.c b/multilog/pthread_lock/pthread_lock.c
new file mode 100644 (file)
index 0000000..dfe24dc
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2005 Red Hat, Inc. All rights reserved.
+ *
+ * This file is part of the device-mapper userspace tools.
+ *
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU Lesser General Public License v.2.1.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <pthread.h>
+#include <stdlib.h>
+#include <string.h>
+#include "pthread_lock.h"
+
+void *nop(void *data)
+{
+       pthread_exit(NULL);
+}
+
+void *init_locking(void)
+{
+       pthread_t thread;
+       pthread_mutex_t *mutex;
+       if(!(mutex = malloc(sizeof(*mutex))))
+               return NULL;
+       if(!memset(mutex, 0, sizeof(*mutex)))
+               return NULL;
+       /*
+        * Hack to ensure DSO loading fails if not linked with
+        * libpthread
+        */
+       pthread_create(&thread, NULL, nop, NULL);
+
+       return mutex;
+}
+
+int lock_fn(void *handle)
+{
+       pthread_mutex_t *mutex = (pthread_mutex_t *)handle;
+       if(mutex)
+               return pthread_mutex_lock(mutex);
+       else
+               return 0;
+}
+
+
+int unlock_fn(void *handle)
+{
+       pthread_mutex_t *mutex = (pthread_mutex_t *)handle;
+       if(mutex)
+               return pthread_mutex_unlock(mutex);
+       else
+               return 0;
+}
+
+
+void destroy_locking(void *handle)
+{
+        pthread_mutex_t *mutex = (pthread_mutex_t *)handle;
+       if(mutex)
+               free(mutex);
+}
+
diff --git a/multilog/pthread_lock/pthread_lock.h b/multilog/pthread_lock/pthread_lock.h
new file mode 100644 (file)
index 0000000..c180ae9
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2005 Red Hat, Inc. All rights reserved.
+ *
+ * This file is part of the device-mapper userspace tools.
+ *
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU Lesser General Public License v.2.1.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef LIB_PTHREADLOCK_H
+#define LIB_PTHREADLOCK_H
+
+void *init_locking(void);
+int lock_fn(void *handle);
+int unlock_fn(void *handle);
+void destroy_locking(void *handle);
+
+#endif
This page took 0.045816 seconds and 5 git commands to generate.