/*
 * Copyright (c) 2002-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: qm_ar.c,v 1.39 2006/03/20 23:32:09 ca Exp $")
#include "sm/error.h"
#include "sm/assert.h"
#include "sm/qmgr.h"
#include "sm/qmgr-int.h"
#include "qmgr.h"

/*
**  QMGR_AR -- QMGR - AR interface
**	This runs as a task.
**
**	Parameters:
**		tsk -- evthr task
**
**	Returns:
**		Success: evthread action code
**		Error: usual sm_error code
**
**	Last code review: 2003-10-17 03:23:14, see comments below.
*/

sm_ret_T
qmgr_ar(sm_evthr_task_P tsk)
{
	sm_ret_T ret;

	SM_IS_EVTHR_TSK(tsk);
	QM_LEV_DPRINTFC(QDC_Q2A, 5, (QM_DEBFP, "sev=DBG, func=qmgr_ar, tsk=%p, fd=%d, ev=%#x\n", tsk, tsk->evthr_t_fd, evthr_rqevents(tsk)));
	if (is_valid_fd(tsk->evthr_t_fd))
	{
		/*
		**  Note: The first call is not allowed to put the
		**  task back into the wait queue since then the second
		**  function acts on a "non-locked" tsk.
		**  Moreover, the result of the first call is ignored
		**  if the second function is called too.
		**  Currently qmgr2MOD() only returns
		**  EVTHR_WAITQ and maybe evthr_r_no(EVTHR_EV_WR)
		**  However, the WR event must not be cleared if the
		**  second function puts something back into the RCB list.
		**  We could create a more complicated "merge the return
		**  values" function, or we can simply ignore it for now.
		**  The worst that can happen is that the write function
		**  will be called again just to notice that there is
		**  nothing to write. This will "self adjust" if the read
		**  function won't be called since then the WR event flag
		**  is finally cleared.
		*/

		ret = EVTHR_WAITQ;
		if (evthr_got_wr(tsk))
		{
			ret = qm_to_ar(tsk);	/* XXX check ret here? */
			if (sm_is_err(ret))
				QM_LEV_DPRINTFC(QDC_Q2A, 0, (QM_DEBFP, "sev=ERROR, func=qmgr_ar, where=write, fd=%d, ev=%#x, ret=%r\n", tsk->evthr_t_fd, evthr_rqevents(tsk), ret));
			else
				QM_LEV_DPRINTFC(QDC_Q2A, 5, (QM_DEBFP, "sev=DBG, func=qmgr_ar, where=write, fd=%d, ev=%#x, ret=%r\n", tsk->evthr_t_fd, evthr_rqevents(tsk), ret));
		}
		if (evthr_got_rd(tsk))
			ret = qm_fr_ar(tsk);
		if (sm_is_err(ret))
		{
			QM_LEV_DPRINTFC(QDC_Q2A, 0, (QM_DEBFP, "sev=ERROR, func=qmgr_ar, where=read, fd=%d, ev=%#x, ret=%r\n", tsk->evthr_t_fd, evthr_rqevents(tsk), ret));
			return ret;
		}
		QM_LEV_DPRINTFC(QDC_Q2A, 6, (QM_DEBFP, "sev=DBG, func=qmgr_ar, ret=%r\n", ret));
		return ret;
	}
	return EVTHR_DEL;
}


syntax highlighted by Code2HTML, v. 0.9.1