db

mut_fcntl.c

Go to the documentation of this file.
00001 /*-
00002  * See the file LICENSE for redistribution information.
00003  *
00004  * Copyright (c) 1996, 1997, 1998, 1999, 2000
00005  * Sleepycat Software. All rights reserved.
00006  */
00007 
00008 #include "config.h"
00009 
00010 #ifdef HAVE_MUTEX_FCNTL
00011 
00012 #ifndef lint
00013 static const char revid[] = "$Id: mut__fcntl_8c-source.html,v 1.1 2008年06月08日 10:20:55 sebdiaz Exp $";
00014 #endif /* not lint */
00015 
00016 #ifndef NO_SYSTEM_INCLUDES
00017 #include <sys/types.h>
00018 
00019 #include <errno.h>
00020 #include <fcntl.h>
00021 #include <stdlib.h>
00022 #include <string.h>
00023 #include <unistd.h>
00024 #endif
00025 
00026 #include "db_int.h"
00027 
00028 /*
00029  * __db_fcntl_mutex_init --
00030  * Initialize a DB mutex structure.
00031  *
00032  * PUBLIC: int __db_fcntl_mutex_init __P((DB_ENV *, MUTEX *, u_int32_t));
00033  */
00034 int
00035 __db_fcntl_mutex_init(dbenv, mutexp, offset)
00036 DB_ENV *dbenv;
00037 MUTEX *mutexp;
00038 u_int32_t offset;
00039 {
00040 memset(mutexp, 0, sizeof(*mutexp));
00041 
00042 /*
00043  * This is where we decide to ignore locks we don't need to set -- if
00044  * the application is private, we don't need any locks.
00045  */
00046 if (F_ISSET(dbenv, DB_ENV_PRIVATE)) {
00047 F_SET(mutexp, MUTEX_IGNORE);
00048 return (0);
00049 }
00050 
00051 mutexp->off = offset;
00052 
00053 return (0);
00054 }
00055 
00056 /*
00057  * __db_fcntl_mutex_lock
00058  * Lock on a mutex, blocking if necessary.
00059  *
00060  * PUBLIC: int __db_fcntl_mutex_lock __P((MUTEX *, DB_FH *));
00061  */
00062 int
00063 __db_fcntl_mutex_lock(mutexp, fhp)
00064 MUTEX *mutexp;
00065 DB_FH *fhp;
00066 {
00067 struct flock k_lock;
00068 int locked, ms, waited;
00069 
00070 if (!DB_GLOBAL(db_mutexlocks))
00071 return (0);
00072 
00073 /* Initialize the lock. */
00074 k_lock.l_whence = SEEK_SET;
00075 k_lock.l_start = mutexp->off;
00076 k_lock.l_len = 1;
00077 
00078 for (locked = waited = 0;;) {
00079 /*
00080  * Wait for the lock to become available; wait 1ms initially,
00081  * up to 1 second.
00082  */
00083 for (ms = 1; mutexp->pid != 0;) {
00084 waited = 1;
00085 CDB___os_yield(NULL, ms * USEC_PER_MS);
00086 if ((ms <<= 1) > MS_PER_SEC)
00087 ms = MS_PER_SEC;
00088 }
00089 
00090 /* Acquire an exclusive kernel lock. */
00091 k_lock.l_type = F_WRLCK;
00092 if (fcntl(fhp->fd, F_SETLKW, &k_lock))
00093 return (CDB___os_get_errno());
00094 
00095 /* If the resource is still available, it's ours. */
00096 if (mutexp->pid == 0) {
00097 locked = 1;
00098 mutexp->pid = (u_int32_t)getpid();
00099 }
00100 
00101 /* Release the kernel lock. */
00102 k_lock.l_type = F_UNLCK;
00103 if (fcntl(fhp->fd, F_SETLK, &k_lock))
00104 return (CDB___os_get_errno());
00105 
00106 /*
00107  * If we got the resource lock we're done.
00108  *
00109  * !!!
00110  * We can't check to see if the lock is ours, because we may
00111  * be trying to block ourselves in the lock manager, and so
00112  * the holder of the lock that's preventing us from getting
00113  * the lock may be us! (Seriously.)
00114  */
00115 if (locked)
00116 break;
00117 }
00118 
00119 if (waited)
00120 ++mutexp->mutex_set_wait;
00121 else
00122 ++mutexp->mutex_set_nowait;
00123 return (0);
00124 }
00125 
00126 /*
00127  * __db_fcntl_mutex_unlock --
00128  * Release a lock.
00129  *
00130  * PUBLIC: int __db_fcntl_mutex_unlock __P((MUTEX *));
00131  */
00132 int
00133 __db_fcntl_mutex_unlock(mutexp)
00134 MUTEX *mutexp;
00135 {
00136 if (!DB_GLOBAL(db_mutexlocks))
00137 return (0);
00138 
00139 #ifdef DIAGNOSTIC
00140 #define MSG "mutex_unlock: ERROR: released lock that was unlocked\n"
00141 #ifndef STDERR_FILENO
00142 #define STDERR_FILENO 2
00143 #endif
00144 if (mutexp->pid == 0)
00145 write(STDERR_FILENO, MSG, sizeof(MSG) - 1);
00146 #endif
00147 
00148 /*
00149  * Release the resource. We don't have to acquire any locks because
00150  * processes trying to acquire the lock are checking for a pid set to
00151  * 0/non-0, not to any specific value.
00152  */
00153 mutexp->pid = 0;
00154 
00155 return (0);
00156 }
00157 
00158 #endif /* HAVE_MUTEX_FCNTL */

Generated on Sun Jun 8 10:56:38 2008 for GNUmifluz by doxygen 1.5.5

AltStyle によって変換されたページ (->オリジナル) /