1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174
|
<copyright> TOO RunLoop.
Written by <a href="mailto:tiggr@ics.ele.tue.nl">Pieter J. Schoenmakers</a>
Copyright (C) 1996 Pieter J. Schoenmakers.
This file is part of TOM. TOM is distributed under the terms of the
TOM License, a copy of which can be found in the TOM distribution; see
the file LICENSE.
<id>$Id: RunLoop.t,v 1.14 1998/05/07 21:20:14 tiggr Exp $</id>
</copyright>
// The advantage of MACH _message_-based IPC is that multiple threads can
// wait on the same port-set. This can not be done with TCP runloops as
// implemented here, i.e. on _stream_-based IPC.
// Sat Mar 29 01:30:09 1997, tiggr@tricky.es.ele.tue.nl
implementation class
RunLoop: State
{
<doc> This thread's run loop. </doc>
local static instance (id) current;
}
<doc> Return this thread's {RunLoop}, creating it if it does not yet
exist. </doc>
instance (id)
current
{
if (!current)
current = [self new];
= current;
}
end;
implementation instance
RunLoop
{
<doc> The read and write sets. </doc>
DescriptorSet read_set, write_set;
<doc> The timers scheduled with us. </doc>
Heap timers;
<doc> The delegate, if we have one. </doc>
public mutable RunLoopDelegate delegate;
<doc> Iff {TRUE}, one of the descriptor sets was changed, indicating to
the {run} method that it should update some of its local variables.
</doc>
boolean d_changed;
<doc> Iff {TRUE}, the {timers} was changed. </doc>
boolean t_changed;
}
<doc> Designated initializer. </doc>
id (self)
init
{
read_set = [DescriptorSet new];
write_set = [DescriptorSet new];
timers = [[Heap alloc] init FALSE];
}
<doc> Run this runloop. This method does not return. </doc>
extern void
run;
/********** Descriptors **********/
<doc><h4>Descriptors</h4></doc>
<doc> Add the {descriptor} to this runloop, read events on which are to be
handled by the {delegate}. This does not protect against adding the
{descriptor} to only a single runloop. </doc>
void
addDescriptorForRead Descriptor descriptor
delegate DescriptorReadDelegate delegate
{
read_set[descriptor] = delegate;
d_changed = YES;
}
<doc> Similar to {addDescriptorForRead delegate}, add the {descriptor} to
this runloop, write events on which are to be handled by the
{delegate}. </doc>
void
addDescriptorForWrite Descriptor descriptor
delegate DescriptorWriteDelegate delegate
{
write_set[descriptor] = delegate;
d_changed = YES;
}
<doc> Remove the {descriptor} from this runloop. No check is performed on
whether the {descriptor} actually is registered for reading with this
runloop. </doc>
void
removeReadDescriptor Descriptor descriptor
{
[read_set remove descriptor];
d_changed = YES;
}
<doc> Similar to {removeReadDescriptor}, but the {descriptor} is removed
from the write set. </doc>
void
removeWriteDescriptor Descriptor descriptor
{
[write_set remove descriptor];
d_changed = YES;
}
/********** Timers **********/
<doc><h4>Timers</h4></doc>
<doc> Add the {timer} to the current run loop. </doc>
void
add_timer Timer timer
{
[timers add timer];
t_changed = YES;
}
<doc> Remove the {timer} which is scheduled with this run loop. </doc>
void
remove_timer Timer timer
{
[timers remove timer];
t_changed = YES;
}
end;
/******************** RunLoopDelegate ********************/
implementation class
RunLoopDelegate
end;
implementation instance
RunLoopDelegate
<doc> Be notified that the {RunLoop} {loop} will do another select. </doc>
deferred void
runLoopWillSelect RunLoop loop;
end;
/******************** All (RunLoop) ********************/
<doc> This extension of {All} provides delayed {perform}ance. </doc>
implementation class
All extension RunLoop
end;
implementation instance
All extension RunLoop
<doc> Perform the selector {sel} with the {arguments} after {seconds}
delay. Even if {seconds} is 0, the invocation is not fired
immediately; a timer is always set to have the {RunLoop} fire the
invocation. </doc>
extern void
perform selector sel
after double seconds
with dynamic arguments
pre
seconds >= 0.0;
end;
|