diff options
author | cvsadm <cvsadm> | 2005-01-21 00:44:34 +0000 |
---|---|---|
committer | cvsadm <cvsadm> | 2005-01-21 00:44:34 +0000 |
commit | b2093e3016027d6b5cf06b3f91f30769bfc099e2 (patch) | |
tree | cf58939393a9032182c4fbc4441164a9456e82f8 /lib/base/fsmutex.cpp | |
download | ds-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.cpp | 187 |
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 +} |