00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include "db_config.h"
00011
00012 #ifndef NO_SYSTEM_INCLUDES
00013 #include <sys/types.h>
00014
00015 #include <fcntl.h>
00016 #include <stdlib.h>
00017 #include <string.h>
00018 #endif
00019
00020 #include "db_int.h"
00021 #include "dbinc/mutex_int.h"
00022
00023
00024
00025
00026
00027
00028
00029 int
00030 __db_fcntl_mutex_init(dbenv, mutex, flags)
00031 DB_ENV *dbenv;
00032 db_mutex_t mutex;
00033 u_int32_t flags;
00034 {
00035 COMPQUIET(dbenv, NULL);
00036 COMPQUIET(mutex, MUTEX_INVALID);
00037 COMPQUIET(flags, 0);
00038
00039 return (0);
00040 }
00041
00042
00043
00044
00045
00046
00047
00048 int
00049 __db_fcntl_mutex_lock(dbenv, mutex)
00050 DB_ENV *dbenv;
00051 db_mutex_t mutex;
00052 {
00053 DB_MUTEX *mutexp;
00054 DB_MUTEXMGR *mtxmgr;
00055 DB_MUTEXREGION *mtxregion;
00056 struct flock k_lock;
00057 int locked, ms, ret;
00058
00059 if (!MUTEX_ON(dbenv) || F_ISSET(dbenv, DB_ENV_NOLOCKING))
00060 return (0);
00061
00062 mtxmgr = dbenv->mutex_handle;
00063 mtxregion = mtxmgr->reginfo.primary;
00064 mutexp = MUTEXP_SET(mutex);
00065
00066 #ifdef HAVE_STATISTICS
00067 if (F_ISSET(mutexp, DB_MUTEX_LOCKED))
00068 ++mutexp->mutex_set_wait;
00069 else
00070 ++mutexp->mutex_set_nowait;
00071 #endif
00072
00073
00074 k_lock.l_whence = SEEK_SET;
00075 k_lock.l_start = mutex;
00076 k_lock.l_len = 1;
00077
00078 for (locked = 0;;) {
00079
00080
00081
00082
00083 for (ms = 1; F_ISSET(mutexp, DB_MUTEX_LOCKED);) {
00084 __os_yield(NULL, ms * USEC_PER_MS);
00085 if ((ms <<= 1) > MS_PER_SEC)
00086 ms = MS_PER_SEC;
00087 }
00088
00089
00090 k_lock.l_type = F_WRLCK;
00091 if (fcntl(dbenv->lockfhp->fd, F_SETLKW, &k_lock))
00092 goto err;
00093
00094
00095 if (!F_ISSET(mutexp, DB_MUTEX_LOCKED)) {
00096 locked = 1;
00097
00098 F_SET(mutexp, DB_MUTEX_LOCKED);
00099 dbenv->thread_id(dbenv, &mutexp->pid, &mutexp->tid);
00100 CHECK_MTX_THREAD(dbenv, mutexp);
00101 }
00102
00103
00104 k_lock.l_type = F_UNLCK;
00105 if (fcntl(dbenv->lockfhp->fd, F_SETLK, &k_lock))
00106 goto err;
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117 if (locked)
00118 break;
00119 }
00120
00121 #ifdef DIAGNOSTIC
00122
00123
00124
00125
00126 if (F_ISSET(dbenv, DB_ENV_YIELDCPU))
00127 __os_yield(NULL, 1);
00128 #endif
00129 return (0);
00130
00131 err: ret = __os_get_errno();
00132 __db_err(dbenv, "fcntl lock failed: %s", db_strerror(ret));
00133 return (__db_panic(dbenv, ret));
00134 }
00135
00136
00137
00138
00139
00140
00141
00142 int
00143 __db_fcntl_mutex_unlock(dbenv, mutex)
00144 DB_ENV *dbenv;
00145 db_mutex_t mutex;
00146 {
00147 DB_MUTEX *mutexp;
00148 DB_MUTEXMGR *mtxmgr;
00149 DB_MUTEXREGION *mtxregion;
00150
00151 if (!MUTEX_ON(dbenv) || F_ISSET(dbenv, DB_ENV_NOLOCKING))
00152 return (0);
00153
00154 mtxmgr = dbenv->mutex_handle;
00155 mtxregion = mtxmgr->reginfo.primary;
00156 mutexp = MUTEXP_SET(mutex);
00157
00158 #ifdef DIAGNOSTIC
00159 if (!F_ISSET(mutexp, DB_MUTEX_LOCKED)) {
00160 __db_err(dbenv, "fcntl unlock failed: lock already unlocked");
00161 return (__db_panic(dbenv, EACCES));
00162 }
00163 #endif
00164
00165
00166
00167
00168
00169
00170
00171 F_CLR(mutexp, DB_MUTEX_LOCKED);
00172
00173 return (0);
00174 }
00175
00176
00177
00178
00179
00180
00181
00182 int
00183 __db_fcntl_mutex_destroy(dbenv, mutex)
00184 DB_ENV *dbenv;
00185 db_mutex_t mutex;
00186 {
00187 COMPQUIET(dbenv, NULL);
00188 COMPQUIET(mutex, MUTEX_INVALID);
00189
00190 return (0);
00191 }