示例#1
0
void
AQWAIT(
    _f_int	*aqp,
    _f_int	*status,
    _f_int	*reply)
{
    AQFIL		*f;
    struct fflistreq *nxtq;
    _f_int		dummy, *lreply;

    /*
     *	UNICOS 8.0 and previous quietly permitted fewer than 2 arguments,
     *	even though our documentatiokn for AQWAIT has required >= 2 args
     *	for some time.  Do the service of printing an error message if a
     *	dusty deck code happens to use < 2 arguments.
     */
    if (_numargs() < 2)
        _lerror(_LELVL_ABORT, FEARGCNT, "AQWAIT", _numargs(), "2 or 3");
    /*
     *	reply is an optional argument.
     */
    lreply = reply;
    if (_numargs() < 3) lreply = &dummy;

    f	= (AQFIL *) *aqp;

    if (f == NULL || f->aq_chk != AQ_CHK) {
        *status = -FEAQBADH;    /* file handle is not valid */
        return;
    }

    if (f->aq_busy == f->aq_nxtq) {
        *status = IDLE;
        return;
    }

    *status = OK;

    AQ_LOCK(aq_lkbusy);
    nxtq = f->aq_nxtq;
    _aqwait(f, status, lreply, nxtq);
    AQ_UNLOCK(aq_lkbusy);
    if (*status < 0 && _numargs() <= 1)
        _lerror(_LELVL_ABORT, -(*status));
    return;
}
示例#2
0
void
AQSTAT(
_f_int	*aqp,
_f_int	*reply,
_f_int	*reqid,
_f_int	*status,
_f_int	*wait)
{
	AQFIL		*f;
	struct fflistreq *base, *limit, *ptr, *busy, *eptr;
	struct ffsw	*istat;
	struct ffsw	dumstat;
	int		indx;
	int		ret;
	int		max;
	int		isbusy;

	f	= (AQFIL *) *aqp;

	if (f == NULL || f->aq_chk != AQ_CHK) {
		*status = -FEAQBADH;    /* file handle is not valid */
		return;
	}

	base	= f->aq_base;
	limit	= f->aq_limit;
	max	= limit - base;
/*
 *	Lock the tail of the queue so no one can stomp on the entry for
 *	which we are searching.
 */
	AQ_LOCK(aq_lknxtq);
	AQ_LOCK(aq_lkbusy);		/* don't nobody move */
	busy	= f->aq_busy;
/*
 *	Examine the entire queue, regardless of pointers
 */
	for (indx = 0 ; indx < max ; indx++) {
		if ( f->aq_reqid[indx] == *reqid ) {
			eptr = &base[indx];
			istat = base[indx].li_status;
			ptr = f->aq_ptr;	/* Grab stable copy */
						/* If it moves, that's OK. */
/*
 *			If the user requested that we wait for this one...
 */
			if (_numargs() > 4 && *wait != 0) {
/*
 *				Determine if the entry in question is
 *				between busy and ptr.
 */
				isbusy = NO;
				if (busy <= ptr) {
					if (busy <= eptr && eptr < ptr)
						isbusy = YES;
				}
				else {
					if (eptr < ptr || busy <= eptr)
						isbusy = YES;
				}
/*
 *				Now pointing to entry in question.
 *				Wait for its completion,  if btwn busy and ptr,
 *				Unlock queue head to allow additions
 *				to the queue while waiting.
 */
				AQ_UNLOCK(aq_lknxtq);
/*
 *				If the requested reqid has not been fired,
 *				fire the listio before the wait.
 */
				if (isbusy == NO) {
					_aqcall(f);
				}
				goto finish_io2;
			}
/*
 *			If user did not request wait, just return the status,
 *			but first check to see if it is done.  If it is, Give
 *			the recall routine a shot at cleanup and finish up as
 *			though a wait had been requested.
 */
			if (f->aq_ffio == YES) {
				AQPOLL(eptr, &dumstat);
				if (FFSTAT(*istat) != FFBSY) {
					goto finish_io1;
				}
			}
			else if ( istat->sw_flag != 0 ) {
					goto finish_io1;
			}

/* 
 *			If the entry is found, but not complete, it is
 *			either QUEUED and active or QUEUED and not yet
 *			activated.
 *			If eptr is between busy and ptr, it is active.
 */
			*status = LQUEUED;	/* not yet active */
			if (busy <= ptr) {
				if (busy <= eptr && eptr < ptr)
					/* queued and active */
					*status = QUEUED;
			}
			else {
				if (eptr < ptr || busy <= eptr)
					/* queued and active */
					*status = QUEUED;
			}

			goto done;
		}
	}
	*status = NOTFOUND;

done:
	AQ_UNLOCK(aq_lkbusy);
	AQ_UNLOCK(aq_lknxtq);
	return;

finish_io1:
	AQ_UNLOCK(aq_lknxtq);

finish_io2:
/*
 *	Do the 'recall' on the request.
 */
	ret = _aqrcl(f, eptr);
/*
 *	The request is now done.  Now that we are about to return the status
 *	of the request, check if this entry is at tail of queue.
 *	If the request is at the tail of the queue free up the entry.
 *	This is probably silly.
 */
	if (f->aq_busy == eptr)
		INC_QP(f->aq_busy, limit, max);

/*
 *	Set return status
 */
	*status = IOCOMPLETE;
	if (ret != 0)
		{
		*status = -ret;
		if (ret == FERDWRER)
			*reply = eptr->li_status->sw_count;
		}
/*
 *	Flag the status as delivered
 */
	f->aq_told[indx] = 1;	/* mark status as having been sent to user */

	AQ_UNLOCK(aq_lkbusy);

	return;
}
示例#3
0
void
AQRECALL(
    _f_int	*aqp,
    _f_int	*status,
    _f_int	*reqid,
    _f_int	*reply)
{
    AQFIL		*f;
    struct fflistreq *base, *limit, *nxtq, *busy, *eptr;
    int		i;
    int		max;
    int		inside;

    if (_numargs() < 4)
        _lerror(_LELVL_ABORT, FEARGCNT, "AQRECALL", _numargs(), "4");

    f	= (AQFIL *) *aqp;

    if (f == NULL || f->aq_chk != AQ_CHK) {
        *status = -FEAQBADH;    /* file handle is not valid */
        return;
    }

    base	= f->aq_base;
    limit	= f->aq_limit;
    max	= limit - base;
    /*
     *	Lock the tail of the queue so no one can stomp on the entry for
     *	which we are searching.
     */
    AQ_LOCK(aq_lkbusy);
    busy	= f->aq_busy;
    /*
     *	Examine the entire queue, regardless of pointers
     */
    for (i = 0 ; i < max ; i++) {
        if ( f->aq_reqid[i] == *reqid ) {
            eptr = &base[i];
            /*
             *			Determine if the entry in question is
             *			between busy and nxtq.
             */
            nxtq = f->aq_nxtq;	/* Grab stable copy */
            inside = NO;
            if (busy < nxtq) {
                if (busy <= eptr && eptr < nxtq)
                    inside = YES;
            }
            else {
                if (eptr < nxtq || busy <= eptr)
                    inside = YES;
            }
            /*
             *			Now pointing to entry in question.
             *			Wait for its completion,  _aqwait will set status
             *			appropriately.  If not between nxtq and busy,
             *			assume that if we found it, it must be done.
             */
            *status = IOCOMPLETE;
            if (inside) {
                INC_QP(eptr, limit, max);
                _aqwait(f, status, reply, eptr);
            }
            AQ_UNLOCK(aq_lkbusy);

            return;
        }
    }
    AQ_UNLOCK(aq_lkbusy);
    *status = NOTFOUND;
    return;
}