Mercurial > projects > ldc
comparison tango/tango/io/selector/Selector.d @ 132:1700239cab2e trunk
[svn r136] MAJOR UNSTABLE UPDATE!!!
Initial commit after moving to Tango instead of Phobos.
Lots of bugfixes...
This build is not suitable for most things.
author | lindquist |
---|---|
date | Fri, 11 Jan 2008 17:57:40 +0100 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
131:5825d48b27d1 | 132:1700239cab2e |
---|---|
1 /******************************************************************************* | |
2 copyright: Copyright (c) 2006 Juan Jose Comellas. All rights reserved | |
3 license: BSD style: $(LICENSE) | |
4 author: Juan Jose Comellas <juanjo@comellas.com.ar> | |
5 *******************************************************************************/ | |
6 | |
7 module tango.io.selector.Selector; | |
8 | |
9 /** | |
10 * A multiplexor of conduit I/O events. | |
11 * | |
12 * A Selector can wait for I/O events (Read, Write, etc.) for multiple | |
13 * conduits efficiently (i.e. without consuming CPU cycles). | |
14 * | |
15 * The Selector is an alias for your system's most efficient I/O multiplexor, | |
16 * which will be determined during compilation. | |
17 * | |
18 * To create a Selector you need to use the open() method and when you decide | |
19 * you no longer need it you should call its close() method to free any system | |
20 * resources it may be consuming. All selectors that need to free resources | |
21 * when close() is called also implement a destructor that automatically calls | |
22 * this method. This means that if you declare your selector instance with the | |
23 * 'auto' keyword you won't have to worry about doing it manually. | |
24 * | |
25 * Once you have open()'ed your selector you need to associate the conduits to | |
26 * it by using the register() method. This method receives the conduit and the | |
27 * events you want to track for it. For example, if you wanted to read from | |
28 * the conduit you would do: | |
29 * | |
30 * --- | |
31 * selector.register(conduit, Event.Read, myObject); | |
32 * --- | |
33 * | |
34 * This method also accepts an optional third parameter to associate a | |
35 * user-defined object to the conduit. These three parameters together define | |
36 * a SelectionKey, which is what you'll receive when the conduit is "selected" | |
37 * (i.e. receives an event). | |
38 * | |
39 * If you need to modify your conduit's registration you need to use the | |
40 * reregister() method, which works like register(), but expects to be passed | |
41 * a conduit that has already been associated to the selector: | |
42 * | |
43 * --- | |
44 * selector.reregister(conduit, Event.Write, myObject); | |
45 * --- | |
46 * | |
47 * If you need to remove a conduit from the selector you do it by calling | |
48 * unregister(): | |
49 * | |
50 * --- | |
51 * selector.unregister(conduit); | |
52 * --- | |
53 * | |
54 * Once you are done setting up the conduits you will want to wait for I/O | |
55 * events for them. To do that you need to use the select() method. This | |
56 * method blocks until either one of the conduits is selected or the | |
57 * specified timeout is reached. Even though it has two different versions: | |
58 * a) select(); b) select(Interval); the first one is just the same as doing | |
59 * select(Interval.max). In that case we don't have a timeout and | |
60 * select() blocks until a conduit receives an event. | |
61 * | |
62 * When select() returns you will receive an integer; if this integer is | |
63 * bigger than 0, it indicates the number of conduits that have been selected. | |
64 * If this number is 0, the it means that the selector reached a timeout, and | |
65 * if it's -1, then it means that there was an error. A normal block that deals | |
66 * with the selection process would look like this: | |
67 * | |
68 * --- | |
69 * try | |
70 * { | |
71 * int eventCount = selector.select(10.0); | |
72 * if (eventCount > 0) | |
73 * { | |
74 * // Process the I/O events in the selected set | |
75 * } | |
76 * else if (eventCount == 0) | |
77 * { | |
78 * // Timeout | |
79 * } | |
80 * else if (eventCount == -1) | |
81 * { | |
82 * // Error | |
83 * } | |
84 * else | |
85 * { | |
86 * // Error: should never happen. | |
87 * } | |
88 * } | |
89 * catch (SelectorException e) | |
90 * { | |
91 * Stdout.format("Exception caught: {0}", e.toString()).newline(); | |
92 * } | |
93 * --- | |
94 * | |
95 * Finally, to gather the events you need to iterate over the selector's | |
96 * selection set, which can be accessed via the selectedSet() method. | |
97 * | |
98 * --- | |
99 * foreach (SelectionKey key; selector.selectedSet()) | |
100 * { | |
101 * if (key.isReadable()) | |
102 * { | |
103 * // Read from conduit | |
104 * // [...] | |
105 * // Then register it for writing | |
106 * selector.reregister(key.conduit, Event.Write, key.attachment); | |
107 * } | |
108 * | |
109 * if (key.isWriteable()) | |
110 * { | |
111 * // Write to conduit | |
112 * // [...] | |
113 * // Then register it for reading | |
114 * selector.reregister(key.conduit, Event.Read, key.attachment); | |
115 * } | |
116 * | |
117 * if (key.isError()) | |
118 * { | |
119 * // Problem with conduit; remove it from selector | |
120 * selector.remove(conduit); | |
121 * } | |
122 * } | |
123 * --- | |
124 */ | |
125 version (linux) | |
126 { | |
127 public import tango.io.selector.EpollSelector; | |
128 | |
129 /** | |
130 * Default Selector for Linux. | |
131 */ | |
132 alias EpollSelector Selector; | |
133 } | |
134 else version(Posix) | |
135 { | |
136 public import tango.io.selector.PollSelector; | |
137 | |
138 /** | |
139 * Default Selector for POSIX-compatible platforms. | |
140 */ | |
141 alias PollSelector Selector; | |
142 } | |
143 else | |
144 { | |
145 public import tango.io.selector.SelectSelector; | |
146 | |
147 /** | |
148 * Default Selector for Windows. | |
149 */ | |
150 alias SelectSelector Selector; | |
151 } |