Main Page | Class Hierarchy | Data Structures | Directories | File List | Data Fields | Related Pages

lock_method.c

00001 /*-
00002  * See the file LICENSE for redistribution information.
00003  *
00004  * Copyright (c) 1996-2005
00005  *      Sleepycat Software.  All rights reserved.
00006  *
00007  * $Id: lock_method.c,v 12.6 2005/08/08 14:56:49 bostic Exp $
00008  */
00009 
00010 #include "db_config.h"
00011 
00012 #ifndef NO_SYSTEM_INCLUDES
00013 #include <sys/types.h>
00014 
00015 #include <string.h>
00016 #endif
00017 
00018 #include "db_int.h"
00019 #include "dbinc/db_shash.h"
00020 #include "dbinc/lock.h"
00021 
00022 /*
00023  * __lock_dbenv_create --
00024  *      Lock specific creation of the DB_ENV structure.
00025  *
00026  * PUBLIC: void __lock_dbenv_create __P((DB_ENV *));
00027  */
00028 void
00029 __lock_dbenv_create(dbenv)
00030         DB_ENV *dbenv;
00031 {
00032         /*
00033          * !!!
00034          * Our caller has not yet had the opportunity to reset the panic
00035          * state or turn off mutex locking, and so we can neither check
00036          * the panic state or acquire a mutex in the DB_ENV create path.
00037          */
00038         dbenv->lk_max = DB_LOCK_DEFAULT_N;
00039         dbenv->lk_max_lockers = DB_LOCK_DEFAULT_N;
00040         dbenv->lk_max_objects = DB_LOCK_DEFAULT_N;
00041 }
00042 
00043 /*
00044  * __lock_dbenv_close --
00045  *      Lock specific destruction of the DB_ENV structure.
00046  *
00047  * PUBLIC: int __lock_dbenv_close __P((DB_ENV *));
00048  */
00049 int
00050 __lock_dbenv_close(dbenv)
00051         DB_ENV *dbenv;
00052 {
00053         if (dbenv->lk_conflicts != NULL) {
00054                 __os_free(dbenv, dbenv->lk_conflicts);
00055                 dbenv->lk_conflicts = NULL;
00056         }
00057 
00058         return (0);
00059 }
00060 
00061 /*
00062  * __lock_get_lk_conflicts
00063  *      Get the conflicts matrix.
00064  *
00065  * PUBLIC: int __lock_get_lk_conflicts
00066  * PUBLIC:     __P((DB_ENV *, const u_int8_t **, int *));
00067  */
00068 int
00069 __lock_get_lk_conflicts(dbenv, lk_conflictsp, lk_modesp)
00070         DB_ENV *dbenv;
00071         const u_int8_t **lk_conflictsp;
00072         int *lk_modesp;
00073 {
00074         DB_LOCKTAB *lt;
00075 
00076         ENV_NOT_CONFIGURED(dbenv,
00077             dbenv->lk_handle, "DB_ENV->get_lk_conflicts", DB_INIT_LOCK);
00078 
00079         lt = dbenv->lk_handle;
00080 
00081         if (LOCKING_ON(dbenv)) {
00082                 /* Cannot be set after open, no lock required to read. */
00083                 if (lk_conflictsp != NULL)
00084                         *lk_conflictsp = lt->conflicts;
00085                 if (lk_modesp != NULL)
00086                         *lk_modesp = ((DB_LOCKREGION *)
00087                             (lt->reginfo.primary))->stat.st_nmodes;
00088         } else {
00089                 if (lk_conflictsp != NULL)
00090                         *lk_conflictsp = dbenv->lk_conflicts;
00091                 if (lk_modesp != NULL)
00092                         *lk_modesp = dbenv->lk_modes;
00093         }
00094         return (0);
00095 }
00096 
00097 /*
00098  * __lock_set_lk_conflicts
00099  *      Set the conflicts matrix.
00100  *
00101  * PUBLIC: int __lock_set_lk_conflicts __P((DB_ENV *, u_int8_t *, int));
00102  */
00103 int
00104 __lock_set_lk_conflicts(dbenv, lk_conflicts, lk_modes)
00105         DB_ENV *dbenv;
00106         u_int8_t *lk_conflicts;
00107         int lk_modes;
00108 {
00109         int ret;
00110 
00111         ENV_ILLEGAL_AFTER_OPEN(dbenv, "DB_ENV->set_lk_conflicts");
00112 
00113         if (dbenv->lk_conflicts != NULL) {
00114                 __os_free(dbenv, dbenv->lk_conflicts);
00115                 dbenv->lk_conflicts = NULL;
00116         }
00117         if ((ret = __os_malloc(dbenv,
00118             (size_t)(lk_modes * lk_modes), &dbenv->lk_conflicts)) != 0)
00119                 return (ret);
00120         memcpy(
00121             dbenv->lk_conflicts, lk_conflicts, (size_t)(lk_modes * lk_modes));
00122         dbenv->lk_modes = lk_modes;
00123 
00124         return (0);
00125 }
00126 
00127 /*
00128  * PUBLIC: int __lock_get_lk_detect __P((DB_ENV *, u_int32_t *));
00129  */
00130 int
00131 __lock_get_lk_detect(dbenv, lk_detectp)
00132         DB_ENV *dbenv;
00133         u_int32_t *lk_detectp;
00134 {
00135         DB_LOCKTAB *lt;
00136 
00137         ENV_NOT_CONFIGURED(dbenv,
00138             dbenv->lk_handle, "DB_ENV->get_lk_detect", DB_INIT_LOCK);
00139 
00140         if (LOCKING_ON(dbenv)) {
00141                 lt = dbenv->lk_handle;
00142                 LOCK_SYSTEM_LOCK(dbenv);
00143                 *lk_detectp = ((DB_LOCKREGION *)lt->reginfo.primary)->detect;
00144                 LOCK_SYSTEM_UNLOCK(dbenv);
00145         } else
00146                 *lk_detectp = dbenv->lk_detect;
00147         return (0);
00148 }
00149 
00150 /*
00151  * __lock_set_lk_detect
00152  *      DB_ENV->set_lk_detect.
00153  *
00154  * PUBLIC: int __lock_set_lk_detect __P((DB_ENV *, u_int32_t));
00155  */
00156 int
00157 __lock_set_lk_detect(dbenv, lk_detect)
00158         DB_ENV *dbenv;
00159         u_int32_t lk_detect;
00160 {
00161         DB_LOCKTAB *lt;
00162         DB_LOCKREGION *region;
00163         int ret;
00164 
00165         ENV_NOT_CONFIGURED(dbenv,
00166             dbenv->lk_handle, "DB_ENV->set_lk_detect", DB_INIT_LOCK);
00167 
00168         switch (lk_detect) {
00169         case DB_LOCK_DEFAULT:
00170         case DB_LOCK_EXPIRE:
00171         case DB_LOCK_MAXLOCKS:
00172         case DB_LOCK_MAXWRITE:
00173         case DB_LOCK_MINLOCKS:
00174         case DB_LOCK_MINWRITE:
00175         case DB_LOCK_OLDEST:
00176         case DB_LOCK_RANDOM:
00177         case DB_LOCK_YOUNGEST:
00178                 break;
00179         default:
00180                 __db_err(dbenv,
00181             "DB_ENV->set_lk_detect: unknown deadlock detection mode specified");
00182                 return (EINVAL);
00183         }
00184 
00185         ret = 0;
00186         if (LOCKING_ON(dbenv)) {
00187                 lt = dbenv->lk_handle;
00188                 region = lt->reginfo.primary;
00189                 LOCK_SYSTEM_LOCK(dbenv);
00190                 /*
00191                  * Check for incompatible automatic deadlock detection requests.
00192                  * There are scenarios where changing the detector configuration
00193                  * is reasonable, but we disallow them guessing it is likely to
00194                  * be an application error.
00195                  *
00196                  * We allow applications to turn on the lock detector, and we
00197                  * ignore attempts to set it to the default or current value.
00198                  */
00199                 if (region->detect != DB_LOCK_NORUN &&
00200                     lk_detect != DB_LOCK_DEFAULT &&
00201                     region->detect != lk_detect) {
00202                         __db_err(dbenv,
00203             "DB_ENV->set_lk_detect: incompatible deadlock detector mode");
00204                         ret = EINVAL;
00205                 } else
00206                         if (region->detect == DB_LOCK_NORUN)
00207                                 region->detect = lk_detect;
00208                 LOCK_SYSTEM_UNLOCK(dbenv);
00209         } else
00210                 dbenv->lk_detect = lk_detect;
00211 
00212         return (ret);
00213 }
00214 
00215 /*
00216  * __lock_set_lk_max
00217  *      DB_ENV->set_lk_max.
00218  *
00219  * PUBLIC: int __lock_set_lk_max __P((DB_ENV *, u_int32_t));
00220  */
00221 int
00222 __lock_set_lk_max(dbenv, lk_max)
00223         DB_ENV *dbenv;
00224         u_int32_t lk_max;
00225 {
00226         ENV_ILLEGAL_AFTER_OPEN(dbenv, "DB_ENV->set_lk_max");
00227 
00228         dbenv->lk_max = lk_max;
00229         dbenv->lk_max_objects = lk_max;
00230         dbenv->lk_max_lockers = lk_max;
00231         return (0);
00232 }
00233 
00234 /*
00235  * PUBLIC: int __lock_get_lk_max_locks __P((DB_ENV *, u_int32_t *));
00236  */
00237 int
00238 __lock_get_lk_max_locks(dbenv, lk_maxp)
00239         DB_ENV *dbenv;
00240         u_int32_t *lk_maxp;
00241 {
00242         ENV_NOT_CONFIGURED(dbenv,
00243             dbenv->lk_handle, "DB_ENV->get_lk_maxlocks", DB_INIT_LOCK);
00244 
00245         if (LOCKING_ON(dbenv)) {
00246                 /* Cannot be set after open, no lock required to read. */
00247                 *lk_maxp = ((DB_LOCKREGION *)((DB_LOCKTAB *)
00248                     dbenv->lk_handle)->reginfo.primary)->stat.st_maxlocks;
00249         } else
00250                 *lk_maxp = dbenv->lk_max;
00251         return (0);
00252 }
00253 
00254 /*
00255  * __lock_set_lk_max_locks
00256  *      DB_ENV->set_lk_max_locks.
00257  *
00258  * PUBLIC: int __lock_set_lk_max_locks __P((DB_ENV *, u_int32_t));
00259  */
00260 int
00261 __lock_set_lk_max_locks(dbenv, lk_max)
00262         DB_ENV *dbenv;
00263         u_int32_t lk_max;
00264 {
00265         ENV_ILLEGAL_AFTER_OPEN(dbenv, "DB_ENV->set_lk_max_locks");
00266 
00267         dbenv->lk_max = lk_max;
00268         return (0);
00269 }
00270 
00271 /*
00272  * PUBLIC: int __lock_get_lk_max_lockers __P((DB_ENV *, u_int32_t *));
00273  */
00274 int
00275 __lock_get_lk_max_lockers(dbenv, lk_maxp)
00276         DB_ENV *dbenv;
00277         u_int32_t *lk_maxp;
00278 {
00279         ENV_NOT_CONFIGURED(dbenv,
00280             dbenv->lk_handle, "DB_ENV->get_lk_max_lockers", DB_INIT_LOCK);
00281 
00282         if (LOCKING_ON(dbenv)) {
00283                 /* Cannot be set after open, no lock required to read. */
00284                 *lk_maxp = ((DB_LOCKREGION *)((DB_LOCKTAB *)
00285                     dbenv->lk_handle)->reginfo.primary)->stat.st_maxlockers;
00286         } else
00287                 *lk_maxp = dbenv->lk_max_lockers;
00288         return (0);
00289 }
00290 
00291 /*
00292  * __lock_set_lk_max_lockers
00293  *      DB_ENV->set_lk_max_lockers.
00294  *
00295  * PUBLIC: int __lock_set_lk_max_lockers __P((DB_ENV *, u_int32_t));
00296  */
00297 int
00298 __lock_set_lk_max_lockers(dbenv, lk_max)
00299         DB_ENV *dbenv;
00300         u_int32_t lk_max;
00301 {
00302         ENV_ILLEGAL_AFTER_OPEN(dbenv, "DB_ENV->set_lk_max_lockers");
00303 
00304         dbenv->lk_max_lockers = lk_max;
00305         return (0);
00306 }
00307 
00308 /*
00309  * PUBLIC: int __lock_get_lk_max_objects __P((DB_ENV *, u_int32_t *));
00310  */
00311 int
00312 __lock_get_lk_max_objects(dbenv, lk_maxp)
00313         DB_ENV *dbenv;
00314         u_int32_t *lk_maxp;
00315 {
00316         ENV_NOT_CONFIGURED(dbenv,
00317             dbenv->lk_handle, "DB_ENV->get_lk_max_objects", DB_INIT_LOCK);
00318 
00319         if (LOCKING_ON(dbenv)) {
00320                 /* Cannot be set after open, no lock required to read. */
00321                 *lk_maxp = ((DB_LOCKREGION *)((DB_LOCKTAB *)
00322                     dbenv->lk_handle)->reginfo.primary)->stat.st_maxobjects;
00323         } else
00324                 *lk_maxp = dbenv->lk_max_objects;
00325         return (0);
00326 }
00327 
00328 /*
00329  * __lock_set_lk_max_objects
00330  *      DB_ENV->set_lk_max_objects.
00331  *
00332  * PUBLIC: int __lock_set_lk_max_objects __P((DB_ENV *, u_int32_t));
00333  */
00334 int
00335 __lock_set_lk_max_objects(dbenv, lk_max)
00336         DB_ENV *dbenv;
00337         u_int32_t lk_max;
00338 {
00339         ENV_ILLEGAL_AFTER_OPEN(dbenv, "DB_ENV->set_lk_max_objects");
00340 
00341         dbenv->lk_max_objects = lk_max;
00342         return (0);
00343 }
00344 
00345 /*
00346  * PUBLIC: int __lock_get_env_timeout
00347  * PUBLIC:     __P((DB_ENV *, db_timeout_t *, u_int32_t));
00348  */
00349 int
00350 __lock_get_env_timeout(dbenv, timeoutp, flag)
00351         DB_ENV *dbenv;
00352         db_timeout_t *timeoutp;
00353         u_int32_t flag;
00354 {
00355         DB_LOCKTAB *lt;
00356         DB_LOCKREGION *region;
00357         int ret;
00358 
00359         ENV_NOT_CONFIGURED(dbenv,
00360             dbenv->lk_handle, "DB_ENV->get_env_timeout", DB_INIT_LOCK);
00361 
00362         ret = 0;
00363         if (LOCKING_ON(dbenv)) {
00364                 lt = dbenv->lk_handle;
00365                 region = lt->reginfo.primary;
00366                 LOCK_SYSTEM_LOCK(dbenv);
00367                 switch (flag) {
00368                 case DB_SET_LOCK_TIMEOUT:
00369                         *timeoutp = region->lk_timeout;
00370                         break;
00371                 case DB_SET_TXN_TIMEOUT:
00372                         *timeoutp = region->tx_timeout;
00373                         break;
00374                 default:
00375                         ret = 1;
00376                         break;
00377                 }
00378                 LOCK_SYSTEM_UNLOCK(dbenv);
00379         } else
00380                 switch (flag) {
00381                 case DB_SET_LOCK_TIMEOUT:
00382                         *timeoutp = dbenv->lk_timeout;
00383                         break;
00384                 case DB_SET_TXN_TIMEOUT:
00385                         *timeoutp = dbenv->tx_timeout;
00386                         break;
00387                 default:
00388                         ret = 1;
00389                         break;
00390                 }
00391 
00392         if (ret)
00393                 ret = __db_ferr(dbenv, "DB_ENV->get_timeout", 0);
00394 
00395         return (ret);
00396 }
00397 
00398 /*
00399  * __lock_set_env_timeout
00400  *      DB_ENV->set_lock_timeout.
00401  *
00402  * PUBLIC: int __lock_set_env_timeout __P((DB_ENV *, db_timeout_t, u_int32_t));
00403  */
00404 int
00405 __lock_set_env_timeout(dbenv, timeout, flags)
00406         DB_ENV *dbenv;
00407         db_timeout_t timeout;
00408         u_int32_t flags;
00409 {
00410         DB_LOCKTAB *lt;
00411         DB_LOCKREGION *region;
00412         int ret;
00413 
00414         ENV_NOT_CONFIGURED(dbenv,
00415             dbenv->lk_handle, "DB_ENV->set_env_timeout", DB_INIT_LOCK);
00416 
00417         ret = 0;
00418         if (LOCKING_ON(dbenv)) {
00419                 lt = dbenv->lk_handle;
00420                 region = lt->reginfo.primary;
00421                 LOCK_SYSTEM_LOCK(dbenv);
00422                 switch (flags) {
00423                 case DB_SET_LOCK_TIMEOUT:
00424                         region->lk_timeout = timeout;
00425                         break;
00426                 case DB_SET_TXN_TIMEOUT:
00427                         region->tx_timeout = timeout;
00428                         break;
00429                 default:
00430                         ret = 1;
00431                         break;
00432                 }
00433                 LOCK_SYSTEM_UNLOCK(dbenv);
00434         } else
00435                 switch (flags) {
00436                 case DB_SET_LOCK_TIMEOUT:
00437                         dbenv->lk_timeout = timeout;
00438                         break;
00439                 case DB_SET_TXN_TIMEOUT:
00440                         dbenv->tx_timeout = timeout;
00441                         break;
00442                 default:
00443                         ret = 1;
00444                         break;
00445                 }
00446 
00447         if (ret)
00448                 ret = __db_ferr(dbenv, "DB_ENV->set_timeout", 0);
00449 
00450         return (ret);
00451 }

Generated on Sun Dec 25 12:14:40 2005 for Berkeley DB 4.4.16 by  doxygen 1.4.2