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