/*
 * Copyright (c) 2004, 2005 Sendmail, Inc. and its suppliers.
 *      All rights reserved.
 *
 * By using this file, you agree to the terms and conditions set
 * forth in the LICENSE file which can be found at the top level of
 * the sendmail distribution.
 */

#include "sm/generic.h"
SM_RCSID("@(#)$Id: edbchkpt.c,v 1.8 2006/03/13 18:41:32 ca Exp $")
#include "sm/error.h"
#include "sm/assert.h"
#include "sm/edb.h"
#include "edb-int.h"
#include "sm/pthread.h"

/*
**  EDB_CHKPT -- maintainance operation for deferred envelope database on disk
**
**	Parameters:
**		edb_ctx -- pointer to EDB context
**
**	Returns:
**		usual sm_error code; SM_NOTDONE, (un)lock
**
**	Locking: tries to lock edb, returns if not possible
**
**	Last code review: 2005-04-10 18:28:38
**	Last code change: 2005-04-10 18:28:35
*/

sm_ret_T
edb_chkpt(edb_ctx_P edb_ctx)
{
	int r, ret;
	bool done;

	SM_IS_EDB_CTX(edb_ctx);

	/*
	**  Should this get a locktype parameter?
	**  Enhance locktype by "try only"?
	*/

	done = false;
	ret = SM_SUCCESS;
	r = pthread_mutex_trylock(&edb_ctx->edb_mutex);
	if (r == EBUSY)
		return SM_NOTDONE;
	if (r != 0)
	{
		/* LOG? */
		return sm_error_perm(SM_EM_EDB, r);
	}

	/* larger threshold? edb_chkpt_kb is checked below. */
	if (edb_ctx->edb_writes > 0
	    && EDBREQL_EMPTY(&edb_ctx->edb_reql_wr))
	{
		/*
		**  txn_checkpoint() performs a checkpoint if:
		**  something has been written after the last one
		**  (edb_writes tests that) and (quote from $BDB/txn/txn.c):
		**  If either kbytes or minutes is non-zero, then only take the
		**  checkpoint if more than "minutes" minutes have passed or if
		**  more than "kbytes" of log data have been written since the
		**  last checkpoint.
		*/

		ret = edb_ctx->edb_bdbenv->txn_checkpoint(edb_ctx->edb_bdbenv,
			edb_ctx->edb_chkpt_kb,
			(uint32_t) (edb_ctx->edb_chkpt_delay / 60), 0);
		if (ret == 0)
		{
			edb_ctx->edb_writes = 0;
			done = true;
		}
	}
	r = pthread_mutex_unlock(&edb_ctx->edb_mutex);
	SM_ASSERT(r == 0);
	if (r != 0 && ret == SM_SUCCESS)
		ret = r;

	return done ? SM_SUCCESS :
		((ret != 0) ? sm_error_perm(SM_EM_EDB, ret) : SM_NOTDONE);
}


syntax highlighted by Code2HTML, v. 0.9.1