summaryrefslogtreecommitdiffstats
path: root/lib/base/fsmutex.cpp
diff options
context:
space:
mode:
authorcvsadm <cvsadm>2005-01-21 00:44:34 +0000
committercvsadm <cvsadm>2005-01-21 00:44:34 +0000
commitb2093e3016027d6b5cf06b3f91f30769bfc099e2 (patch)
treecf58939393a9032182c4fbc4441164a9456e82f8 /lib/base/fsmutex.cpp
downloadds-b2093e3016027d6b5cf06b3f91f30769bfc099e2.tar.gz
ds-b2093e3016027d6b5cf06b3f91f30769bfc099e2.tar.xz
ds-b2093e3016027d6b5cf06b3f91f30769bfc099e2.zip
Moving NSCP Directory Server from DirectoryBranch to TRUNK, initial drop. (foxworth)ldapserver7x
Diffstat (limited to 'lib/base/fsmutex.cpp')
-rw-r--r--lib/base/fsmutex.cpp187
1 files changed, 187 insertions, 0 deletions
diff --git a/lib/base/fsmutex.cpp b/lib/base/fsmutex.cpp
new file mode 100644
index 00000000..06fe2403
--- /dev/null
+++ b/lib/base/fsmutex.cpp
@@ -0,0 +1,187 @@
+/** BEGIN COPYRIGHT BLOCK
+ * Copyright 2001 Sun Microsystems, Inc.
+ * Portions copyright 1999, 2001-2003 Netscape Communications Corporation.
+ * All rights reserved.
+ * END COPYRIGHT BLOCK **/
+/*
+ * fsmutex: Mutexes that are filesystem-based so they're available from more
+ * than one process and address space
+ *
+ * Rob McCool
+ */
+
+#include "base/fsmutex.h"
+#ifdef THREAD_ANY
+#include "base/crit.h"
+#include "base/systhr.h"
+#endif
+
+#include "base/util.h"
+#ifdef XP_WIN32
+typedef HANDLE sys_fsmutex_t;
+#endif
+
+#ifdef XP_UNIX
+#include "base/file.h"
+typedef SYS_FILE sys_fsmutex_t;
+#endif
+
+
+typedef struct {
+ sys_fsmutex_t mutex;
+ char *id;
+#ifdef THREAD_ANY
+ CRITICAL crit;
+#endif
+ int flags;
+} fsmutex_s;
+
+
+
+/* ----------------------------- fsmutex_init ----------------------------- */
+
+
+#ifdef XP_UNIX
+static int
+_fsmutex_create(fsmutex_s *fsm, char *name, int number)
+{
+ char tn[256];
+ SYS_FILE lfd;
+ int visible = (fsm->flags & FSMUTEX_VISIBLE ? 1 : 0);
+
+ util_snprintf(tn, 256, "/tmp/%s.%d", name, number);
+ if(!visible)
+ unlink(tn);
+ if( (lfd = PR_Open(tn, PR_RDWR|PR_CREATE_FILE, 0644)) == NULL)
+ return -1;
+
+ if(!visible)
+ unlink(tn);
+ else
+ fsm->id = PERM_STRDUP(tn);
+ fsm->mutex = lfd;
+ return 0;
+}
+#endif
+
+#ifdef XP_WIN32
+static int
+_fsmutex_create(fsmutex_s *fsm, char *name, int number)
+{
+ char tn[256];
+ util_snprintf(tn, sizeof(tn), "%s.%d", name, number);
+
+ fsm->id = NULL;
+ fsm->mutex = CreateMutex(NULL, FALSE,
+ (fsm->flags & FSMUTEX_VISIBLE ? tn : NULL));
+ return (fsm->mutex ? 0 : -1);
+}
+#endif
+
+NSAPI_PUBLIC FSMUTEX
+fsmutex_init(char *name, int number, int flags)
+{
+ fsmutex_s *ret = (fsmutex_s *) PERM_MALLOC(sizeof(fsmutex_s));
+
+ ret->flags = flags;
+ if(_fsmutex_create(ret, name, number) == -1) {
+ PERM_FREE(ret);
+ return NULL;
+ }
+#ifdef THREAD_ANY
+ if(flags & FSMUTEX_NEEDCRIT)
+ ret->crit = crit_init();
+#endif
+ return (FSMUTEX) ret;
+}
+
+#ifdef XP_UNIX
+NSAPI_PUBLIC void
+fsmutex_setowner(FSMUTEX fsm, uid_t uid, gid_t gid)
+{
+ if(!geteuid())
+ (void) chown( ((fsmutex_s *)fsm)->id, uid, gid);
+}
+#endif
+
+
+/* -------------------------- fsmutex_terminate --------------------------- */
+
+
+#ifdef XP_UNIX
+static void
+_fsmutex_delete(fsmutex_s *fsm)
+{
+ if(fsm->flags & FSMUTEX_VISIBLE)
+ unlink(fsm->id);
+ PERM_FREE(fsm->id);
+ PR_Close(fsm->mutex);
+}
+#endif
+
+#ifdef XP_WIN32
+static void
+_fsmutex_delete(fsmutex_s *fsm)
+{
+ CloseHandle(fsm->mutex);
+}
+#endif
+
+NSAPI_PUBLIC void
+fsmutex_terminate(FSMUTEX id)
+{
+ fsmutex_s *fsm = (fsmutex_s *) id;
+
+ _fsmutex_delete(fsm);
+#ifdef THREAD_ANY
+ if(fsm->flags & FSMUTEX_NEEDCRIT)
+ crit_terminate(fsm->crit);
+#endif
+ PERM_FREE(fsm);
+}
+
+
+/* ----------------------------- fsmutex_lock ----------------------------- */
+
+
+NSAPI_PUBLIC void
+fsmutex_lock(FSMUTEX id)
+{
+ fsmutex_s *fsm = (fsmutex_s *) id;
+#ifdef THREAD_ANY
+ if(fsm->flags & FSMUTEX_NEEDCRIT)
+ crit_enter(fsm->crit);
+#endif
+#ifdef XP_UNIX
+#ifdef THREAD_NSPR_USER
+ /* Poll to avoid blocking. XXXrobm If errno is wrong this may go awry. */
+ while(system_tlock(fsm->mutex) == -1)
+ systhread_sleep(1000);
+#else
+ system_flock(fsm->mutex );
+#endif
+#endif
+#ifdef XP_WIN32
+ WaitForSingleObject(fsm->mutex, INFINITE);
+#endif
+}
+
+
+/* ---------------------------- fsmutex_unlock ---------------------------- */
+
+
+NSAPI_PUBLIC void
+fsmutex_unlock(FSMUTEX id)
+{
+ fsmutex_s *fsm = (fsmutex_s *) id;
+#ifdef XP_UNIX
+ system_ulock(fsm->mutex);
+#endif
+#ifdef XP_WIN32
+ ReleaseMutex(fsm->mutex);
+#endif
+#ifdef THREAD_ANY
+ if(fsm->flags & FSMUTEX_NEEDCRIT)
+ crit_exit(fsm->crit);
+#endif
+}