*** dbinc/mp.h 2007-09-28 01:28:25.000000000 +1000 --- dbinc/mp.h 2008-02-14 01:22:09.000000000 +1100 *************** *** 639,644 **** --- 639,647 ---- */ #define MP_TRUNC_RECOVER 0x01 + /* Private flags to DB_MPOOLFILE->close. */ + #define DB_MPOOL_NOLOCK 0x002 /* Already have mpf locked. */ + #if defined(__cplusplus) } #endif *** mp/mp_fopen.c 2007-05-18 03:18:01.000000000 +1000 --- mp/mp_fopen.c 2008-02-12 16:09:42.000000000 +1100 *************** *** 888,894 **** * when we try to flush them. */ deleted = 0; ! MUTEX_LOCK(dbenv, mfp->mutex); if (F_ISSET(dbmfp, MP_MULTIVERSION)) --mfp->multiversion; if (--mfp->mpf_cnt == 0 || LF_ISSET(DB_MPOOL_DISCARD)) { --- 888,895 ---- * when we try to flush them. */ deleted = 0; ! if (!LF_ISSET(DB_MPOOL_NOLOCK)) ! MUTEX_LOCK(dbenv, mfp->mutex); if (F_ISSET(dbmfp, MP_MULTIVERSION)) --mfp->multiversion; if (--mfp->mpf_cnt == 0 || LF_ISSET(DB_MPOOL_DISCARD)) { *************** *** 909,921 **** } } if (mfp->block_cnt == 0) { if ((t_ret = __memp_mf_discard(dbmp, mfp)) != 0 && ret == 0) ret = t_ret; deleted = 1; } } ! if (!deleted) MUTEX_UNLOCK(dbenv, mfp->mutex); done: /* Discard the DB_MPOOLFILE structure. */ --- 910,928 ---- } } if (mfp->block_cnt == 0) { + /* + * We should never discard this mp file if our caller + * is holding the lock on it. See comment in + * __memp_sync_file. + */ + DB_ASSERT(dbenv, !LF_ISSET(DB_MPOOL_NOLOCK)); if ((t_ret = __memp_mf_discard(dbmp, mfp)) != 0 && ret == 0) ret = t_ret; deleted = 1; } } ! if (!deleted && !LF_ISSET(DB_MPOOL_NOLOCK)) MUTEX_UNLOCK(dbenv, mfp->mutex); done: /* Discard the DB_MPOOLFILE structure. */ *** mp/mp_sync.c 2007-06-02 04:32:44.000000000 +1000 --- mp/mp_sync.c 2008-02-12 16:09:42.000000000 +1100 *************** *** 755,761 **** * This is important since we are called with the hash bucket * locked. The mfp will get freed via the cleanup pass. */ ! if (dbmfp != NULL && (t_ret = __memp_fclose(dbmfp, 0)) != 0 && ret == 0) ret = t_ret; --mfp->mpf_cnt; --- 755,762 ---- * This is important since we are called with the hash bucket * locked. The mfp will get freed via the cleanup pass. */ ! if (dbmfp != NULL && ! (t_ret = __memp_fclose(dbmfp, DB_MPOOL_NOLOCK)) != 0 && ret == 0) ret = t_ret; --mfp->mpf_cnt;