OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #ifndef BIN_EVENTHANDLER_WIN_H_ | 5 #ifndef BIN_EVENTHANDLER_WIN_H_ |
6 #define BIN_EVENTHANDLER_WIN_H_ | 6 #define BIN_EVENTHANDLER_WIN_H_ |
7 | 7 |
8 #if !defined(BIN_EVENTHANDLER_H_) | 8 #if !defined(BIN_EVENTHANDLER_H_) |
9 #error Do not include eventhandler_win.h directly; use eventhandler.h instead. | 9 #error Do not include eventhandler_win.h directly; use eventhandler.h instead. |
10 #endif | 10 #endif |
(...skipping 11 matching lines...) Expand all Loading... |
22 | 22 |
23 // Forward declarations. | 23 // Forward declarations. |
24 class EventHandlerImplementation; | 24 class EventHandlerImplementation; |
25 class Handle; | 25 class Handle; |
26 class FileHandle; | 26 class FileHandle; |
27 class SocketHandle; | 27 class SocketHandle; |
28 class ClientSocket; | 28 class ClientSocket; |
29 class ListenSocket; | 29 class ListenSocket; |
30 | 30 |
31 | 31 |
32 struct InterruptMessage { | |
33 intptr_t id; | |
34 Dart_Port dart_port; | |
35 int64_t data; | |
36 }; | |
37 | |
38 | |
39 // An OverlappedBuffer encapsulates the OVERLAPPED structure and the | 32 // An OverlappedBuffer encapsulates the OVERLAPPED structure and the |
40 // associated data buffer. For accept it also contains the pre-created | 33 // associated data buffer. For accept it also contains the pre-created |
41 // socket for the client. | 34 // socket for the client. |
42 class OverlappedBuffer { | 35 class OverlappedBuffer { |
43 public: | 36 public: |
44 enum Operation { | 37 enum Operation { |
45 kAccept, kRead, kRecvFrom, kWrite, kSendTo, kDisconnect, kConnect | 38 kAccept, kRead, kRecvFrom, kWrite, kSendTo, kDisconnect, kConnect |
46 }; | 39 }; |
47 | 40 |
48 static OverlappedBuffer* AllocateAcceptBuffer(int buffer_size); | 41 static OverlappedBuffer* AllocateAcceptBuffer(int buffer_size); |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
154 | 147 |
155 // Buffer for recv/send/AcceptEx. This must be at the end of the | 148 // Buffer for recv/send/AcceptEx. This must be at the end of the |
156 // object as the object is allocated larger than it's definition | 149 // object as the object is allocated larger than it's definition |
157 // indicate to extend this array. | 150 // indicate to extend this array. |
158 uint8_t buffer_data_[1]; | 151 uint8_t buffer_data_[1]; |
159 }; | 152 }; |
160 | 153 |
161 | 154 |
162 // Abstract super class for holding information on listen and connected | 155 // Abstract super class for holding information on listen and connected |
163 // sockets. | 156 // sockets. |
164 class Handle { | 157 class Handle : public DescriptorInfoBase { |
165 public: | 158 public: |
166 enum Type { | 159 enum Type { |
167 kFile, | 160 kFile, |
168 kStd, | 161 kStd, |
169 kDirectoryWatch, | 162 kDirectoryWatch, |
170 kClientSocket, | 163 kClientSocket, |
171 kListenSocket, | 164 kListenSocket, |
172 kDatagramSocket | 165 kDatagramSocket |
173 }; | 166 }; |
174 | 167 |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
218 bool IsError() { return (flags_ & (1 << kError)) != 0; } | 211 bool IsError() { return (flags_ & (1 << kError)) != 0; } |
219 void MarkClosing() { flags_ |= (1 << kClosing); } | 212 void MarkClosing() { flags_ |= (1 << kClosing); } |
220 void MarkClosedRead() { flags_ |= (1 << kCloseRead); } | 213 void MarkClosedRead() { flags_ |= (1 << kCloseRead); } |
221 void MarkClosedWrite() { flags_ |= (1 << kCloseWrite); } | 214 void MarkClosedWrite() { flags_ |= (1 << kCloseWrite); } |
222 void MarkError() { flags_ |= (1 << kError); } | 215 void MarkError() { flags_ |= (1 << kError); } |
223 | 216 |
224 virtual void EnsureInitialized( | 217 virtual void EnsureInitialized( |
225 EventHandlerImplementation* event_handler) = 0; | 218 EventHandlerImplementation* event_handler) = 0; |
226 | 219 |
227 HANDLE handle() { return handle_; } | 220 HANDLE handle() { return handle_; } |
228 Dart_Port port() { return port_; } | |
229 | 221 |
230 void Lock(); | 222 void Lock(); |
231 void Unlock(); | 223 void Unlock(); |
232 | 224 |
233 bool CreateCompletionPort(HANDLE completion_port); | 225 bool CreateCompletionPort(HANDLE completion_port); |
234 | 226 |
235 void Close(); | 227 void Close(); |
236 virtual void DoClose(); | 228 virtual void DoClose(); |
237 virtual bool IsClosed() = 0; | 229 virtual bool IsClosed() = 0; |
238 | 230 |
239 bool IsHandleClosed() const { return handle_ == INVALID_HANDLE_VALUE; } | 231 bool IsHandleClosed() const { return handle_ == INVALID_HANDLE_VALUE; } |
240 | 232 |
241 void SetPortAndMask(Dart_Port port, intptr_t mask) { | |
242 port_ = port; | |
243 mask_ = mask; | |
244 } | |
245 Type type() { return type_; } | 233 Type type() { return type_; } |
246 bool is_file() { return type_ == kFile; } | 234 bool is_file() { return type_ == kFile; } |
247 bool is_socket() { return type_ == kListenSocket || | 235 bool is_socket() { return type_ == kListenSocket || |
248 type_ == kClientSocket || | 236 type_ == kClientSocket || |
249 type_ == kDatagramSocket; } | 237 type_ == kDatagramSocket; } |
250 bool is_listen_socket() { return type_ == kListenSocket; } | 238 bool is_listen_socket() { return type_ == kListenSocket; } |
251 bool is_client_socket() { return type_ == kClientSocket; } | 239 bool is_client_socket() { return type_ == kClientSocket; } |
252 bool is_datagram_socket() { return type_ == kDatagramSocket; } | 240 bool is_datagram_socket() { return type_ == kDatagramSocket; } |
253 void set_mask(intptr_t mask) { mask_ = mask; } | |
254 intptr_t mask() { return mask_; } | |
255 | 241 |
256 void MarkDoesNotSupportOverlappedIO() { | 242 void MarkDoesNotSupportOverlappedIO() { |
257 flags_ |= (1 << kDoesNotSupportOverlappedIO); | 243 flags_ |= (1 << kDoesNotSupportOverlappedIO); |
258 } | 244 } |
259 bool SupportsOverlappedIO() { | 245 bool SupportsOverlappedIO() { |
260 return (flags_ & (1 << kDoesNotSupportOverlappedIO)) == 0; | 246 return (flags_ & (1 << kDoesNotSupportOverlappedIO)) == 0; |
261 } | 247 } |
262 | 248 |
263 void ReadSyncCompleteAsync(); | 249 void ReadSyncCompleteAsync(); |
264 | 250 |
265 DWORD last_error() { return last_error_; } | 251 DWORD last_error() { return last_error_; } |
266 void set_last_error(DWORD last_error) { last_error_ = last_error; } | 252 void set_last_error(DWORD last_error) { last_error_ = last_error; } |
267 | 253 |
268 protected: | 254 protected: |
269 enum Flags { | 255 enum Flags { |
270 kClosing = 0, | 256 kClosing = 0, |
271 kCloseRead = 1, | 257 kCloseRead = 1, |
272 kCloseWrite = 2, | 258 kCloseWrite = 2, |
273 kDoesNotSupportOverlappedIO = 3, | 259 kDoesNotSupportOverlappedIO = 3, |
274 kError = 4 | 260 kError = 4 |
275 }; | 261 }; |
276 | 262 |
277 explicit Handle(HANDLE handle); | 263 explicit Handle(intptr_t handle); |
278 Handle(HANDLE handle, Dart_Port port); | |
279 | 264 |
280 virtual void HandleIssueError(); | 265 virtual void HandleIssueError(); |
281 | 266 |
282 Type type_; | 267 Type type_; |
283 HANDLE handle_; | 268 HANDLE handle_; |
284 Dart_Port port_; // Dart port to communicate events for this socket. | |
285 intptr_t mask_; // Mask of events to report through the port. | |
286 HANDLE completion_port_; | 269 HANDLE completion_port_; |
287 EventHandlerImplementation* event_handler_; | 270 EventHandlerImplementation* event_handler_; |
288 | 271 |
289 OverlappedBuffer* data_ready_; // Buffer for data ready to be read. | 272 OverlappedBuffer* data_ready_; // Buffer for data ready to be read. |
290 OverlappedBuffer* pending_read_; // Buffer for pending read. | 273 OverlappedBuffer* pending_read_; // Buffer for pending read. |
291 OverlappedBuffer* pending_write_; // Buffer for pending write | 274 OverlappedBuffer* pending_write_; // Buffer for pending write |
292 | 275 |
293 DWORD last_error_; | 276 DWORD last_error_; |
294 | 277 |
295 private: | 278 private: |
296 int flags_; | 279 int flags_; |
297 CRITICAL_SECTION cs_; // Critical section protecting this object. | 280 CRITICAL_SECTION cs_; // Critical section protecting this object. |
298 }; | 281 }; |
299 | 282 |
300 | 283 |
301 class FileHandle : public Handle { | 284 class FileHandle : public DescriptorInfoSingleMixin<Handle> { |
302 public: | 285 public: |
303 explicit FileHandle(HANDLE handle) | 286 explicit FileHandle(HANDLE handle) |
304 : Handle(handle) { type_ = kFile; } | 287 : DescriptorInfoSingleMixin(reinterpret_cast<intptr_t>(handle)) { |
305 FileHandle(HANDLE handle, Dart_Port port) | 288 type_ = kFile; |
306 : Handle(handle, port) { type_ = kFile; } | 289 } |
307 | 290 |
308 virtual void EnsureInitialized(EventHandlerImplementation* event_handler); | 291 virtual void EnsureInitialized(EventHandlerImplementation* event_handler); |
309 virtual bool IsClosed(); | 292 virtual bool IsClosed(); |
310 }; | 293 }; |
311 | 294 |
312 | 295 |
313 class StdHandle : public FileHandle { | 296 class StdHandle : public FileHandle { |
314 public: | 297 public: |
315 explicit StdHandle(HANDLE handle) | 298 explicit StdHandle(HANDLE handle) |
316 : FileHandle(handle), | 299 : FileHandle(handle), |
(...skipping 15 matching lines...) Expand all Loading... |
332 void RunWriteLoop(); | 315 void RunWriteLoop(); |
333 | 316 |
334 private: | 317 private: |
335 intptr_t thread_wrote_; | 318 intptr_t thread_wrote_; |
336 bool write_thread_exists_; | 319 bool write_thread_exists_; |
337 bool write_thread_running_; | 320 bool write_thread_running_; |
338 Monitor* write_monitor_; | 321 Monitor* write_monitor_; |
339 }; | 322 }; |
340 | 323 |
341 | 324 |
342 class DirectoryWatchHandle : public Handle { | 325 class DirectoryWatchHandle : public DescriptorInfoSingleMixin<Handle> { |
343 public: | 326 public: |
344 DirectoryWatchHandle(HANDLE handle, int events, bool recursive) | 327 DirectoryWatchHandle(HANDLE handle, int events, bool recursive) |
345 : Handle(handle), | 328 : DescriptorInfoSingleMixin(reinterpret_cast<intptr_t>(handle)), |
346 events_(events), | 329 events_(events), |
347 recursive_(recursive) { | 330 recursive_(recursive) { |
348 type_ = kDirectoryWatch; | 331 type_ = kDirectoryWatch; |
349 } | 332 } |
350 | 333 |
351 virtual void EnsureInitialized(EventHandlerImplementation* event_handler); | 334 virtual void EnsureInitialized(EventHandlerImplementation* event_handler); |
352 virtual bool IsClosed(); | 335 virtual bool IsClosed(); |
353 | 336 |
354 virtual bool IssueRead(); | 337 virtual bool IssueRead(); |
355 | 338 |
356 void Stop(); | 339 void Stop(); |
357 | 340 |
358 private: | 341 private: |
359 int events_; | 342 int events_; |
360 bool recursive_; | 343 bool recursive_; |
361 }; | 344 }; |
362 | 345 |
363 | 346 |
364 class SocketHandle : public Handle { | 347 class SocketHandle : public Handle { |
365 public: | 348 public: |
366 SOCKET socket() const { return socket_; } | 349 SOCKET socket() const { return socket_; } |
367 | 350 |
368 protected: | 351 protected: |
369 explicit SocketHandle(SOCKET s) | 352 explicit SocketHandle(intptr_t s) |
370 : Handle(reinterpret_cast<HANDLE>(s)), | 353 : Handle(s), |
371 socket_(s) {} | |
372 SocketHandle(SOCKET s, Dart_Port port) | |
373 : Handle(reinterpret_cast<HANDLE>(s), port), | |
374 socket_(s) {} | 354 socket_(s) {} |
375 | 355 |
376 virtual void HandleIssueError(); | 356 virtual void HandleIssueError(); |
377 | 357 |
378 private: | 358 private: |
379 const SOCKET socket_; | 359 const SOCKET socket_; |
380 }; | 360 }; |
381 | 361 |
382 | 362 |
383 // Information on listen sockets. | 363 // Information on listen sockets. |
384 class ListenSocket : public SocketHandle { | 364 class ListenSocket : public DescriptorInfoMultipleMixin<SocketHandle> { |
385 public: | 365 public: |
386 explicit ListenSocket(SOCKET s) : SocketHandle(s), | 366 explicit ListenSocket(intptr_t s) : DescriptorInfoMultipleMixin(s), |
387 AcceptEx_(NULL), | 367 AcceptEx_(NULL), |
388 pending_accept_count_(0), | 368 pending_accept_count_(0), |
389 accepted_head_(NULL), | 369 accepted_head_(NULL), |
390 accepted_tail_(NULL) { | 370 accepted_tail_(NULL), |
| 371 accepted_count_(0) { |
391 type_ = kListenSocket; | 372 type_ = kListenSocket; |
392 } | 373 } |
393 virtual ~ListenSocket() { | 374 virtual ~ListenSocket() { |
394 ASSERT(!HasPendingAccept()); | 375 ASSERT(!HasPendingAccept()); |
395 ASSERT(accepted_head_ == NULL); | 376 ASSERT(accepted_head_ == NULL); |
396 ASSERT(accepted_tail_ == NULL); | 377 ASSERT(accepted_tail_ == NULL); |
397 } | 378 } |
398 | 379 |
399 // Socket interface exposing normal socket operations. | 380 // Socket interface exposing normal socket operations. |
400 ClientSocket* Accept(); | 381 ClientSocket* Accept(); |
401 bool CanAccept(); | 382 bool CanAccept(); |
402 | 383 |
403 // Internal interface used by the event handler. | 384 // Internal interface used by the event handler. |
404 bool HasPendingAccept() { return pending_accept_count_ > 0; } | 385 bool HasPendingAccept() { return pending_accept_count_ > 0; } |
405 bool IssueAccept(); | 386 bool IssueAccept(); |
406 void AcceptComplete(OverlappedBuffer* buffer, HANDLE completion_port); | 387 void AcceptComplete(OverlappedBuffer* buffer, HANDLE completion_port); |
407 | 388 |
408 virtual void EnsureInitialized( | 389 virtual void EnsureInitialized( |
409 EventHandlerImplementation* event_handler); | 390 EventHandlerImplementation* event_handler); |
410 virtual void DoClose(); | 391 virtual void DoClose(); |
411 virtual bool IsClosed(); | 392 virtual bool IsClosed(); |
412 | 393 |
413 int pending_accept_count() { return pending_accept_count_; } | 394 int pending_accept_count() { return pending_accept_count_; } |
414 | 395 |
| 396 int accepted_count() { return accepted_count_; } |
| 397 |
415 private: | 398 private: |
416 bool LoadAcceptEx(); | 399 bool LoadAcceptEx(); |
417 | 400 |
418 LPFN_ACCEPTEX AcceptEx_; | 401 LPFN_ACCEPTEX AcceptEx_; |
| 402 |
| 403 // The number of asynchronous `IssueAccept` operations which haven't completed |
| 404 // yet. |
419 int pending_accept_count_; | 405 int pending_accept_count_; |
| 406 |
420 // Linked list of accepted connections provided by completion code. Ready to | 407 // Linked list of accepted connections provided by completion code. Ready to |
421 // be handed over through accept. | 408 // be handed over through accept. |
422 ClientSocket* accepted_head_; | 409 ClientSocket* accepted_head_; |
423 ClientSocket* accepted_tail_; | 410 ClientSocket* accepted_tail_; |
| 411 |
| 412 // The number of accepted connections which are waiting to be removed from |
| 413 // this queue and processed by dart isolates. |
| 414 int accepted_count_; |
424 }; | 415 }; |
425 | 416 |
426 | 417 |
427 // Information on connected sockets. | 418 // Information on connected sockets. |
428 class ClientSocket : public SocketHandle { | 419 class ClientSocket : public DescriptorInfoSingleMixin<SocketHandle> { |
429 public: | 420 public: |
430 explicit ClientSocket(SOCKET s) : SocketHandle(s), | 421 explicit ClientSocket(intptr_t s) : DescriptorInfoSingleMixin(s), |
431 DisconnectEx_(NULL), | 422 DisconnectEx_(NULL), |
432 next_(NULL), | 423 next_(NULL), |
433 connected_(false), | 424 connected_(false), |
434 closed_(false) { | 425 closed_(false) { |
435 LoadDisconnectEx(); | 426 LoadDisconnectEx(); |
436 type_ = kClientSocket; | 427 type_ = kClientSocket; |
437 } | 428 } |
438 | 429 |
439 ClientSocket(SOCKET s, Dart_Port port) : SocketHandle(s, port), | |
440 DisconnectEx_(NULL), | |
441 next_(NULL), | |
442 connected_(false), | |
443 closed_(false) { | |
444 LoadDisconnectEx(); | |
445 type_ = kClientSocket; | |
446 } | |
447 | |
448 virtual ~ClientSocket() { | 430 virtual ~ClientSocket() { |
449 // Don't delete this object until all pending requests have been handled. | 431 // Don't delete this object until all pending requests have been handled. |
450 ASSERT(!HasPendingRead()); | 432 ASSERT(!HasPendingRead()); |
451 ASSERT(!HasPendingWrite()); | 433 ASSERT(!HasPendingWrite()); |
452 ASSERT(next_ == NULL); | 434 ASSERT(next_ == NULL); |
453 ASSERT(closed_ == true); | 435 ASSERT(closed_ == true); |
454 } | 436 } |
455 | 437 |
456 void Shutdown(int how); | 438 void Shutdown(int how); |
457 | 439 |
(...skipping 21 matching lines...) Expand all Loading... |
479 private: | 461 private: |
480 bool LoadDisconnectEx(); | 462 bool LoadDisconnectEx(); |
481 | 463 |
482 LPFN_DISCONNECTEX DisconnectEx_; | 464 LPFN_DISCONNECTEX DisconnectEx_; |
483 ClientSocket* next_; | 465 ClientSocket* next_; |
484 bool connected_; | 466 bool connected_; |
485 bool closed_; | 467 bool closed_; |
486 }; | 468 }; |
487 | 469 |
488 | 470 |
489 class DatagramSocket : public SocketHandle { | 471 class DatagramSocket : public DescriptorInfoSingleMixin<SocketHandle> { |
490 public: | 472 public: |
491 explicit DatagramSocket(SOCKET s) : SocketHandle(s) { | 473 explicit DatagramSocket(intptr_t s) : DescriptorInfoSingleMixin(s) { |
492 type_ = kDatagramSocket; | 474 type_ = kDatagramSocket; |
493 } | 475 } |
494 | 476 |
495 virtual ~DatagramSocket() { | 477 virtual ~DatagramSocket() { |
496 // Don't delete this object until all pending requests have been handled. | 478 // Don't delete this object until all pending requests have been handled. |
497 ASSERT(!HasPendingRead()); | 479 ASSERT(!HasPendingRead()); |
498 ASSERT(!HasPendingWrite()); | 480 ASSERT(!HasPendingWrite()); |
499 } | 481 } |
500 | 482 |
501 // Internal interface used by the event handler. | 483 // Internal interface used by the event handler. |
(...skipping 14 matching lines...) Expand all Loading... |
516 void SendData(intptr_t id, Dart_Port dart_port, int64_t data); | 498 void SendData(intptr_t id, Dart_Port dart_port, int64_t data); |
517 void Start(EventHandler* handler); | 499 void Start(EventHandler* handler); |
518 void Shutdown(); | 500 void Shutdown(); |
519 | 501 |
520 static void EventHandlerEntry(uword args); | 502 static void EventHandlerEntry(uword args); |
521 | 503 |
522 int64_t GetTimeout(); | 504 int64_t GetTimeout(); |
523 void HandleInterrupt(InterruptMessage* msg); | 505 void HandleInterrupt(InterruptMessage* msg); |
524 void HandleTimeout(); | 506 void HandleTimeout(); |
525 void HandleAccept(ListenSocket* listen_socket, OverlappedBuffer* buffer); | 507 void HandleAccept(ListenSocket* listen_socket, OverlappedBuffer* buffer); |
| 508 void TryDispatchingPendingAccepts(ListenSocket *listen_socket); |
526 void HandleRead(Handle* handle, int bytes, OverlappedBuffer* buffer); | 509 void HandleRead(Handle* handle, int bytes, OverlappedBuffer* buffer); |
527 void HandleRecvFrom(Handle* handle, int bytes, OverlappedBuffer* buffer); | 510 void HandleRecvFrom(Handle* handle, int bytes, OverlappedBuffer* buffer); |
528 void HandleWrite(Handle* handle, int bytes, OverlappedBuffer* buffer); | 511 void HandleWrite(Handle* handle, int bytes, OverlappedBuffer* buffer); |
529 void HandleDisconnect(ClientSocket* client_socket, | 512 void HandleDisconnect(ClientSocket* client_socket, |
530 int bytes, | 513 int bytes, |
531 OverlappedBuffer* buffer); | 514 OverlappedBuffer* buffer); |
532 void HandleConnect(ClientSocket* client_socket, | 515 void HandleConnect(ClientSocket* client_socket, |
533 int bytes, | 516 int bytes, |
534 OverlappedBuffer* buffer); | 517 OverlappedBuffer* buffer); |
535 void HandleIOCompletion(DWORD bytes, ULONG_PTR key, OVERLAPPED* overlapped); | 518 void HandleIOCompletion(DWORD bytes, ULONG_PTR key, OVERLAPPED* overlapped); |
536 | 519 |
537 HANDLE completion_port() { return completion_port_; } | 520 HANDLE completion_port() { return completion_port_; } |
538 | 521 |
539 private: | 522 private: |
540 ClientSocket* client_sockets_head_; | 523 ClientSocket* client_sockets_head_; |
541 | 524 |
542 TimeoutQueue timeout_queue_; // Time for next timeout. | 525 TimeoutQueue timeout_queue_; // Time for next timeout. |
543 bool shutdown_; | 526 bool shutdown_; |
544 HANDLE completion_port_; | 527 HANDLE completion_port_; |
545 }; | 528 }; |
546 | 529 |
547 } // namespace bin | 530 } // namespace bin |
548 } // namespace dart | 531 } // namespace dart |
549 | 532 |
550 #endif // BIN_EVENTHANDLER_WIN_H_ | 533 #endif // BIN_EVENTHANDLER_WIN_H_ |
OLD | NEW |