summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/wrap.c235
-rw-r--r--src/wrap.h40
2 files changed, 275 insertions, 0 deletions
diff --git a/src/wrap.c b/src/wrap.c
new file mode 100644
index 0000000..a2ac5ba
--- /dev/null
+++ b/src/wrap.c
@@ -0,0 +1,235 @@
+/*
+ * Copyright 2008 Red Hat, Inc.
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This Program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU 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
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "../config.h"
+#endif
+
+#include <sys/types.h>
+#include <pthread.h>
+#include <search.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <unistd.h>
+
+#ifdef HAVE_DIRSRV_SLAPI_PLUGIN_H
+#include <nspr.h>
+#include <nss.h>
+#include <dirsrv/slapi-plugin.h>
+#else
+#include <slapi-plugin.h>
+#endif
+
+#ifdef USE_PTHREADS
+#include <pthread.h>
+#endif
+
+#include <rpc/xdr.h>
+
+#include "wrap.h"
+
+struct wrapped_thread {
+#if defined(USE_PTHREADS)
+ pthread_t tid;
+ void *arg;
+#elif defined(USE_NSPR_THREADS)
+ PRThread *tid;
+ struct wrapped_pthread_args {
+ void * (*fn)(struct wrapped_thread *);
+ void *arg, *result;
+ } args;
+#else
+#error "Unknown threading model!"
+#endif
+ int stopfd[2];
+};
+
+struct wrapped_rwlock {
+#if defined(USE_PTHREADS)
+ pthread_rwlock_t rwlock;
+#elif defined(USE_NSPR_THREADS)
+ PRRWLock *rwlock;
+#else
+#error "Unknown threading model!"
+#endif
+};
+
+#ifdef USE_NSPR_THREADS
+static void
+wrap_pthread_starter(void *p)
+{
+ struct wrapped_thread *t = p;
+ t->args.result = t->args.fn(t);
+}
+#endif
+
+void *
+wrap_thread_arg(struct wrapped_thread *t)
+{
+#ifdef USE_PTHREADS
+ return t->arg;
+#endif
+#ifdef USE_NSPR_THREADS
+ return t->args.arg;
+#endif
+}
+
+struct wrapped_thread *
+wrap_start_thread(void * (*fn)(struct wrapped_thread *), void *arg)
+{
+ struct wrapped_thread *t;
+ void *returned;
+ t = malloc(sizeof(*t));
+ if (t == NULL) {
+ return NULL;
+ }
+ memset(t, 0, sizeof(*t));
+ if (pipe(t->stopfd) == -1) {
+ free(t);
+ return NULL;
+ }
+#ifdef USE_PTHREADS
+ t->arg = arg;
+ if (pthread_create(&t->tid, NULL, fn, t) != 0) {
+ free(t);
+ return NULL;
+ }
+#endif
+#ifdef USE_NSPR_THREADS
+ t->args.fn = fn;
+ t->args.arg = arg;
+ t->args.result = NULL;
+ t->tid = PR_CreateThread(PR_SYSTEM_THREAD,
+ wrap_pthread_starter, t,
+ PR_PRIORITY_NORMAL,
+ PR_GLOBAL_THREAD,
+ PR_JOINABLE_THREAD,
+ 0);
+ if (t->tid == NULL) {
+ free(t);
+ return NULL;
+ }
+#endif
+ return t;
+}
+
+void *
+wrap_stop_thread(struct wrapped_thread *t)
+{
+ void *returned = NULL;
+#ifdef USE_PTHREADS
+ write(t->stopfd[1], "", 1);
+ close(t->stopfd[1]);
+ pthread_join(t->tid, &returned);
+#endif
+#ifdef USE_NSPR_THREADS
+ write(t->stopfd[1], "", 1);
+ close(t->stopfd[1]);
+ PR_JoinThread(t->tid);
+ returned = t->args.result;
+#endif
+ free(t);
+ return returned;
+}
+
+int
+wrap_thread_stopfd(struct wrapped_thread *t)
+{
+ int ret;
+#ifdef USE_PTHREADS
+ ret = t->stopfd[0];
+#endif
+#ifdef USE_NSPR_THREADS
+ ret = t->stopfd[0];
+#endif
+ return ret;
+}
+
+struct wrapped_rwlock *
+wrap_new_rwlock(void)
+{
+ struct wrapped_rwlock *rwlock;
+ rwlock = malloc(sizeof(*rwlock));
+ if (rwlock == NULL) {
+ return NULL;
+ }
+#ifdef USE_PTHREADS
+ if (pthread_rwlock_init(&rwlock->rwlock, NULL) != 0) {
+ free(rwlock);
+ return NULL;
+ }
+#endif
+#ifdef USE_NSPR_THREADS
+ rwlock->rwlock = PR_NewRWLock(PR_RWLOCK_RANK_NONE,
+ PACKAGE_NAME "-rw-lock");
+ if (rwlock->rwlock == NULL) {
+ free(rwlock);
+ return NULL;
+ }
+#endif
+ return rwlock;
+}
+
+void
+wrap_free_rwlock(struct wrapped_rwlock *rwlock)
+{
+#ifdef USE_PTHREADS
+ pthread_rwlock_destroy(&rwlock->rwlock);
+#endif
+#ifdef USE_NSPR_THREADS
+ PR_DestroyRWLock(rwlock->rwlock);
+#endif
+ free(rwlock);
+}
+
+void
+wrap_rwlock_rdlock(struct wrapped_rwlock *rwlock)
+{
+#ifdef USE_PTHREADS
+ pthread_rwlock_rdlock(&rwlock->rwlock);
+#endif
+#ifdef USE_NSPR_THREADS
+ PR_RWLock_Rlock(rwlock->rwlock);
+#endif
+}
+
+void
+wrap_rwlock_wrlock(struct wrapped_rwlock *rwlock)
+{
+#ifdef USE_PTHREADS
+ pthread_rwlock_wrlock(&rwlock->rwlock);
+#endif
+#ifdef USE_NSPR_THREADS
+ PR_RWLock_Wlock(rwlock->rwlock);
+#endif
+}
+
+void
+wrap_rwlock_unlock(struct wrapped_rwlock *rwlock)
+{
+#ifdef USE_PTHREADS
+ pthread_rwlock_unlock(&rwlock->rwlock);
+#endif
+#ifdef USE_NSPR_THREADS
+ PR_RWLock_Unlock(rwlock->rwlock);
+#endif
+}
diff --git a/src/wrap.h b/src/wrap.h
new file mode 100644
index 0000000..d5cc434
--- /dev/null
+++ b/src/wrap.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2008 Red Hat, Inc.
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This Program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU 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 wrap_h
+#define wrap_h
+
+struct wrapped_thread;
+struct wrapped_rwlock;
+
+struct wrapped_thread * wrap_start_thread(void * (*fn)(struct wrapped_thread *),
+ void *arg);
+void *wrap_stop_thread(struct wrapped_thread *t);
+void *wrap_thread_arg(struct wrapped_thread *t);
+int wrap_thread_stopfd(struct wrapped_thread *t);
+
+struct wrapped_rwlock *wrap_new_rwlock(void);
+void wrap_free_rwlock(struct wrapped_rwlock *rwlock);
+void wrap_rwlock_rdlock(struct wrapped_rwlock *rwlock);
+void wrap_rwlock_wrlock(struct wrapped_rwlock *rwlock);
+void wrap_rwlock_unlock(struct wrapped_rwlock *rwlock);
+
+#endif