windows-nt/Source/XPSP1/NT/net/tcpip/tpipv6/tcpip6/inc/queue.h
2020-09-26 16:20:57 +08:00

101 lines
2.7 KiB
C

// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil -*- (for GNU Emacs)
//
// Copyright (c) 1985-2000 Microsoft Corporation
//
// This file is part of the Microsoft Research IPv6 Network Protocol Stack.
// You should have received a copy of the Microsoft End-User License Agreement
// for this software along with this release; see the file "license.txt".
// If not, please see http://www.research.microsoft.com/msripv6/license.htm,
// or write to Microsoft Research, One Microsoft Way, Redmond, WA 98052-6399.
//
// Abstract:
//
// TCP/UDP queuing definitions.
//
//
// Definition of a queue linkage field.
//
typedef struct Queue {
struct Queue *q_next;
struct Queue *q_prev;
} Queue;
//
// Initialize queue macro.
//
#define INITQ(q) { (q)->q_next = (q);\
(q)->q_prev = (q); }
//
// Macro to check for queue empty.
//
#define EMPTYQ(q) ((q)->q_next == (q))
//
// Place an element onto the end of the queue.
//
#define ENQUEUE(q, e) { (q)->q_prev->q_next = (e);\
(e)->q_prev = (q)->q_prev;\
(q)->q_prev = (e);\
(e)->q_next = (q); }
//
// Remove an element from the head of the queue. This macro assumes the queue
// is not empty. The element is returned as type t, queued through linkage l.
//
#define DEQUEUE(q, ptr, t, l) {\
Queue *__tmp__;\
\
__tmp__ = (q)->q_next;\
(q)->q_next = __tmp__->q_next;\
__tmp__->q_next->q_prev = (q);\
(ptr) = CONTAINING_RECORD(__tmp__, t, l);\
}
//
// Peek at an element at the head of the queue. Return a pointer to it
// without removing anything.
//
#define PEEKQ(q, ptr, t, l) {\
Queue *__tmp__;\
\
__tmp__ = (q)->q_next;\
(ptr) = CONTAINING_RECORD(__tmp__, t, l);\
}
//
// Macro to push an element onto the head of a queue.
//
#define PUSHQ(q, e) { (e)->q_next = (q)->q_next;\
(q)->q_next->q_prev = (e);\
(e)->q_prev = (q);\
(q)->q_next = e; }
//
// Macro to remove an element from the middle of a queue.
//
#define REMOVEQ(q) { (q)->q_next->q_prev = (q)->q_prev;\
(q)->q_prev->q_next = (q)->q_next; }
//
// The following macros define methods for working with queue without
// dequeueing, mostly dealing with Queue structures directly.
//
// Macro to define the end of a Q, used in walking a queue sequentially.
#define QEND(q) (q)
// Macro to get the first on a queue.
#define QHEAD(q) (q)->q_next
// Macro to get a structure, given a queue.
#define QSTRUCT(t, q, l) CONTAINING_RECORD((q), t, l)
// Macro to get the next thing on q queue.
#define QNEXT(q) (q)->q_next