]> git.saurik.com Git - apple/security.git/blame - cdsa/cdsa_utilities/tqueue.h
Security-30.1.tar.gz
[apple/security.git] / cdsa / cdsa_utilities / tqueue.h
CommitLineData
bac41a7b
A
1/*
2 * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
3 *
4 * The contents of this file constitute Original Code as defined in and are
5 * subject to the Apple Public Source License Version 1.2 (the 'License').
6 * You may not use this file except in compliance with the License. Please obtain
7 * a copy of the License at http://www.apple.com/publicsource and read it before
8 * using this file.
9 *
10 * This Original Code and all software distributed under the License are
11 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS
12 * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT
13 * LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
14 * PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see the License for the
15 * specific language governing rights and limitations under the License.
16 */
17
18
19//
20// tqueue.h -- timer queues
21//
22#ifndef _H_TQUEUE
23#define _H_TQUEUE
24
25#include <Security/utilities.h>
26#include <Security/cssmalloc.h>
27#include <Security/debugging.h>
28
29#ifdef _CPP_CDSA_UTILITIES_TQUEUE
30#pragma export on
31#endif
32
33
34namespace Security
35{
36
37//
38// A TimerQueue is a container of elements that have relative "timer" positions.
39// TimerQueues are concerned with shuffling these elements around as their "times"
40// change, and with processing elements that fall off the front of the queue as
41// "time" passes.
42// We put "time" into quotes because nothing here really cares what kind of time
43// you are playing with. It could be seconds, points scored, etc. The only requirement
44// is that "time" doesn't ever flow backwards...
45//
46template <class Time>
47class ScheduleQueue {
48public:
49 ScheduleQueue() { first.fwd = first.back = &first; }
50 virtual ~ScheduleQueue() { }
51
52public:
53 class Event {
54 friend class ScheduleQueue;
55 public:
56 Event() : mScheduled(false) { }
57 ~Event() { if (scheduled()) unschedule(); }
58
59 void unschedule();
60
61 Time when() const { return fireTime; }
62 bool scheduled() const { return mScheduled; }
63
64 private:
65 Time fireTime; // when will it happen?
66 bool mScheduled; // are we scheduled?
67 Event *back, *fwd; // doubly-linked interior list
68
69 void putBefore(Event *ev)
70 { back = ev->back; fwd = ev; ev->back = back->fwd = this; mScheduled = true; }
71 };
72
73public:
74 void schedule(Event *event, Time when);
75 void unschedule(Event *event)
76 { event->unschedule(); }
77
78 bool empty() const { return first.fwd == &first; }
79 Time next() const { assert(!empty()); return first.fwd->fireTime; }
80
81 Event *pop(Time now);
82
83private:
84 Event first; // root of active timers list
85};
86
87template <class Time>
88void ScheduleQueue<Time>::Event::unschedule()
89{
90 assert(mScheduled);
91 back->fwd = fwd; fwd->back = back;
92 mScheduled = false;
93 debug("schedq", "event %p unscheduled", this);
94}
95
96template <class Time>
97inline void ScheduleQueue<Time>::schedule(Event *event, Time when)
98{
99 Event *ev = first.fwd;
100 if (event->scheduled()) {
101 if (when == event->fireTime) // no change
102 return;
103 else if (when > event->fireTime) // forward move
104 ev = event->back;
105 event->unschedule();
106 }
107 event->fireTime = when;
108 // newly schedule the event
109 for (; ev != &first; ev = ev->fwd)
110 if (ev->fireTime > when) {
111 event->putBefore(ev);
112 return;
113 }
114 // hit the end-of-queue; put at end
115 event->putBefore(&first);
116 debug("schedq", "event %p set for %.3f", event, double(when));
117}
118
119template <class Time>
120inline ScheduleQueue<Time>::Event *ScheduleQueue<Time>::pop(Time now)
121{
122 if (!empty()) {
123 Event *top = first.fwd;
124 if (top->fireTime <= now) {
125 top->unschedule();
126 debug("schedq", "event %p delivered at %.3f", top, double(now));
127 return top;
128 }
129 }
130 return NULL;
131}
132
133} // end namespace Security
134
135#ifdef _CPP_CDSA_UTILITIES_TQUEUE
136#pragma export off
137#endif
138
139#endif // _H_TQUEUE