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

lock_failchk.c

00001 /*-
00002  * See the file LICENSE for redistribution information.
00003  *
00004  * Copyright (c) 2005
00005  *      Sleepycat Software.  All rights reserved.
00006  *
00007  * $Id: lock_failchk.c,v 12.3 2005/10/14 15:06:44 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 #include "dbinc/txn.h"
00022 
00023 /*
00024  * __lock_failchk --
00025  *      Check for locks held by dead threads of control.
00026  *
00027  * PUBLIC: int __lock_failchk __P((DB_ENV *));
00028  */
00029 int
00030 __lock_failchk(dbenv)
00031         DB_ENV *dbenv;
00032 {
00033         DB_LOCKER *lip;
00034         DB_LOCKREGION *lrp;
00035         DB_LOCKREQ request;
00036         DB_LOCKTAB *lt;
00037         u_int32_t i;
00038         int ret;
00039         char buf[DB_THREADID_STRLEN];
00040 
00041         lt = dbenv->lk_handle;
00042         lrp = lt->reginfo.primary;
00043 
00044 retry:  LOCK_SYSTEM_LOCK(dbenv);
00045 
00046         ret = 0;
00047         for (i = 0; i < lrp->locker_t_size; i++)
00048                 for (lip =
00049                     SH_TAILQ_FIRST(&lt->locker_tab[i], __db_locker);
00050                     lip != NULL;
00051                     lip = SH_TAILQ_NEXT(lip, links, __db_locker)) {
00052                         /*
00053                          * If the locker is transactional, we can ignore it;
00054                          * __txn_failchk aborts any transactions the locker
00055                          * is involved in.
00056                          */
00057                         if (lip->id >= TXN_MINIMUM)
00058                                 continue;
00059 
00060                         /* If the locker is still alive, it's not a problem. */
00061                         if (dbenv->is_alive(dbenv, lip->pid, lip->tid))
00062                                 continue;
00063 
00064                         /*
00065                          * We can only deal with read locks.  If the locker
00066                          * holds write locks we have to assume a Berkeley DB
00067                          * operation was interrupted with only 1-of-N pages
00068                          * modified.
00069                          */
00070                         if (lip->nwrites != 0) {
00071                                 ret = __db_failed(dbenv,
00072                                      "locker has write locks",
00073                                      lip->pid, lip->tid);
00074                                 break;
00075                         }
00076 
00077                         /*
00078                          * Discard the locker and its read locks.
00079                          */
00080                         __db_msg(dbenv, "Freeing locks for locker %#lx: %s",
00081                             (u_long)lip->id, dbenv->thread_id_string(
00082                             dbenv, lip->pid, lip->tid, buf));
00083                         LOCK_SYSTEM_UNLOCK(dbenv);
00084                         memset(&request, 0, sizeof(request));
00085                         request.op = DB_LOCK_PUT_ALL;
00086                         if ((ret = __lock_vec(
00087                             dbenv, lip->id, 0, &request, 1, NULL)) != 0)
00088                                 return (ret);
00089 
00090                         /*
00091                          * This locker is most likely referenced by a cursor
00092                          * which is owned by a dead thread.  Normally the
00093                          * cursor would be available for other threads
00094                          * but we assume the dead thread will never release
00095                          * it.
00096                          */
00097                         if ((ret = __lock_freefamilylocker(lt, lip->id)) != 0)
00098                                 return (ret);
00099                         goto retry;
00100                 }
00101 
00102         LOCK_SYSTEM_UNLOCK(dbenv);
00103 
00104         return (ret);
00105 }

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