File: RunLoop.t

package info (click to toggle)
tom 1.1.1-2
  • links: PTS
  • area: main
  • in suites: potato
  • size: 6,340 kB
  • ctags: 2,244
  • sloc: objc: 27,863; ansic: 9,804; sh: 7,411; yacc: 3,377; lex: 966; asm: 208; makefile: 62; cpp: 10
file content (174 lines) | stat: -rw-r--r-- 4,168 bytes parent folder | download
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;