diff options
Diffstat (limited to 'debian/htdig/htdig-3.2.0b6/db/mut_fcntl.c')
-rw-r--r-- | debian/htdig/htdig-3.2.0b6/db/mut_fcntl.c | 158 |
1 files changed, 158 insertions, 0 deletions
diff --git a/debian/htdig/htdig-3.2.0b6/db/mut_fcntl.c b/debian/htdig/htdig-3.2.0b6/db/mut_fcntl.c new file mode 100644 index 00000000..f57987bf --- /dev/null +++ b/debian/htdig/htdig-3.2.0b6/db/mut_fcntl.c @@ -0,0 +1,158 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1996, 1997, 1998, 1999 + * Sleepycat Software. All rights reserved. + */ + +#include "db_config.h" + +#ifdef HAVE_MUTEX_FCNTL + +#ifndef lint +static const char sccsid[] = "@(#)mut_fcntl.c 11.1 (Sleepycat) 7/25/99"; +#endif /* not lint */ + +#ifndef NO_SYSTEM_INCLUDES +#include <sys/types.h> + +#include <errno.h> +#include <fcntl.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#endif + +#include "db_int.h" + +/* + * CDB___db_fcntl_mutex_init -- + * Initialize a DB mutex structure. + * + * PUBLIC: int CDB___db_fcntl_mutex_init __P((DB_ENV *, MUTEX *, u_int32_t)); + */ +int +CDB___db_fcntl_mutex_init(dbenv, mutexp, offset) + DB_ENV *dbenv; + MUTEX *mutexp; + u_int32_t offset; +{ + memset(mutexp, 0, sizeof(*mutexp)); + + /* + * This is where we decide to ignore locks we don't need to set -- if + * the application is private, we don't need any locks. + */ + if (F_ISSET(dbenv, DB_ENV_PRIVATE)) { + F_SET(mutexp, MUTEX_IGNORE); + return (0); + } + + mutexp->off = offset; + + return (0); +} + +/* + * CDB___db_fcntl_mutex_lock + * Lock on a mutex, blocking if necessary. + * + * PUBLIC: int CDB___db_fcntl_mutex_lock __P((MUTEX *, DB_FH *)); + */ +int +CDB___db_fcntl_mutex_lock(mutexp, fhp) + MUTEX *mutexp; + DB_FH *fhp; +{ + struct flock k_lock; + int locked, ms, waited; + + if (!DB_GLOBAL(db_mutexlocks)) + return (0); + + /* Initialize the lock. */ + k_lock.l_whence = SEEK_SET; + k_lock.l_start = mutexp->off; + k_lock.l_len = 1; + + for (locked = waited = 0;;) { + /* + * Wait for the lock to become available; wait 1ms initially, + * up to 1 second. + */ + for (ms = 1; mutexp->pid != 0;) { + waited = 1; + CDB___os_yield(ms * USEC_PER_MS); + if ((ms <<= 1) > MS_PER_SEC) + ms = MS_PER_SEC; + } + + /* Acquire an exclusive kernel lock. */ + k_lock.l_type = F_WRLCK; + if (fcntl(fhp->fd, F_SETLKW, &k_lock)) + return (CDB___os_get_errno()); + + /* If the resource is still available, it's ours. */ + if (mutexp->pid == 0) { + locked = 1; + mutexp->pid = (u_int32_t)getpid(); + } + + /* Release the kernel lock. */ + k_lock.l_type = F_UNLCK; + if (fcntl(fhp->fd, F_SETLK, &k_lock)) + return (CDB___os_get_errno()); + + /* + * If we got the resource lock we're done. + * + * !!! + * We can't check to see if the lock is ours, because we may + * be trying to block ourselves in the lock manager, and so + * the holder of the lock that's preventing us from getting + * the lock may be us! (Seriously.) + */ + if (locked) + break; + } + + if (waited) + ++mutexp->mutex_set_wait; + else + ++mutexp->mutex_set_nowait; + return (0); +} + +/* + * CDB___db_fcntl_mutex_unlock -- + * Release a lock. + * + * PUBLIC: int CDB___db_fcntl_mutex_unlock __P((MUTEX *)); + */ +int +CDB___db_fcntl_mutex_unlock(mutexp) + MUTEX *mutexp; +{ + if (!DB_GLOBAL(db_mutexlocks)) + return (0); + +#ifdef DIAGNOSTIC +#define MSG "mutex_unlock: ERROR: released lock that was unlocked\n" +#ifndef STDERR_FILENO +#define STDERR_FILENO 2 +#endif + if (mutexp->pid == 0) + write(STDERR_FILENO, MSG, sizeof(MSG) - 1); +#endif + + /* + * Release the resource. We don't have to acquire any locks because + * processes trying to acquire the lock are checking for a pid set to + * 0/non-0, not to any specific value. + */ + mutexp->pid = 0; + + return (0); +} + +#endif /* HAVE_MUTEX_FCNTL */ |