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