DataMuseum.dk

Presents historical artifacts from the history of:

DKUUG/EUUG Conference tapes

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about DKUUG/EUUG Conference tapes

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - metrics - download
Index: T r

⟦819ae2d6b⟧ TextFile

    Length: 10607 (0x296f)
    Types: TextFile
    Names: »rywait.c«

Derivation

└─⟦3d0c2be1b⟧ Bits:30001254 ISODE-5.0 Tape
    └─⟦eba4602b1⟧ »./isode-5.0.tar.Z« 
        └─⟦d3ac74d73⟧ 
            └─⟦this⟧ »isode-5.0/rosy/rywait.c« 

TextFile

/* rywait.c - ROSY: wait */

#ifndef	lint
static char *rcsid = "$Header: /f/osi/rosy/RCS/rywait.c,v 6.0 89/03/18 23:42:59 mrose Rel $";
#endif

/* 
 * $Header: /f/osi/rosy/RCS/rywait.c,v 6.0 89/03/18 23:42:59 mrose Rel $
 *
 *
 * $Log:	rywait.c,v $
 * Revision 6.0  89/03/18  23:42:59  mrose
 * Release 5.0
 * 
 */

/*
 *				  NOTICE
 *
 *    Acquisition, use, and distribution of this module and related
 *    materials are subject to the restrictions of a license agreement.
 *    Consult the Preface in the User's Manual for the full terms of
 *    this agreement.
 *
 */


/* LINTLIBRARY */

#include <stdio.h>
#include "rosy.h"


#define	missingP(p) \
{ \
    if (p == NULL) \
	return rosaplose (roi, ROS_PARAMETER, NULLCP, \
			    "mandatory parameter \"%s\" missing", "p"); \
}

/* \f

   WAIT */

int	RyWait (sd, id, out, secs, roi)
int	sd,
       *id,
	secs;
caddr_t *out;
struct RoSAPindication *roi;
{
    int     reason,
	    result;
    register struct opsblk *opb;

#ifdef	notdef
    missingP (out);
#endif
    missingP (roi);

    if (id) {
	if ((opb = findopblk (sd, *id, OPB_INITIATOR)) == NULLOPB)
	    return rosaplose (roi, ROS_PARAMETER, NULLCP,
		    "invocation %d not in progress on association %d",
		    *id, sd);
    }
    else
	opb = firstopblk (sd);

    if (out && opb && (opb -> opb_flags & OPB_EVENT)) {
	*out = opb -> opb_out;
	*roi = opb -> opb_event;	/* struct copy */
	opb -> opb_out = NULL;
	freeopblk (opb);

	return OK;
    }

    if (!id)
	opb = NULLOPB;

    switch (result = RoWaitRequest (sd, secs, roi)) {
	case NOTOK:
	    reason = roi -> roi_preject.rop_reason;
	    if (ROS_FATAL (reason))
		loseopblk (sd, reason);
	    break;

	case DONE: 
	    loseopblk (sd, ROS_IP_RELEASE);
	    break;

	case OK: 
	    result = RyWaitAux (sd, opb, out, secs, roi);
	    break;

	default: 
	    result = rosaplose (roi, ROS_PROTOCOL, NULLCP,
		    "unknown return from RoWaitRequest=%d", result);
	    break;
    }

    return result;
}

/* \f

 */

int	RyWaitAux (sd, opb, out, secs, roi)
int	sd;
register struct opsblk *opb;
int	secs;
caddr_t *out;
struct RoSAPindication *roi;
{
    int     id,
	    reason,
	    result;
    char   *cp;
    caddr_t in;
    register struct dspblk *dsb;
    register struct opsblk *op2;
    register struct RyError **rye;
    register struct RyOperation *ryo;

    missingP (roi);

    if (out)
	*out = NULL;

    for (;;) {
	switch (roi -> roi_type) {
	    case ROI_INVOKE: {
		struct RoSAPinvoke roxs;
		register struct RoSAPinvoke *rox = &roxs;

		*rox = roi -> roi_invoke;	/* struct copy */

		if (op2 = findopblk (sd, rox -> rox_id, OPB_RESPONDER)) {
		    (void) rosaplose (roi, result = ROS_IP_DUP, NULLCP,
				"duplicate invocation %d", rox -> rox_id);

bad_request: ;
		    (void) RoURejectRequest (sd, &rox -> rox_id, result,
				ROS_NOPRIO, roi);
		    ROXFREE (rox);

		    if (opb == NULLOPB)
			return NOTOK;
		    goto next;
		}

		if ((dsb = finddsblk (sd, rox -> rox_op)) == NULLDSB
			&& (dsb = finddsblk (NOTOK, rox -> rox_op))
				== NULLDSB) {
		    (void) rosaplose (roi, result = ROS_IP_UNRECOG, NULLCP,
				"unexpected invocation %d of operation %d",
				rox -> rox_id, rox -> rox_op);
		    goto bad_request;
		}
		
		ryo = dsb -> dsb_ryo;
		in = NULL;
		if (rox -> rox_args) {
		    if (!ryo -> ryo_arg_decode) {	/* XXX: MISTYPED? */
			(void) rosaplose (roi, result = ROS_IP_MISTYPED,
				NULLCP,
				"unexpected argument for invocation %d of operation %s/%d",
				rox -> rox_id, ryo -> ryo_name, ryo -> ryo_op);
			goto bad_request;
		    }

		    if ((*ryo -> ryo_arg_decode) (rox -> rox_args, 1, NULLIP,
			    NULLVP, &in) == NOTOK) {
			(void) rosaplose (roi, result = ROS_IP_MISTYPED,
				NULLCP,
				"mistyped argument for invocation %d of operation %s/%d",
				rox -> rox_id, ryo -> ryo_name, ryo -> ryo_op);
			goto bad_request;
		    }
		}

		if (ryo -> ryo_result || ryo -> ryo_errors) {
		    if ((op2 = newopblk (sd, rox -> rox_id)) == NULLOPB) {
			(void) rosaplose (roi, result = ROS_IP_LIMIT, NULLCP,
				"unable to allocate opblock for invocation %d of operation %s/%d",
				rox -> rox_id, ryo -> ryo_name, ryo -> ryo_op);
			goto bad_request;
		    }
		    op2 -> opb_flags &= ~OPB_INITIATOR;
		    op2 -> opb_flags |= OPB_RESPONDER;
		    op2 -> opb_ryo = ryo;
		}

		result = (*dsb -> dsb_vector) (sd, ryo, rox, in, roi);
		if (in && ryo -> ryo_arg_free)
		    (void) (*ryo -> ryo_arg_free) (in);
		ROXFREE (rox);
		
		switch (result) {
		    default:
			result = rosaplose (roi, ROS_PROTOCOL, NULLCP,
				"%s invoke dispatch for invoke id %d returns %d",
				ryo -> ryo_name, rox -> rox_id, result);
			/* and fall */
		    case NOTOK:
			if (opb != NULLOPB)
			    break;
		    case DONE:
			return result;

		    case OK:
			break;
		}
		goto next;
	    }

	    case ROI_RESULT: {
		register struct RoSAPresult *ror = &roi -> roi_result;

		if ((op2 = findopblk (sd, ror -> ror_id, OPB_INITIATOR))
			    == NULLOPB
			|| (op2 -> opb_flags & OPB_EVENT)) {
		    (void) RoURejectRequest (sd, &ror -> ror_id,
				ROS_RRP_UNRECOG, ROS_NOPRIO, roi);
		    RORFREE (ror);
		    goto next;
		}

		ryo = op2 -> opb_ryo;
		if (!ryo -> ryo_result) {
		    result = ROS_RRP_UNEXP;

bad_result: ;
		    RORFREE (ror);
		    goto bad_response;
		}

		if (ryo -> ryo_res_decode) {		/* XXX: MISTYPED? */
		    if (!ror -> ror_result) {
			result = ROS_RRP_MISTYPED;
			goto bad_result;
		    }

		    result = (*ryo -> ryo_res_decode) (ror -> ror_result, 1,
				    NULLIP, NULLVP, &op2 -> opb_out);
		    op2 -> opb_free = ryo -> ryo_res_free;
		}
		else {
		    if (ror -> ror_result) {
			result = ROS_RRP_MISTYPED;
			goto bad_result;
		    }

		    result = OK;
		}

		op2 -> opb_pe = ror -> ror_result, ror -> ror_result = NULLPE;
		RORFREE (ror);

		if (result == NOTOK) {
		    result = ROS_RRP_MISTYPED;
		    goto bad_response;
		}

		if (op2 -> opb_resfnx) {
		    result = (*op2 -> opb_resfnx) (sd, op2 -> opb_id,
						   RY_RESULT, op2 -> opb_out,
						   roi);
		    freeopblk (op2);

		    id = ror -> ror_id, cp = "result";
punch: ;
		    switch (result) {
		        default:
			    result = rosaplose (roi, ROS_PROTOCOL, NULLCP,
				        "%s %s dispatch for invoke id %d returns %d",
					ryo -> ryo_name, cp, id, result);
			    /* and fall */
		        case NOTOK:
			    if (opb != NULLOPB)
				break;
		        case DONE:
			    return result;

			case OK:
			    break;
		    }
		    if (opb == op2)
			return OK;
		    goto next;
		}

		if (opb == NULLOPB || opb == op2) {
		    if (out == NULL) {
waiting: ;
			op2 -> opb_flags |= OPB_EVENT;
			op2 -> opb_event = *roi;	/* struct copy */
			return rosaplose (roi, ROS_WAITING, NULLCP, NULLCP);
		    }

		    *out = op2 -> opb_out;
		    op2 -> opb_out = NULL;
		    freeopblk (op2);

		    return OK;
		}

		op2 -> opb_flags |= OPB_EVENT;
		op2 -> opb_event = *roi;	/* struct copy */
		goto next;
	    }

	    case ROI_ERROR: {
		register struct RoSAPerror *roe = &roi -> roi_error;

		if ((op2 = findopblk (sd, roe -> roe_id, OPB_INITIATOR))
			    == NULLOPB
			|| (op2 -> opb_flags & OPB_EVENT)) {
		    (void) RoURejectRequest (sd, &roe -> roe_id,
				ROS_REP_UNRECOG, ROS_NOPRIO, roi);
		    ROEFREE (roe);
		    goto next;
		}

		ryo = op2 -> opb_ryo;
		if (!(rye = ryo -> ryo_errors)) {
		    result = ROS_REP_UNEXP;

bad_error: ;
		    ROEFREE (roe);
		    goto bad_response;
		}
		for (; *rye; rye++)
		    if ((*rye) -> rye_err == roe -> roe_error)
			break;
		if (!*rye) {
		    result = ROS_REP_UNEXPERR;
		    goto bad_error;
		}

		if ((*rye) -> rye_param_decode) {	/* XXX: MISTYPED? */
		    if (!roe -> roe_param) {
			result = ROS_REP_MISTYPED;
			goto bad_error;
		    }

		    result = (*(*rye) -> rye_param_decode) (roe -> roe_param,
				    1, NULLIP, NULLVP, &op2 -> opb_out);
		    op2 -> opb_free = (*rye) -> rye_param_free;
		}
		else {
		    if (roe -> roe_param) {
			result = ROS_REP_MISTYPED;
			goto bad_error;
		    }

		    result = OK;
		}

		op2 -> opb_pe = roe -> roe_param, roe -> roe_param = NULLPE;
		ROEFREE (roe);

		if (result == NOTOK) {
		    result = ROS_REP_MISTYPED;
		    goto bad_response;
		}

		if (op2 -> opb_errfnx) {
		    result = (*op2 -> opb_errfnx) (sd, op2 -> opb_id,
						   roe -> roe_error,
						   op2 -> opb_out, roi);
		    freeopblk (op2);

		    id = roe -> roe_id, cp = "error";
		    goto punch;
		}

		if (opb == NULLOPB || opb == op2) {
		    if (out == NULL)
			goto waiting;
		    *out = op2 -> opb_out;
		    op2 -> opb_out = NULL;
		    freeopblk (op2);

		    return OK;
		}

		op2 -> opb_flags |= OPB_EVENT;
		op2 -> opb_event = *roi;	/* struct copy */
		goto next;
	    }

	    case ROI_UREJECT: {
		register struct RoSAPureject *rou = &roi -> roi_ureject;

		if (rou -> rou_noid)
		    op2 = opb;
		else
		    if ((op2 = findopblk (sd, rou -> rou_id, OPB_INITIATOR))
				== NULLOPB
			    || (op2 -> opb_flags & OPB_EVENT))
			goto next;

		if (op2 -> opb_errfnx) {
		    result = (*op2 -> opb_errfnx) (sd, id = op2 -> opb_id,
						   RY_REJECT,
						   (caddr_t) rou -> rou_reason,
						   roi);
		    freeopblk (op2);

		    cp = "reject";
		    goto punch;
		}

		if (opb == NULLOPB || opb == op2) {
		    freeopblk (op2);

		    return OK;
		}

		op2 -> opb_flags |= OPB_EVENT;
		op2 -> opb_event = *roi;	/* struct copy */
		goto next;
	    }

	    default: 
		return rosaplose (roi, ROS_PROTOCOL, NULLCP,
			"unknown indication type=%d", roi -> roi_type);
	}

bad_response: ;
    {
	register struct RoSAPureject   *rou = &roi -> roi_ureject;

	(void) RoURejectRequest (op2 -> opb_fd, &op2 -> opb_id,
		result, ROS_NOPRIO, roi);

	roi -> roi_type = ROI_UREJECT;
	rou -> rou_id = op2 -> opb_id;
	rou -> rou_noid = 0;
	rou -> rou_reason = result;

	if (op2 -> opb_errfnx) {
	    result = (*op2 -> opb_errfnx) (sd, id = op2 -> opb_id, RY_REJECT,
					   (caddr_t) rou ->rou_reason, roi);

	    freeopblk (op2);

	    cp = "reject";
	    goto punch;
	}

	if (opb == NULLOPB || opb == op2) {
	    freeopblk (op2);

	    return OK;
	}

	op2 -> opb_flags |= OPB_EVENT;
	op2 -> opb_event = *roi;	/* struct copy */
    }
    /* and fall... */

next: 	;
	if (secs != NOTOK)
	    return rosaplose (roi, ROS_TIMER, NULLCP, NULLCP);

	switch (result = RoWaitRequest (sd, NOTOK, roi)) {
	    case NOTOK:
		reason = roi -> roi_preject.rop_reason;
		if (ROS_FATAL (reason))
		    loseopblk (sd, reason);
		break;

	    case DONE:
		loseopblk (sd, ROS_IP_RELEASE);
		break;

	    case OK: 
		continue;

	    default: 
		result = rosaplose (roi, ROS_PROTOCOL, NULLCP,
			"unknown return from RoWaitRequest=%d", result);
		break;
	}

	return result;
    }
}