 |
Changeset 3851
- Timestamp:
- 08/04/08 16:24:57
(4 months ago)
- Author:
- schveiguy
- Message:
Deprecating ISelector.reregister, call register instead.
Applied patch from rrichardson (thanks!)
Fixed some minor bugs
-
Files:
-
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
| r2983 |
r3851 |
|
| 39 | 39 | * manage will be incremented dynamically if necessary. |
|---|
| 40 | 40 | * |
|---|
| 41 | | * To add, modify or remove conduit registrations to the selector you use |
|---|
| 42 | | * the register(), reregister() and unregister() methods respectively. |
|---|
| | 41 | * To add or modify conduit registrations in the selector, use the register() |
|---|
| | 42 | * method. To remove conduit registrations from the selector, use the |
|---|
| | 43 | * unregister() method. |
|---|
| 43 | 44 | * |
|---|
| 44 | 45 | * To wait for events from the conduits you need to call any of the select() |
|---|
| … | … | |
| 87 | 88 | * { |
|---|
| 88 | 89 | * Stdout.format("Received '{0}' from peer\n", buffer[0..count]); |
|---|
| 89 | | * selector.reregister(key.conduit, Event.Write, key.attachment); |
|---|
| | 90 | * selector.register(key.conduit, Event.Write, key.attachment); |
|---|
| 90 | 91 | * } |
|---|
| 91 | 92 | * else |
|---|
| … | … | |
| 102 | 103 | * { |
|---|
| 103 | 104 | * Stdout("Sent 'MESSAGE' to peer\n"); |
|---|
| 104 | | * selector.reregister(key.conduit, Event.Read, key.attachment); |
|---|
| | 105 | * selector.register(key.conduit, Event.Read, key.attachment); |
|---|
| 105 | 106 | * } |
|---|
| 106 | 107 | * else |
|---|
| … | … | |
| 193 | 194 | |
|---|
| 194 | 195 | /** |
|---|
| 195 | | * Modify the events that are being tracked or the 'attachment' field |
|---|
| 196 | | * for an already registered conduit. |
|---|
| 197 | | * |
|---|
| 198 | | * Params: |
|---|
| 199 | | * conduit = conduit that will be associated to the selector |
|---|
| 200 | | * events = bit mask of Event values that represent the events that |
|---|
| 201 | | * will be tracked for the conduit. |
|---|
| 202 | | * attachment = optional object with application-specific data that will |
|---|
| 203 | | * be available when an event is triggered for the conduit |
|---|
| 204 | | * |
|---|
| 205 | | * Remarks: |
|---|
| 206 | | * The 'attachment' member of the SelectionKey will always be overwritten, |
|---|
| 207 | | * even if it's null. |
|---|
| 208 | | * |
|---|
| 209 | | * Examples: |
|---|
| 210 | | * --- |
|---|
| 211 | | * AbstractSelector selector; |
|---|
| 212 | | * SocketConduit conduit; |
|---|
| 213 | | * MyClass object; |
|---|
| 214 | | * |
|---|
| 215 | | * selector.reregister(conduit, Event.Write, object); |
|---|
| 216 | | * --- |
|---|
| 217 | | */ |
|---|
| 218 | | public abstract void reregister(ISelectable conduit, Event events, |
|---|
| 219 | | Object attachment); |
|---|
| | 196 | * Deprecated, use register instead |
|---|
| | 197 | */ |
|---|
| | 198 | deprecated public final void reregister(ISelectable conduit, Event events, |
|---|
| | 199 | Object attachment = null) |
|---|
| | 200 | { |
|---|
| | 201 | register(conduit, events, attachment); |
|---|
| | 202 | } |
|---|
| 220 | 203 | |
|---|
| 221 | 204 | /** |
|---|
| r3508 |
r3851 |
|
| 67 | 67 | * { |
|---|
| 68 | 68 | * Stdout.format("Received '{0}' from peer\n", buffer[0..count]); |
|---|
| 69 | | * selector.reregister(key.conduit, Event.Write, key.attachment); |
|---|
| | 69 | * selector.register(key.conduit, Event.Write, key.attachment); |
|---|
| 70 | 70 | * } |
|---|
| 71 | 71 | * else |
|---|
| … | … | |
| 82 | 82 | * { |
|---|
| 83 | 83 | * Stdout("Sent 'MESSAGE' to peer"); |
|---|
| 84 | | * selector.reregister(key.conduit, Event.Read, key.attachment); |
|---|
| | 84 | * selector.register(key.conduit, Event.Read, key.attachment); |
|---|
| 85 | 85 | * } |
|---|
| 86 | 86 | * else |
|---|
| … | … | |
| 196 | 196 | /** |
|---|
| 197 | 197 | * Associate a conduit to the selector and track specific I/O events. |
|---|
| | 198 | * If a conduit is already associated, changes the events and |
|---|
| | 199 | * attachment. |
|---|
| 198 | 200 | * |
|---|
| 199 | 201 | * Params: |
|---|
| … | … | |
| 223 | 225 | body |
|---|
| 224 | 226 | { |
|---|
| 225 | | epoll_event event; |
|---|
| 226 | | SelectionKey key = new SelectionKey(conduit, events, attachment); |
|---|
| 227 | | |
|---|
| 228 | | event.events = events; |
|---|
| 229 | | // We associate the selection key to the epoll_event to be able to |
|---|
| 230 | | // retrieve it efficiently when we get events for this handle. |
|---|
| 231 | | event.data.ptr = cast(void*) key; |
|---|
| 232 | | |
|---|
| 233 | | if (epoll_ctl(_epfd, EPOLL_CTL_ADD, conduit.fileHandle(), &event) == 0) |
|---|
| 234 | | { |
|---|
| 235 | | // We keep the keys in a map to make sure that the key is not |
|---|
| 236 | | // garbage collected while there is still a reference to it in |
|---|
| 237 | | // an epoll_event. This also allows to to efficiently find the |
|---|
| 238 | | // key corresponding to a handle in methods where this |
|---|
| 239 | | // association is not provided automatically. |
|---|
| 240 | | _keys[conduit.fileHandle()] = key; |
|---|
| 241 | | } |
|---|
| 242 | | else |
|---|
| 243 | | { |
|---|
| 244 | | checkErrno(__FILE__, __LINE__); |
|---|
| 245 | | } |
|---|
| 246 | | } |
|---|
| 247 | | |
|---|
| 248 | | /** |
|---|
| 249 | | * Modify the events that are being tracked or the 'attachment' field |
|---|
| 250 | | * for an already registered conduit. |
|---|
| 251 | | * |
|---|
| 252 | | * Params: |
|---|
| 253 | | * conduit = conduit that will be associated to the selector; |
|---|
| 254 | | * must be a valid conduit (i.e. not null and open). |
|---|
| 255 | | * events = bit mask of Event values that represent the events |
|---|
| 256 | | * that will be tracked for the conduit. |
|---|
| 257 | | * attachment = optional object with application-specific data that |
|---|
| 258 | | * will be available when an event is triggered for the |
|---|
| 259 | | * conduit |
|---|
| 260 | | * |
|---|
| 261 | | * Remarks: |
|---|
| 262 | | * The 'attachment' member of the SelectionKey will always be |
|---|
| 263 | | * overwritten, even if it's null. |
|---|
| 264 | | * |
|---|
| 265 | | * Throws: |
|---|
| 266 | | * UnregisteredConduitException if the conduit had not been previously |
|---|
| 267 | | * registered to the selector; SelectorException if there are not |
|---|
| 268 | | * enough resources to modify the conduit registration. |
|---|
| 269 | | * |
|---|
| 270 | | * Examples: |
|---|
| 271 | | * --- |
|---|
| 272 | | * selector.reregister(conduit, Event.Write, object); |
|---|
| 273 | | * --- |
|---|
| 274 | | */ |
|---|
| 275 | | public void reregister(ISelectable conduit, Event events, Object attachment = null) |
|---|
| 276 | | in |
|---|
| 277 | | { |
|---|
| 278 | | assert(conduit !is null && conduit.fileHandle() >= 0); |
|---|
| 279 | | } |
|---|
| 280 | | body |
|---|
| 281 | | { |
|---|
| 282 | 227 | SelectionKey* key = (conduit.fileHandle() in _keys); |
|---|
| 283 | 228 | |
|---|
| … | … | |
| 299 | 244 | else |
|---|
| 300 | 245 | { |
|---|
| 301 | | throw new UnregisteredConduitException(__FILE__, __LINE__); |
|---|
| | 246 | epoll_event event; |
|---|
| | 247 | SelectionKey newkey = new SelectionKey(conduit, events, attachment); |
|---|
| | 248 | |
|---|
| | 249 | event.events = events; |
|---|
| | 250 | // We associate the selection key to the epoll_event to be able to |
|---|
| | 251 | // retrieve it efficiently when we get events for this handle. |
|---|
| | 252 | event.data.ptr = cast(void*) newkey; |
|---|
| | 253 | |
|---|
| | 254 | if (epoll_ctl(_epfd, EPOLL_CTL_ADD, conduit.fileHandle(), &event) == 0) |
|---|
| | 255 | { |
|---|
| | 256 | // We keep the keys in a map to make sure that the key is not |
|---|
| | 257 | // garbage collected while there is still a reference to it in |
|---|
| | 258 | // an epoll_event. This also allows to to efficiently find the |
|---|
| | 259 | // key corresponding to a handle in methods where this |
|---|
| | 260 | // association is not provided automatically. |
|---|
| | 261 | _keys[conduit.fileHandle()] = newkey; |
|---|
| | 262 | } |
|---|
| | 263 | else |
|---|
| | 264 | { |
|---|
| | 265 | checkErrno(__FILE__, __LINE__); |
|---|
| | 266 | } |
|---|
| 302 | 267 | } |
|---|
| 303 | 268 | } |
|---|
| r3508 |
r3851 |
|
| 121 | 121 | /** |
|---|
| 122 | 122 | * Associate a conduit to the selector and track specific I/O events. |
|---|
| | 123 | * If a conduit is already associated, modify the events and |
|---|
| | 124 | * attachment. |
|---|
| 123 | 125 | * |
|---|
| 124 | 126 | * Params: |
|---|
| … | … | |
| 148 | 150 | { |
|---|
| 149 | 151 | debug (selector) |
|---|
| 150 | | Stdout.format("--- PollSelector.register(handle={0}, events=0x{1:x})\n", |
|---|
| 151 | | cast(int) conduit.fileHandle(), cast(uint) events); |
|---|
| 152 | | |
|---|
| 153 | | // We make sure that the conduit is not already registered to |
|---|
| 154 | | // the Selector |
|---|
| 155 | | if ((conduit.fileHandle() in _keys) is null) |
|---|
| 156 | | { |
|---|
| 157 | | if (_count == _pfds.length) |
|---|
| 158 | | _pfds.length = _pfds.length + 1; |
|---|
| 159 | | |
|---|
| 160 | | _pfds[_count].fd = conduit.fileHandle(); |
|---|
| 161 | | _pfds[_count].events = cast(short) events; |
|---|
| 162 | | _pfds[_count].revents = 0; |
|---|
| 163 | | |
|---|
| 164 | | _keys[conduit.fileHandle()] = new PollSelectionKey(conduit, events, _count, attachment); |
|---|
| 165 | | _count++; |
|---|
| 166 | | } |
|---|
| 167 | | else |
|---|
| 168 | | { |
|---|
| 169 | | throw new RegisteredConduitException(__FILE__, __LINE__); |
|---|
| 170 | | } |
|---|
| 171 | | } |
|---|
| 172 | | |
|---|
| 173 | | /** |
|---|
| 174 | | * Modify the events that are being tracked or the 'attachment' field |
|---|
| 175 | | * for an already registered conduit. |
|---|
| 176 | | * |
|---|
| 177 | | * Params: |
|---|
| 178 | | * conduit = conduit that will be associated to the selector; |
|---|
| 179 | | * must be a valid conduit (i.e. not null and open). |
|---|
| 180 | | * events = bit mask of Event values that represent the events |
|---|
| 181 | | * that will be tracked for the conduit. |
|---|
| 182 | | * attachment = optional object with application-specific data that |
|---|
| 183 | | * will be available when an event is triggered for the |
|---|
| 184 | | * conduit |
|---|
| 185 | | * |
|---|
| 186 | | * Remarks: |
|---|
| 187 | | * The 'attachment' member of the SelectionKey will always be |
|---|
| 188 | | * overwritten, even if it's null. |
|---|
| 189 | | * |
|---|
| 190 | | * Throws: |
|---|
| 191 | | * UnregisteredConduitException if the conduit had not been previously |
|---|
| 192 | | * registered to the selector. |
|---|
| 193 | | * |
|---|
| 194 | | * Examples: |
|---|
| 195 | | * --- |
|---|
| 196 | | * selector.reregister(conduit, Event.Write, object); |
|---|
| 197 | | * --- |
|---|
| 198 | | */ |
|---|
| 199 | | public void reregister(ISelectable conduit, Event events, Object attachment = null) |
|---|
| 200 | | in |
|---|
| 201 | | { |
|---|
| 202 | | assert(conduit !is null && conduit.fileHandle() >= 0); |
|---|
| 203 | | } |
|---|
| 204 | | body |
|---|
| 205 | | { |
|---|
| 206 | | debug (selector) |
|---|
| 207 | | Stdout.format("--- PollSelector.reregister(handle={0}, events=0x{1:x})", |
|---|
| | 152 | Stdout.formatln("--- PollSelector.register(handle={0}, events=0x{1:x})", |
|---|
| 208 | 153 | cast(int) conduit.fileHandle(), cast(uint) events); |
|---|
| 209 | 154 | |
|---|
| … | … | |
| 213 | 158 | { |
|---|
| 214 | 159 | debug (selector) |
|---|
| 215 | | Stdout.format("--- Adding pollfd in index {0} (of {1})\n", |
|---|
| | 160 | Stdout.formatln("--- Adding pollfd in index {0} (of {1})", |
|---|
| 216 | 161 | current.index, _count); |
|---|
| 217 | 162 | |
|---|
| … | … | |
| 223 | 168 | else |
|---|
| 224 | 169 | { |
|---|
| 225 | | throw new UnregisteredConduitException(__FILE__, __LINE__); |
|---|
| | 170 | if (_count == _pfds.length) |
|---|
| | 171 | _pfds.length = _pfds.length + 1; |
|---|
| | 172 | |
|---|
| | 173 | _pfds[_count].fd = conduit.fileHandle(); |
|---|
| | 174 | _pfds[_count].events = cast(short) events; |
|---|
| | 175 | _pfds[_count].revents = 0; |
|---|
| | 176 | |
|---|
| | 177 | _keys[conduit.fileHandle()] = new PollSelectionKey(conduit, events, _count, attachment); |
|---|
| | 178 | _count++; |
|---|
| 226 | 179 | } |
|---|
| 227 | 180 | } |
|---|
| … | … | |
| 249 | 202 | { |
|---|
| 250 | 203 | debug (selector) |
|---|
| 251 | | Stdout.format("--- PollSelector.unregister(handle={0})\n", |
|---|
| | 204 | Stdout.formatln("--- PollSelector.unregister(handle={0})", |
|---|
| 252 | 205 | cast(int) conduit.fileHandle()); |
|---|
| 253 | 206 | |
|---|
| … | … | |
| 257 | 210 | { |
|---|
| 258 | 211 | debug (selector) |
|---|
| 259 | | Stdout.format("--- Removing pollfd in index {0} (of {1})\n", |
|---|
| | 212 | Stdout.formatln("--- Removing pollfd in index {0} (of {1})", |
|---|
| 260 | 213 | removed.index, _count); |
|---|
| 261 | 214 | |
|---|
| 262 | | for (uint i = removed.index + 1; i > 0 && i < _count; i++) |
|---|
| 263 | | { |
|---|
| 264 | | _pfds[i - 1] = _pfds[i]; |
|---|
| 265 | | } |
|---|
| | 215 | // |
|---|
| | 216 | // instead of doing an O(n) remove, move the last |
|---|
| | 217 | // element to the removed slot |
|---|
| | 218 | // |
|---|
| | 219 | _pfds[removed.index] = _pfds[_count - 1]; |
|---|
| | 220 | _keys[cast(ISelectable.Handle)_pfds[removed.index].fd].index = removed.index; |
|---|
| 266 | 221 | _count--; |
|---|
| 267 | 222 | |
|---|
| … | … | |
| 271 | 226 | { |
|---|
| 272 | 227 | debug (selector) |
|---|
| 273 | | Stdout.format("--- PollSelector.unregister(handle={0}): conduit was not found\n", |
|---|
| | 228 | Stdout.formatln("--- PollSelector.unregister(handle={0}): conduit was not found", |
|---|
| 274 | 229 | cast(int) conduit.fileHandle()); |
|---|
| 275 | 230 | throw new UnregisteredConduitException(__FILE__, __LINE__); |
|---|
| … | … | |
| 279 | 234 | { |
|---|
| 280 | 235 | debug (selector) |
|---|
| 281 | | Stdout.format("--- Exception inside PollSelector.unregister(handle={0}): {1}", |
|---|
| | 236 | Stdout.formatln("--- Exception inside PollSelector.unregister(handle={0}): {1}", |
|---|
| 282 | 237 | cast(int) conduit.fileHandle(), e.toString()); |
|---|
| 283 | 238 | |
|---|
| … | … | |
| 314 | 269 | |
|---|
| 315 | 270 | debug (selector) |
|---|
| 316 | | Stdout.format("--- PollSelector.select({0} ms): waiting on {1} handles\n", |
|---|
| | 271 | Stdout.formatln("--- PollSelector.select({0} ms): waiting on {1} handles", |
|---|
| 317 | 272 | to, _count); |
|---|
| 318 | 273 | |
|---|
| … | … | |
| 340 | 295 | { |
|---|
| 341 | 296 | debug (selector) |
|---|
| 342 | | Stdout.format("--- Found events 0x{0:x} for handle {1} (index {2})\n", |
|---|
| | 297 | Stdout.formatln("--- Found events 0x{0:x} for handle {1} (index {2})", |
|---|
| 343 | 298 | cast(uint) pfd.revents, cast(int) pfd.fd, i); |
|---|
| 344 | 299 | |
|---|
| … | … | |
| 364 | 319 | { |
|---|
| 365 | 320 | debug (selector) |
|---|
| 366 | | Stdout.format("--- Handle {0} was not found in the Selector\n", |
|---|
| | 321 | Stdout.formatln("--- Handle {0} was not found in the Selector", |
|---|
| 367 | 322 | cast(int) pfd.fd); |
|---|
| 368 | 323 | } |
|---|
| r3508 |
r3851 |
|
| 153 | 153 | } |
|---|
| 154 | 154 | |
|---|
| | 155 | private HandleSet allocateSet(ref HandleSet set, ref HandleSet selectedSet) |
|---|
| | 156 | { |
|---|
| | 157 | if(set is null) |
|---|
| | 158 | { |
|---|
| | 159 | set = new HandleSet(_size); |
|---|
| | 160 | selectedSet = new HandleSet(_size); |
|---|
| | 161 | } |
|---|
| | 162 | return set; |
|---|
| | 163 | } |
|---|
| | 164 | |
|---|
| 155 | 165 | /** |
|---|
| 156 | 166 | * Associate a conduit to the selector and track specific I/O events. |
|---|
| | 167 | * If a conduit is already associated with the selector, the events and |
|---|
| | 168 | * attachment are upated. |
|---|
| 157 | 169 | * |
|---|
| 158 | 170 | * Params: |
|---|
| … | … | |
| 185 | 197 | debug (selector) |
|---|
| 186 | 198 | Stdout.format("--- SelectSelector.register(handle={0}, events=0x{1:x})\n", |
|---|
| 187 | | cast(int) handle, cast(uint) events); |
|---|
| 188 | | |
|---|
| 189 | | // We make sure that the conduit is not already registered to |
|---|
| 190 | | // the Selector |
|---|
| 191 | | SelectionKey* key = (conduit.fileHandle() in _keys); |
|---|
| 192 | | |
|---|
| 193 | | if (key is null) |
|---|
| | 199 | cast(int) handle, cast(uint) events); |
|---|
| | 200 | |
|---|
| | 201 | SelectionKey *key = (handle in _keys); |
|---|
| | 202 | if (key !is null) |
|---|
| | 203 | { |
|---|
| | 204 | if ((events & Event.Read) || (events & Event.Hangup)) |
|---|
| | 205 | { |
|---|
| | 206 | allocateSet(_readSet, _selectedReadSet).set(handle); |
|---|
| | 207 | } |
|---|
| | 208 | else if (_readSet !is null) |
|---|
| | 209 | { |
|---|
| | 210 | _readSet.clear(handle); |
|---|
| | 211 | } |
|---|
| | 212 | |
|---|
| | 213 | if ((events & Event.Write)) |
|---|
| | 214 | { |
|---|
| | 215 | allocateSet(_writeSet, _selectedWriteSet).set(handle); |
|---|
| | 216 | } |
|---|
| | 217 | else if (_writeSet !is null) |
|---|
| | 218 | { |
|---|
| | 219 | _writeSet.clear(handle); |
|---|
| | 220 | } |
|---|
| | 221 | |
|---|
| | 222 | if (events & Event.Error) |
|---|
| | 223 | { |
|---|
| | 224 | allocateSet(_exceptionSet, _selectedExceptionSet).set(handle); |
|---|
| | 225 | } |
|---|
| | 226 | else if (_exceptionSet !is null) |
|---|
| | 227 | { |
|---|
| | 228 | _exceptionSet.clear(handle); |
|---|
| | 229 | } |
|---|
| | 230 | |
|---|
| | 231 | version (Posix) |
|---|
| | 232 | { |
|---|
| | 233 | if (handle > _maxfd) |
|---|
| | 234 | _maxfd = handle; |
|---|
| | 235 | } |
|---|
| | 236 | |
|---|
| | 237 | (*key).events = events; |
|---|
| | 238 | (*key).attachment = attachment; |
|---|
| | 239 | } |
|---|
| | 240 | else |
|---|
| 194 | 241 | { |
|---|
| 195 | 242 | // Keep record of the Conduits for whom we're tracking events. |
|---|
| … | … | |
| 198 | 245 | if ((events & Event.Read) || (events & Event.Hangup)) |
|---|
| 199 | 246 | { |
|---|
| 200 | | if (_readSet is null) |
|---|
| 201 | | { |
|---|
| 202 | | _readSet = new HandleSet(_size); |
|---|
| 203 | | _selectedReadSet = new HandleSet(_size); |
|---|
| 204 | | } |
|---|
| 205 | | _readSet.set(handle); |
|---|
| | 247 | allocateSet(_readSet, _selectedReadSet).set(handle); |
|---|
| 206 | 248 | } |
|---|
| 207 | 249 | |
|---|
| 208 | 250 | if (events & Event.Write) |
|---|
| 209 | 251 | { |
|---|
| 210 | | if (_writeSet is null) |
|---|
| 211 | | { |
|---|
| 212 | | _writeSet = new HandleSet(_size); |
|---|
| 213 | | _selectedWriteSet = new HandleSet(_size); |
|---|
| 214 | | } |
|---|
| 215 | | _writeSet.set(handle); |
|---|
| | 252 | allocateSet(_writeSet, _selectedWriteSet).set(handle); |
|---|
| 216 | 253 | } |
|---|
| 217 | 254 | |
|---|
| 218 | 255 | if (events & Event.Error) |
|---|
| 219 | 256 | { |
|---|
| 220 | | if (_exceptionSet is null) |
|---|
| 221 | | { |
|---|
| 222 | | _exceptionSet = new HandleSet(_size); |
|---|
| 223 | | _selectedExceptionSet = new HandleSet(_size); |
|---|
| 224 | | } |
|---|
| 225 | | _exceptionSet.set(handle); |
|---|
| | 257 | allocateSet(_exceptionSet, _selectedExceptionSet).set(handle); |
|---|
| 226 | 258 | } |
|---|
| 227 | 259 | |
|---|
| … | … | |
| 231 | 263 | _maxfd = handle; |
|---|
| 232 | 264 | } |
|---|
| 233 | | } |
|---|
| 234 | | else |
|---|
| 235 | | { |
|---|
| 236 | | throw new RegisteredConduitException(__FILE__, __LINE__); |
|---|
| 237 | | } |
|---|
| 238 | | } |
|---|
| 239 | | |
|---|
| 240 | | /** |
|---|
| 241 | | * Modify the events that are being tracked or the 'attachment' field |
|---|
| 242 | | * for an already registered conduit. |
|---|
| 243 | | * |
|---|
| 244 | | * Params: |
|---|
| 245 | | * conduit = conduit that will be associated to the selector; |
|---|
| 246 | | * must be a valid conduit (i.e. not null and open). |
|---|
| 247 | | * events = bit mask of Event values that represent the events |
|---|
| 248 | | * that will be tracked for the conduit. |
|---|
| 249 | | * attachment = optional object with application-specific data that |
|---|
| 250 | | * will be available when an event is triggered for the |
|---|
| 251 | | * conduit |
|---|
| 252 | | * |
|---|
| 253 | | * Remarks: |
|---|
| 254 | | * The 'attachment' member of the SelectionKey will always be |
|---|
| 255 | | * overwritten, even if it's null. |
|---|
| 256 | | * |
|---|
| 257 | | * Throws: |
|---|
| 258 | | * UnregisteredConduitException if the conduit had not been previously |
|---|
| 259 | | * registered to the selector. |
|---|
| 260 | | * |
|---|
| 261 | | * Examples: |
|---|
| 262 | | * --- |
|---|
| 263 | | * selector.reregister(conduit, Event.Write, object); |
|---|
| 264 | | * --- |
|---|
| 265 | | */ |
|---|
| 266 | | public void reregister(ISelectable conduit, Event events, Object attachment = null) |
|---|
| 267 | | in |
|---|
| 268 | | { |
|---|
| 269 | | assert(conduit !is null && conduit.fileHandle() >= 0); |
|---|
| 270 | | } |
|---|
| 271 | | body |
|---|
| 272 | | { |
|---|
| 273 | | ISelectable.Handle handle = conduit.fileHandle(); |
|---|
| 274 | | |
|---|
| 275 | | debug (selector) |
|---|
| 276 | | Stdout.format("--- SelectSelector.reregister(handle={0}, events=0x{1:x})\n", |
|---|
| 277 | | cast(int) handle, cast(uint) events); |
|---|
| 278 | | |
|---|
| 279 | | SelectionKey *key = (handle in _keys); |
|---|
| 280 | | if (key !is null) |
|---|
| 281 | | { |
|---|
| 282 | | if ((events & Event.Read) || (events & Event.Hangup)) |
|---|
| 283 | | { |
|---|
| 284 | | if (_readSet is null) |
|---|
| 285 | | { |
|---|
| 286 | | _readSet = new HandleSet(_size); |
|---|
| 287 | | _selectedReadSet = new HandleSet(_size); |
|---|
| 288 | | } |
|---|
| 289 | | _readSet.set(handle); |
|---|
| 290 | | } |
|---|
| 291 | | else if (_readSet !is null) |
|---|
| 292 | | { |
|---|
| 293 | | _readSet.clear(handle); |
|---|
| 294 | | } |
|---|
| 295 | | |
|---|
| 296 | | if ((events & Event.Write)) |
|---|
| 297 | | { |
|---|
| 298 | | if (_writeSet is null) |
|---|
| 299 | | { |
|---|
| 300 | | _writeSet = new HandleSet(_size); |
|---|
| 301 | | _selectedWriteSet = new HandleSet(_size); |
|---|
| 302 | | } |
|---|
| 303 | | _writeSet.set(handle); |
|---|
| 304 | | } |
|---|
| 305 | | else if (_writeSet !is null) |
|---|
| 306 | | { |
|---|
| 307 | | _writeSet.clear(handle); |
|---|
| 308 | | } |
|---|
| 309 | | |
|---|
| 310 | | if (events & Event.Error) |
|---|
| 311 | | { |
|---|
| 312 | | if (_exceptionSet is null) |
|---|
| 313 | | { |
|---|
| 314 | | _exceptionSet = new HandleSet(_size); |
|---|
| 315 | | _selectedExceptionSet = new HandleSet(_size); |
|---|
| 316 | | } |
|---|
| 317 | | _exceptionSet.set(handle); |
|---|
| 318 | | } |
|---|
| 319 | | else if (_exceptionSet !is null) |
|---|
| 320 | | { |
|---|
| 321 | | _exceptionSet.clear(handle); |
|---|
| 322 | | } |
|---|
| 323 | | |
|---|
| 324 | | version (Posix) |
|---|
| 325 | | { |
|---|
| 326 | | if (handle > _maxfd) |
|---|
| 327 | | _maxfd = handle; |
|---|
| 328 | | } |
|---|
| 329 | | |
|---|
| 330 | | (*key).events = events; |
|---|
| 331 | | (*key).attachment = attachment; |
|---|
| 332 | | } |
|---|
| 333 | | else |
|---|
| 334 | | { |
|---|
| 335 | | throw new UnregisteredConduitException(__FILE__, __LINE__); |
|---|
| 336 | 265 | } |
|---|
| 337 | 266 | } |
|---|
| r3069 |
r3851 |
|
| 37 | 37 | * conduit and the events that are to be tracked for it. The 'events' member |
|---|
| 38 | 38 | * of the key can take two meanings, depending on where it's used. If used |
|---|
| 39 | | * with the registration methods of the selector (register(), reregister()) it |
|---|
| 40 | | * represents the events we want to track; if used within a foreach cycle |
|---|
| 41 | | * on an ISelectionSet it represents the events that have been detected for a |
|---|
| 42 | | * conduit. |
|---|
| | 39 | * with the register() method of the selector it represents the events we want |
|---|
| | 40 | * to track; if used within a foreach cycle on an ISelectionSet it represents |
|---|
| | 41 | * the events that have been detected for a conduit. |
|---|
| 43 | 42 | * |
|---|
| 44 | 43 | * The SelectionKey can also hold an optional object via the 'attachment' |
|---|
| … | … | |
| 217 | 216 | * manage will be incremented dynamically if necessary. |
|---|
| 218 | 217 | * |
|---|
| 219 | | * To add, modify or remove conduit registrations to the selector you use |
|---|
| 220 | | * the register(), reregister() and unregister() methods respectively. |
|---|
| | 218 | * To add or modify conduit registrations in the selector, use the register() |
|---|
| | 219 | * method. To remove conduit registrations from the selector, use the |
|---|
| | 220 | * unregister() method. |
|---|
| 221 | 221 | * |
|---|
| 222 | 222 | * To wait for events from the conduits you need to call any of the select() |
|---|
| … | … | |
| 263 | 263 | * { |
|---|
| 264 | 264 | * Stdout.format("Received '{0}' from peer\n", buffer[0..count]); |
|---|
| 265 | | * selector.reregister(key.conduit, Event.Write, key.attachment); |
|---|
| | 265 | * selector.register(key.conduit, Event.Write, key.attachment); |
|---|
| 266 | 266 | * } |
|---|
| 267 | 267 | * else |
|---|
| … | … | |
| 278 | 278 | * { |
|---|
| 279 | 279 | * Stdout.print("Sent 'MESSAGE' to peer\n"); |
|---|
| 280 | | * selector.reregister(key.conduit, Event.Read, key.attachment); |
|---|
| | 280 | * selector.register(key.conduit, Event.Read, key.attachment); |
|---|
| 281 | 281 | * } |
|---|
| 282 | 282 | * else |
|---|
| … | … | |
| 325 | 325 | /** |
|---|
| 326 | 326 | * Associate a conduit to the selector and track specific I/O events. |
|---|
| | 327 | * If the conduit is already part of the selector, modify the events or |
|---|
| | 328 | * atachment. |
|---|
| 327 | 329 | * |
|---|
| 328 | 330 | * Params: |
|---|
| … | … | |
| 346 | 348 | Object attachment = null); |
|---|
| 347 | 349 | |
|---|
| 348 | | /** |
|---|
| 349 | | * Modify the events that are being tracked or the 'attachment' field |
|---|
| 350 | | * for an already registered conduit. |
|---|
| 351 | | * |
|---|
| 352 | | * Params: |
|---|
| 353 | | * conduit = conduit that will be associated to the selector; |
|---|
| 354 | | * must be a valid conduit (i.e. not null and open). |
|---|
| 355 | | * events = bit mask of Event values that represent the events that |
|---|
| 356 | | * will be tracked for the conduit. |
|---|
| 357 | | * attachment = optional object with application-specific data that will |
|---|
| 358 | | * be available when an event is triggered for the conduit |
|---|
| 359 | | * |
|---|
| 360 | | * Remarks: |
|---|
| 361 | | * The 'attachment' member of the SelectionKey will always be overwritten, |
|---|
| 362 | | * even if it's null. |
|---|
| 363 | | * |
|---|
| 364 | | * Examples: |
|---|
| 365 | | * --- |
|---|
| 366 | | * ISelector selector; |
|---|
| 367 | | * SocketConduit conduit; |
|---|
| 368 | | * MyClass object; |
|---|
| 369 | | * |
|---|
| 370 | | * selector.reregister(conduit, Event.Write, object); |
|---|
| 371 | | * --- |
|---|
| 372 | | */ |
|---|
| 373 | | public abstract void reregister(ISelectable conduit, Event events, |
|---|
| 374 | | Object attachment = null); |
|---|
| | 350 | |
|---|
| | 351 | /** |
|---|
| | 352 | * Deprecated, use register instead |
|---|
| | 353 | */ |
|---|
| | 354 | deprecated public abstract void reregister(ISelectable conduit, Event |
|---|
| | 355 | events, Object attachment = null); |
|---|
| | 356 | |
|---|
| 375 | 357 | /** |
|---|
| 376 | 358 | * Remove a conduit from the selector. |
|---|
| … | … | |
| 385 | 367 | */ |
|---|
| 386 | 368 | public abstract void unregister(ISelectable conduit); |
|---|
| | 369 | |
|---|
| 387 | 370 | |
|---|
| 388 | 371 | /** |
|---|
Download in other formats:
|
 |