/*
 *
 * Copyright 1998-1999, University of Notre Dame.
 * Authors: Jeffrey M. Squyres, Kinis L. Meyer with M. D. McNally 
 *          and Andrew Lumsdaine
 *
 * This file is part of the Notre Dame LAM implementation of MPI.
 *
 * You should have received a copy of the License Agreement for the
 * Notre Dame LAM implementation of MPI along with the software; see
 * the file LICENSE.  If not, contact Office of Research, University
 * of Notre Dame, Notre Dame, IN 46556.
 *
 * Permission to modify the code and to distribute modified code is
 * granted, provided the text of this NOTICE is retained, a notice that
 * the code was modified is included with the above COPYRIGHT NOTICE and
 * with the COPYRIGHT NOTICE in the LICENSE file, and that the LICENSE
 * file is distributed with the modified code.
 *
 * LICENSOR MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED.
 * By way of example, but not limitation, Licensor MAKES NO
 * REPRESENTATIONS OR WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY
 * PARTICULAR PURPOSE OR THAT THE USE OF THE LICENSED SOFTWARE COMPONENTS
 * OR DOCUMENTATION WILL NOT INFRINGE ANY PATENTS, COPYRIGHTS, TRADEMARKS
 * OR OTHER RIGHTS.  
 *
 * Additional copyrights may follow.
 *
 *	Ohio Trollius
 *	Copyright 1997 The Ohio State University
 *	GDB
 *
 *	$Id: do_wait.int.c,v 6.3 1999/06/12 17:11:35 kmeyer1 Exp $
 */

#include <net.h>
#include <typical.h>
#include <terror.h>

/*
 * global functions
 */
void			do_wait_block();
void			do_wait_running();

/*
 * local functions
 */
static void		ack_handler();
static void		to_handler();

/*
 * external functions
 */
extern void		do_ack();
extern void		kio_intr();
extern int		kio_to();

/*
 * local variables
 */
static void		*pto_actual_sv;
static void		(*timeout_fn_sv)();

/*
 *	do_wait_block
 *
 *	Function:	- blocks on message receive while servicing
 *			  interrupts
 *			- if no receive, services one interrupt
 *	Accepts:	- ack socket
 *			- packet descriptor
 *			- timeout function
 *			- timeout value
 */
void
do_wait_block(sd_ack, pnh_packet, timeout_fn, pto_actual)

int			sd_ack;
struct nmsg		*pnh_packet;
void			(*timeout_fn)();
void			*pto_actual;

{
	timeout_fn_sv = timeout_fn;
	pto_actual_sv = pto_actual;

	if (frecv(pnh_packet)) lampanic("lamd (frecv)");

	if (kio_to(pto_actual, pto_actual ? to_handler : (void (*)()) 0))
			lampanic("lamd (kio_to)");

	kio_intr(sd_ack, ack_handler, FALSE);
}

/*
 *	do_wait_running
 *
 *	Function:	- waits for one interrupt and handles it
 *	Accepts:	- ack socket
 *			- timeout function
 *			- timeout value
 *	Returns:	- packet received?
 */
void
do_wait_running(sd_ack, timeout_fn, pto_actual)

int			sd_ack;
void			(*timeout_fn)();
void			*pto_actual;

{
	timeout_fn_sv = timeout_fn;
	pto_actual_sv = pto_actual;

	if (kio_to(pto_actual, pto_actual ? to_handler : (void (*)()) 0))
			lampanic("lamd (kio_to)");

	kio_intr(sd_ack, ack_handler, FALSE);
}

/*
 *	to_handler
 *
 *	Function:	- calls the current timeout handler
 *			- possibly updates the current timeout handler
 *			  and current timeout interval
 */
static void
to_handler()

{
	(*timeout_fn_sv)(&timeout_fn_sv, &pto_actual_sv);

	if (kio_to(pto_actual_sv, pto_actual_sv ? to_handler : (void (*)()) 0))
			lampanic("lamd (kio_to)");
}

/*
 *	ack_handler
 *
 *	Function:	- calls the ack handler
 *			- possibly updates the current timeout handler
 *			  and current timeout interval
 */
static void
ack_handler()

{
	do_ack(&timeout_fn_sv, &pto_actual_sv);

	if (kio_to(pto_actual_sv, pto_actual_sv ? to_handler : (void (*)()) 0))
			lampanic("lamd (kio_to)");
}
