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 <string.h>
00016 #include <stdlib.h>
00017 #endif
00018
00019 #include "db_int.h"
00020 #include "dbinc/db_shash.h"
00021 #include "dbinc/lock.h"
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 int
00035 __lock_set_timeout(dbenv, locker, timeout, op)
00036 DB_ENV *dbenv;
00037 u_int32_t locker;
00038 db_timeout_t timeout;
00039 u_int32_t op;
00040 {
00041 int ret;
00042
00043 LOCK_SYSTEM_LOCK(dbenv);
00044 ret = __lock_set_timeout_internal(dbenv, locker, timeout, op);
00045 LOCK_SYSTEM_UNLOCK(dbenv);
00046 return (ret);
00047 }
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060 int
00061 __lock_set_timeout_internal(dbenv, locker, timeout, op)
00062 DB_ENV *dbenv;
00063 u_int32_t locker;
00064 db_timeout_t timeout;
00065 u_int32_t op;
00066 {
00067 DB_LOCKER *sh_locker;
00068 DB_LOCKREGION *region;
00069 DB_LOCKTAB *lt;
00070 u_int32_t locker_ndx;
00071 int ret;
00072
00073 lt = dbenv->lk_handle;
00074 region = lt->reginfo.primary;
00075
00076 LOCKER_LOCK(lt, region, locker, locker_ndx);
00077 ret = __lock_getlocker(lt, locker, locker_ndx, 1, &sh_locker);
00078
00079 if (ret != 0)
00080 return (ret);
00081
00082 if (op == DB_SET_TXN_TIMEOUT) {
00083 if (timeout == 0)
00084 LOCK_SET_TIME_INVALID(&sh_locker->tx_expire);
00085 else
00086 __lock_expires(dbenv, &sh_locker->tx_expire, timeout);
00087 } else if (op == DB_SET_LOCK_TIMEOUT) {
00088 sh_locker->lk_timeout = timeout;
00089 F_SET(sh_locker, DB_LOCKER_TIMEOUT);
00090 } else if (op == DB_SET_TXN_NOW) {
00091 LOCK_SET_TIME_INVALID(&sh_locker->tx_expire);
00092 __lock_expires(dbenv, &sh_locker->tx_expire, 0);
00093 sh_locker->lk_expire = sh_locker->tx_expire;
00094 if (!LOCK_TIME_ISVALID(®ion->next_timeout) ||
00095 LOCK_TIME_GREATER(
00096 ®ion->next_timeout, &sh_locker->lk_expire))
00097 region->next_timeout = sh_locker->lk_expire;
00098 } else
00099 return (EINVAL);
00100
00101 return (0);
00102 }
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113 int
00114 __lock_inherit_timeout(dbenv, parent, locker)
00115 DB_ENV *dbenv;
00116 u_int32_t parent, locker;
00117 {
00118 DB_LOCKER *parent_locker, *sh_locker;
00119 DB_LOCKREGION *region;
00120 DB_LOCKTAB *lt;
00121 u_int32_t locker_ndx;
00122 int ret;
00123
00124 lt = dbenv->lk_handle;
00125 region = lt->reginfo.primary;
00126 ret = 0;
00127 LOCK_SYSTEM_LOCK(dbenv);
00128
00129
00130 LOCKER_LOCK(lt, region, parent, locker_ndx);
00131 if ((ret = __lock_getlocker(lt,
00132 parent, locker_ndx, 0, &parent_locker)) != 0)
00133 goto err;
00134
00135
00136
00137
00138
00139
00140 if (parent_locker == NULL ||
00141 (LOCK_TIME_ISVALID(&parent_locker->tx_expire) &&
00142 !F_ISSET(parent_locker, DB_LOCKER_TIMEOUT))) {
00143 ret = EINVAL;
00144 goto done;
00145 }
00146
00147 LOCKER_LOCK(lt, region, locker, locker_ndx);
00148 if ((ret = __lock_getlocker(lt,
00149 locker, locker_ndx, 1, &sh_locker)) != 0)
00150 goto err;
00151
00152 sh_locker->tx_expire = parent_locker->tx_expire;
00153
00154 if (F_ISSET(parent_locker, DB_LOCKER_TIMEOUT)) {
00155 sh_locker->lk_timeout = parent_locker->lk_timeout;
00156 F_SET(sh_locker, DB_LOCKER_TIMEOUT);
00157 if (!LOCK_TIME_ISVALID(&parent_locker->tx_expire))
00158 ret = EINVAL;
00159 }
00160
00161 done:
00162 err: LOCK_SYSTEM_UNLOCK(dbenv);
00163 return (ret);
00164 }
00165
00166
00167
00168
00169
00170
00171
00172
00173 void
00174 __lock_expires(dbenv, timevalp, timeout)
00175 DB_ENV *dbenv;
00176 db_timeval_t *timevalp;
00177 db_timeout_t timeout;
00178 {
00179 if (!LOCK_TIME_ISVALID(timevalp))
00180 __os_clock(dbenv, &timevalp->tv_sec, &timevalp->tv_usec);
00181 if (timeout > 1000000) {
00182 timevalp->tv_sec += timeout / 1000000;
00183 timevalp->tv_usec += timeout % 1000000;
00184 } else
00185 timevalp->tv_usec += timeout;
00186
00187 if (timevalp->tv_usec > 1000000) {
00188 timevalp->tv_sec++;
00189 timevalp->tv_usec -= 1000000;
00190 }
00191 }
00192
00193
00194
00195
00196
00197
00198 int
00199 __lock_expired(dbenv, now, timevalp)
00200 DB_ENV *dbenv;
00201 db_timeval_t *now, *timevalp;
00202 {
00203 if (!LOCK_TIME_ISVALID(timevalp))
00204 return (0);
00205
00206 if (!LOCK_TIME_ISVALID(now))
00207 __os_clock(dbenv, &now->tv_sec, &now->tv_usec);
00208
00209 return (now->tv_sec > timevalp->tv_sec ||
00210 (now->tv_sec == timevalp->tv_sec &&
00211 now->tv_usec >= timevalp->tv_usec));
00212 }