00001
00002
00003
00004
00005
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
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
00030
00031
00032
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
00044
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
00058
00059
00060
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
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
00081
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
00091 k_lock.l_type = F_WRLCK;
00092 if (fcntl(fhp->fd, F_SETLKW, &k_lock))
00093 return (CDB___os_get_errno());
00094
00095
00096 if (mutexp->pid == 0) {
00097 locked = 1;
00098 mutexp->pid = (u_int32_t)getpid();
00099 }
00100
00101
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
00108
00109
00110
00111
00112
00113
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
00128
00129
00130
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
00150
00151
00152
00153 mutexp->pid = 0;
00154
00155 return (0);
00156 }
00157
00158 #endif