annotate dreactor/core/Vat.d @ 12:d6a3cfe7c3de

more stuff
author rick@Macintosh.local
date Wed, 27 Aug 2008 00:47:33 -0400
parents 5836613d16ac
children 8c9b1276f623
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
11
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
1 /*******************************************************************************
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
2
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
3 copyright: Copyright (c) 2008 Rick Richardson. All rights reserved
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
4
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
5 license: BSD style: $(LICENSE)
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
6
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
7 version: Initial release v0.1 : May 2008
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
8
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
9 author: Rick Richardson
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
10
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
11 *******************************************************************************/
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
12
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
13 module dreactor.core.Vat;
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
14
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
15 import tango.io.selector.Selector;
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
16 import tango.io.selector.model.ISelector;
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
17 import tango.core.Exception;
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
18 import tango.core.Thread;
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
19 import tango.core.Atomic;
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
20 import tango.util.collection.CircularSeq;
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
21 import tango.util.log.Log;
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
22
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
23 import dreactor.transport.AsyncSocketConduit;
12
d6a3cfe7c3de more stuff
rick@Macintosh.local
parents: 11
diff changeset
24 import dreactor.protocol.IProvider;
11
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
25 import dreactor.core.Task;
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
26 import dreactor.util.ThreadSafeQueue;
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
27
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
28 static char[] version_string = "Vat.d 0.1 2008-05-31";
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
29
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
30
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
31 enum : int {CLOSE = -2, UNREGISTER = -1, REMAIN = 0, REGISTER = 1, REREGISTER = 2};
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
32
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
33 class TaskAttachment
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
34 {
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
35 public
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
36 Task task;
12
d6a3cfe7c3de more stuff
rick@Macintosh.local
parents: 11
diff changeset
37 IProvider provider;
11
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
38
12
d6a3cfe7c3de more stuff
rick@Macintosh.local
parents: 11
diff changeset
39 this (Task ta, IProvider p)
d6a3cfe7c3de more stuff
rick@Macintosh.local
parents: 11
diff changeset
40 { task = ta; provider = p; }
11
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
41 }
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
42
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
43 class Vat
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
44 {
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
45 private
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
46 Thread thread;
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
47 bool running;
12
d6a3cfe7c3de more stuff
rick@Macintosh.local
parents: 11
diff changeset
48 Logger log;
11
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
49
12
d6a3cfe7c3de more stuff
rick@Macintosh.local
parents: 11
diff changeset
50 TaskAttachment[int] tasks; //registry for local tasks
d6a3cfe7c3de more stuff
rick@Macintosh.local
parents: 11
diff changeset
51
d6a3cfe7c3de more stuff
rick@Macintosh.local
parents: 11
diff changeset
52 Selector selector;
d6a3cfe7c3de more stuff
rick@Macintosh.local
parents: 11
diff changeset
53 static Atomic!(int) taskCount;
d6a3cfe7c3de more stuff
rick@Macintosh.local
parents: 11
diff changeset
54 TaskAttachment[int] globalTasks; //global registry of tasks
11
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
55
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
56 public
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
57
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
58 this()
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
59 {
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
60 log = Log.lookup("dreactor.core.Vat");
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
61
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
62 running = true;
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
63 thread = new Thread(&eventLoop);
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
64 thread.start();
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
65 }
12
d6a3cfe7c3de more stuff
rick@Macintosh.local
parents: 11
diff changeset
66
d6a3cfe7c3de more stuff
rick@Macintosh.local
parents: 11
diff changeset
67 synchronized int addTask(Task t, IProvider p = null)
11
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
68 {
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
69 t.setVat(this);
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
70 ++taskCount;
12
d6a3cfe7c3de more stuff
rick@Macintosh.local
parents: 11
diff changeset
71 auto ta = new TaskAttachment(t, (p !is null) ? p : new DefaultProvider);
d6a3cfe7c3de more stuff
rick@Macintosh.local
parents: 11
diff changeset
72 tasks[taskCount] = ta;
d6a3cfe7c3de more stuff
rick@Macintosh.local
parents: 11
diff changeset
73 globalTask[taskCount] = ta;
d6a3cfe7c3de more stuff
rick@Macintosh.local
parents: 11
diff changeset
74 selector.register(p.getConduit(), p.getEvents(), ta);
11
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
75 t.setId(taskCount);
12
d6a3cfe7c3de more stuff
rick@Macintosh.local
parents: 11
diff changeset
76 return taskCount;
11
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
77 }
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
78
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
79 void exit()
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
80 {
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
81 running = false;
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
82 }
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
83
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
84 void wait()
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
85 {
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
86 thread.join();
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
87 }
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
88
12
d6a3cfe7c3de more stuff
rick@Macintosh.local
parents: 11
diff changeset
89 bool addConnection(int tid, Conduit c, Events evts)
11
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
90 {
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
91 log.trace("adding handler");
12
d6a3cfe7c3de more stuff
rick@Macintosh.local
parents: 11
diff changeset
92 TaskAttachment ta;
d6a3cfe7c3de more stuff
rick@Macintosh.local
parents: 11
diff changeset
93 if (ta = (tid in tasks))
d6a3cfe7c3de more stuff
rick@Macintosh.local
parents: 11
diff changeset
94 return selector.register(c, evts, ta);
d6a3cfe7c3de more stuff
rick@Macintosh.local
parents: 11
diff changeset
95 else
d6a3cfe7c3de more stuff
rick@Macintosh.local
parents: 11
diff changeset
96 return false;
11
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
97 }
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
98
12
d6a3cfe7c3de more stuff
rick@Macintosh.local
parents: 11
diff changeset
99 bool remConnection(Conduit c)
d6a3cfe7c3de more stuff
rick@Macintosh.local
parents: 11
diff changeset
100 {
d6a3cfe7c3de more stuff
rick@Macintosh.local
parents: 11
diff changeset
101 return selector.unregister(c);
d6a3cfe7c3de more stuff
rick@Macintosh.local
parents: 11
diff changeset
102 }
d6a3cfe7c3de more stuff
rick@Macintosh.local
parents: 11
diff changeset
103
d6a3cfe7c3de more stuff
rick@Macintosh.local
parents: 11
diff changeset
104 Task getTask(int tid)
11
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
105 {
12
d6a3cfe7c3de more stuff
rick@Macintosh.local
parents: 11
diff changeset
106 TaskAttachment ta;
d6a3cfe7c3de more stuff
rick@Macintosh.local
parents: 11
diff changeset
107 if (ta = (tid in tasks))
d6a3cfe7c3de more stuff
rick@Macintosh.local
parents: 11
diff changeset
108 return ta.task;
d6a3cfe7c3de more stuff
rick@Macintosh.local
parents: 11
diff changeset
109 else
d6a3cfe7c3de more stuff
rick@Macintosh.local
parents: 11
diff changeset
110 return null;
d6a3cfe7c3de more stuff
rick@Macintosh.local
parents: 11
diff changeset
111 }
d6a3cfe7c3de more stuff
rick@Macintosh.local
parents: 11
diff changeset
112
d6a3cfe7c3de more stuff
rick@Macintosh.local
parents: 11
diff changeset
113 static synchronized Task getGlobalTask(int tid)
d6a3cfe7c3de more stuff
rick@Macintosh.local
parents: 11
diff changeset
114 {
d6a3cfe7c3de more stuff
rick@Macintosh.local
parents: 11
diff changeset
115 TaskAttachment ta;
d6a3cfe7c3de more stuff
rick@Macintosh.local
parents: 11
diff changeset
116 if (ta = (tid in globaltasks))
d6a3cfe7c3de more stuff
rick@Macintosh.local
parents: 11
diff changeset
117 return ta.task;
d6a3cfe7c3de more stuff
rick@Macintosh.local
parents: 11
diff changeset
118 else
d6a3cfe7c3de more stuff
rick@Macintosh.local
parents: 11
diff changeset
119 return null;
11
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
120 }
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
121
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
122 private
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
123 void eventLoop()
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
124 {
12
d6a3cfe7c3de more stuff
rick@Macintosh.local
parents: 11
diff changeset
125 selector = new Selector();
11
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
126 selector.open();
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
127 do
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
128 {
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
129 execTasks();
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
130 auto eventCount = selector.select(0.01);
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
131
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
132 if (eventCount > 0)
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
133 {
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
134 // process events
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
135 foreach (SelectionKey key; selector.selectedSet())
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
136 {
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
137 if (key.isReadable())
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
138 {
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
139 // incoming data
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
140 log.trace("Read event fired");
12
d6a3cfe7c3de more stuff
rick@Macintosh.local
parents: 11
diff changeset
141 auto ta = cast(TaskAttachment) key.attachment;
d6a3cfe7c3de more stuff
rick@Macintosh.local
parents: 11
diff changeset
142 processReturn(ta.appendMessage(ta.provider.handleRead()), key.conduit);
d6a3cfe7c3de more stuff
rick@Macintosh.local
parents: 11
diff changeset
143
11
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
144 }
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
145 else if (key.isWritable())
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
146 {
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
147 log.trace("Write event fired");
12
d6a3cfe7c3de more stuff
rick@Macintosh.local
parents: 11
diff changeset
148 auto ta = cast(TaskAttachment) key.attachment;
d6a3cfe7c3de more stuff
rick@Macintosh.local
parents: 11
diff changeset
149 ta.appendMessage(ta.provider.handleWrite());
d6a3cfe7c3de more stuff
rick@Macintosh.local
parents: 11
diff changeset
150 processReturn(ta.appendMessage(ta.provider.handleWrite()), key.conduit);
11
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
151 }
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
152 else if (key.isHangup())
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
153 {
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
154 log.trace("Hangup event fired");
12
d6a3cfe7c3de more stuff
rick@Macintosh.local
parents: 11
diff changeset
155 auto ta = cast(TaskAttachment) key.attachment;
d6a3cfe7c3de more stuff
rick@Macintosh.local
parents: 11
diff changeset
156 ta.appendMessage(ta.provider.handleDisconnect());
d6a3cfe7c3de more stuff
rick@Macintosh.local
parents: 11
diff changeset
157 processReturn(ta.appendMessage(ta.provider.handleDisconnect()), key.conduit);
11
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
158 }
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
159 else if (key.isError() || key.isInvalidHandle())
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
160 {
12
d6a3cfe7c3de more stuff
rick@Macintosh.local
parents: 11
diff changeset
161 log.trace("Error event fired");
11
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
162 // error, close connection
12
d6a3cfe7c3de more stuff
rick@Macintosh.local
parents: 11
diff changeset
163 auto ta = cast(TaskAttachment) key.attachment;
d6a3cfe7c3de more stuff
rick@Macintosh.local
parents: 11
diff changeset
164 ta.appendMessage(ta.provider.handleError());
d6a3cfe7c3de more stuff
rick@Macintosh.local
parents: 11
diff changeset
165 processReturn(ta.appendMessage(ta.provider.handleError()), key.conduit);
11
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
166 }
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
167 }
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
168 }
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
169 else if (eventCount == 0)
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
170 {
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
171 /* can't think of anything useful to do here. */
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
172 }
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
173 else
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
174 {
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
175 log.error("Selector.select returned {}", eventCount);
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
176 }
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
177
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
178 } while (running)
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
179
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
180 }
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
181
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
182 void execTasks()
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
183 {
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
184 foreach(int k; tasks.keys)
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
185 {
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
186 if (tasks[k].state() == Fiber.State.HOLD)
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
187 tasks[k].call();
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
188 if (tasks[k].state() == Fiber.State.TERM)
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
189 tasks.remove(k);
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
190 }
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
191 }
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
192
12
d6a3cfe7c3de more stuff
rick@Macintosh.local
parents: 11
diff changeset
193 void processReturn(int result, Conduit c)
11
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
194 {
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
195 switch(result)
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
196 {
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
197 case CLOSE:
12
d6a3cfe7c3de more stuff
rick@Macintosh.local
parents: 11
diff changeset
198 selector.unregister(c);
d6a3cfe7c3de more stuff
rick@Macintosh.local
parents: 11
diff changeset
199 c.detach();
11
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
200 break;
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
201 case UNREGISTER:
12
d6a3cfe7c3de more stuff
rick@Macintosh.local
parents: 11
diff changeset
202 selector.unregister(c);
11
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
203 break;
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
204 case REMAIN:
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
205 //this space intentially left blank
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
206 break;
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
207 case REGISTER:
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
208 break;
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
209 case REREGISTER:
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
210 break;
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
211 default:
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
212 log.error("processReturn: unknown return value");
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
213 }
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
214 }
5836613d16ac reorg! reorg!
rick@minifunk
parents:
diff changeset
215 }