1/*-
2 * See the file LICENSE for redistribution information.
3 *
4 * Copyright (c) 2005,2008 Oracle.  All rights reserved.
5 *
6 * $Id: mut_failchk.c,v 12.8 2008/01/08 20:58:43 bostic Exp $
7 */
8
9#include "db_config.h"
10
11#include "db_int.h"
12#include "dbinc/mutex_int.h"
13
14/*
15 * __mut_failchk --
16 *	Check for mutexes held by dead processes.
17 *
18 * PUBLIC: int __mut_failchk __P((ENV *));
19 */
20int
21__mut_failchk(env)
22	ENV *env;
23{
24	DB_ENV *dbenv;
25	DB_MUTEX *mutexp;
26	DB_MUTEXMGR *mtxmgr;
27	DB_MUTEXREGION *mtxregion;
28	db_mutex_t i;
29	int ret;
30	char buf[DB_THREADID_STRLEN];
31
32	dbenv = env->dbenv;
33	mtxmgr = env->mutex_handle;
34	mtxregion = mtxmgr->reginfo.primary;
35	ret = 0;
36
37	MUTEX_SYSTEM_LOCK(env);
38	for (i = 1; i <= mtxregion->stat.st_mutex_cnt; ++i, ++mutexp) {
39		mutexp = MUTEXP_SET(i);
40
41		/*
42		 * We're looking for per-process mutexes where the process
43		 * has died.
44		 */
45		if (!F_ISSET(mutexp, DB_MUTEX_ALLOCATED) ||
46		    !F_ISSET(mutexp, DB_MUTEX_PROCESS_ONLY))
47			continue;
48
49		/*
50		 * The thread that allocated the mutex may have exited, but
51		 * we cannot reclaim the mutex if the process is still alive.
52		 */
53		if (dbenv->is_alive(
54		    dbenv, mutexp->pid, 0, DB_MUTEX_PROCESS_ONLY))
55			continue;
56
57		__db_msg(env, "Freeing mutex for process: %s",
58		    dbenv->thread_id_string(dbenv, mutexp->pid, 0, buf));
59
60		/* Unlock and free the mutex. */
61		if (F_ISSET(mutexp, DB_MUTEX_LOCKED))
62			MUTEX_UNLOCK(env, i);
63
64		if ((ret = __mutex_free_int(env, 0, &i)) != 0)
65			break;
66	}
67	MUTEX_SYSTEM_UNLOCK(env);
68
69	return (ret);
70}
71