/*
 * @COPYRIGHT@
 *
 * x-kernel v3.3
 *
 * Copyright (c) 1993,1991,1990,1996  Arizona Board of Regents
 *
 * @COPYRIGHT@
 *
 * $RCSfile: scout_queue.c,v $
 *
 * HISTORY
 * $Log: scout_queue.c,v $
 * Revision 1.3  1996/02/01 15:20:28  slm
 * Updated copyright and version.
 *
 * Revision 1.2  1995/08/28  16:14:27  acb
 * Initial revision for x3.3
 *
 * Revision 1.1  1994/10/26  20:03:13  hkaram
 * Initial revision
 *
 * Revision 1.1  1994/05/14  23:55:00  davidm
 * Initial revision
 *
 */
/*
 * General queue manager.  It is not safe for asynchronous usage.
 */
#include "xk_assert.h"
#include "scout_queue.h"


typedef struct scout_queue_link Link;


void
scout_queue_init(Scout_Queue *q)
{
    q->head = q->tail = (void*) 0;
} /* scout_queue_init */


void
scout_queue_append(Scout_Queue *q, void *element)
{
    Link *el = element;

    xAssert(element);

    el->next = 0;
    if (q->tail) {
	q->tail->next = el;
    } /* if */
    q->tail = el;
    if (!q->head) {
	q->head = el;
    } /* if */
} /* scout_queue_append */


void
scout_queue_insert(Scout_Queue *q, void *after_element, void *element)
{
    Link *after = after_element;
    Link *el = element;

    xAssert(element && after_element);

    if (after) {
	el->next = after->next;
	after->next = el;
	if (q->tail == after) {
	    q->tail = el;
	} /* if */
    } else {
	/* insert at head of queue: */
	if (q->head) {
	    el->next = q->head->next;
	} /* if */
	q->head = el;
	if (!q->tail) {
	    q->tail = el;
	} /* if */
    } /* if */
} /* scout_queue_insert */


void*
scout_queue_remove(Scout_Queue *q)
{
    Link *el;

    if (!q->head) {
	/* cannot remove from empty queue: */
	return 0;
    } /* if */

    el = q->head;
    q->head = el->next;

    if (!q->head) {
	q->tail = 0;
    } /* if */
    return el;
} /* scout_queue_remove */


void
scout_queue_delete(Scout_Queue *q, void *after_element)
{
    Link *after = after_element;
    Link *el;

    xAssert(after_element);

    if (after) {
	el = after->next;
	if (el) {
	    after->next = el->next;
	    if (q->tail == el) {
		q->tail = after;
	    } /* if */
	} /* if */
    } else {
	/* remove first element in queue: */
	if (q->head) {
	    q->head = q->head->next;
	    if (!q->head) {
		q->tail = 0;
	    } /* if */
	} /* if */
    } /* if */
} /* scout_queue_delete */

			/*** end of scout_queue.c ***/
