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 RUNTIME_BIN_EVENTHANDLER_WIN_H_ | 5 #ifndef RUNTIME_BIN_EVENTHANDLER_WIN_H_ |
6 #define RUNTIME_BIN_EVENTHANDLER_WIN_H_ | 6 #define RUNTIME_BIN_EVENTHANDLER_WIN_H_ |
7 | 7 |
8 #if !defined(RUNTIME_BIN_EVENTHANDLER_H_) | 8 #if !defined(RUNTIME_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 |
11 | 11 |
12 #include <mswsock.h> | 12 #include <mswsock.h> |
13 #include <winsock2.h> | 13 #include <winsock2.h> |
14 #include <ws2tcpip.h> | 14 #include <ws2tcpip.h> |
15 | 15 |
16 #include "bin/builtin.h" | 16 #include "bin/builtin.h" |
| 17 #include "bin/reference_counting.h" |
17 #include "bin/thread.h" | 18 #include "bin/thread.h" |
18 | 19 |
19 namespace dart { | 20 namespace dart { |
20 namespace bin { | 21 namespace bin { |
21 | 22 |
22 // Forward declarations. | 23 // Forward declarations. |
23 class EventHandlerImplementation; | 24 class EventHandlerImplementation; |
24 class Handle; | 25 class Handle; |
25 class FileHandle; | 26 class FileHandle; |
26 class SocketHandle; | 27 class SocketHandle; |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
63 | 64 |
64 // Write data to a buffer before sending it. Returns the number of bytes | 65 // Write data to a buffer before sending it. Returns the number of bytes |
65 // actually written to the buffer. Calls to Write will always write to | 66 // actually written to the buffer. Calls to Write will always write to |
66 // the buffer from the begining. | 67 // the buffer from the begining. |
67 int Write(const void* buffer, int num_bytes); | 68 int Write(const void* buffer, int num_bytes); |
68 | 69 |
69 // Check the amount of data in a read buffer which has not been read yet. | 70 // Check the amount of data in a read buffer which has not been read yet. |
70 int GetRemainingLength(); | 71 int GetRemainingLength(); |
71 bool IsEmpty() { return GetRemainingLength() == 0; } | 72 bool IsEmpty() { return GetRemainingLength() == 0; } |
72 | 73 |
73 Operation operation() { return operation_; } | 74 Operation operation() const { return operation_; } |
74 SOCKET client() { return client_; } | 75 SOCKET client() const { return client_; } |
75 char* GetBufferStart() { return reinterpret_cast<char*>(&buffer_data_); } | 76 char* GetBufferStart() { return reinterpret_cast<char*>(&buffer_data_); } |
76 int GetBufferSize() { return buflen_; } | 77 int GetBufferSize() const { return buflen_; } |
77 struct sockaddr* from() { | 78 struct sockaddr* from() const { |
78 return from_; | 79 return from_; |
79 } | 80 } |
80 socklen_t* from_len_addr() { return from_len_addr_; } | 81 socklen_t* from_len_addr() const { return from_len_addr_; } |
81 socklen_t from_len() { return from_ == NULL ? 0 : *from_len_addr_; } | 82 socklen_t from_len() const { return from_ == NULL ? 0 : *from_len_addr_; } |
82 | 83 |
83 // Returns the address of the OVERLAPPED structure with all fields | 84 // Returns the address of the OVERLAPPED structure with all fields |
84 // initialized to zero. | 85 // initialized to zero. |
85 OVERLAPPED* GetCleanOverlapped() { | 86 OVERLAPPED* GetCleanOverlapped() { |
86 memset(&overlapped_, 0, sizeof(overlapped_)); | 87 memset(&overlapped_, 0, sizeof(overlapped_)); |
87 return &overlapped_; | 88 return &overlapped_; |
88 } | 89 } |
89 | 90 |
90 // Returns a WASBUF structure initialized with the data in this IO buffer. | 91 // Returns a WASBUF structure initialized with the data in this IO buffer. |
91 WSABUF* GetWASBUF() { | 92 WSABUF* GetWASBUF() { |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
152 // object as the object is allocated larger than it's definition | 153 // object as the object is allocated larger than it's definition |
153 // indicate to extend this array. | 154 // indicate to extend this array. |
154 uint8_t buffer_data_[1]; | 155 uint8_t buffer_data_[1]; |
155 | 156 |
156 DISALLOW_COPY_AND_ASSIGN(OverlappedBuffer); | 157 DISALLOW_COPY_AND_ASSIGN(OverlappedBuffer); |
157 }; | 158 }; |
158 | 159 |
159 | 160 |
160 // Abstract super class for holding information on listen and connected | 161 // Abstract super class for holding information on listen and connected |
161 // sockets. | 162 // sockets. |
162 class Handle : public DescriptorInfoBase { | 163 class Handle : public ReferenceCounted<Handle>, public DescriptorInfoBase { |
163 public: | 164 public: |
164 enum Type { | 165 enum Type { |
165 kFile, | 166 kFile, |
166 kStd, | 167 kStd, |
167 kDirectoryWatch, | 168 kDirectoryWatch, |
168 kClientSocket, | 169 kClientSocket, |
169 kListenSocket, | 170 kListenSocket, |
170 kDatagramSocket | 171 kDatagramSocket |
171 }; | 172 }; |
172 | 173 |
173 virtual ~Handle(); | |
174 | |
175 // Socket interface exposing normal socket operations. | 174 // Socket interface exposing normal socket operations. |
176 intptr_t Available(); | 175 intptr_t Available(); |
177 intptr_t Read(void* buffer, intptr_t num_bytes); | 176 intptr_t Read(void* buffer, intptr_t num_bytes); |
178 intptr_t RecvFrom(void* buffer, | 177 intptr_t RecvFrom(void* buffer, |
179 intptr_t num_bytes, | 178 intptr_t num_bytes, |
180 struct sockaddr* sa, | 179 struct sockaddr* sa, |
181 socklen_t addr_len); | 180 socklen_t addr_len); |
182 virtual intptr_t Write(const void* buffer, intptr_t num_bytes); | 181 virtual intptr_t Write(const void* buffer, intptr_t num_bytes); |
183 virtual intptr_t SendTo(const void* buffer, | 182 virtual intptr_t SendTo(const void* buffer, |
184 intptr_t num_bytes, | 183 intptr_t num_bytes, |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
232 } | 231 } |
233 bool SupportsOverlappedIO() { | 232 bool SupportsOverlappedIO() { |
234 return (flags_ & (1 << kDoesNotSupportOverlappedIO)) == 0; | 233 return (flags_ & (1 << kDoesNotSupportOverlappedIO)) == 0; |
235 } | 234 } |
236 | 235 |
237 void ReadSyncCompleteAsync(); | 236 void ReadSyncCompleteAsync(); |
238 | 237 |
239 DWORD last_error() { return last_error_; } | 238 DWORD last_error() { return last_error_; } |
240 void set_last_error(DWORD last_error) { last_error_ = last_error; } | 239 void set_last_error(DWORD last_error) { last_error_ = last_error; } |
241 | 240 |
| 241 void set_completion_port(HANDLE completion_port) { |
| 242 completion_port_ = completion_port; |
| 243 } |
| 244 |
| 245 void set_event_handler(EventHandlerImplementation* event_handler) { |
| 246 event_handler_ = event_handler; |
| 247 } |
| 248 |
242 protected: | 249 protected: |
243 // For access to monitor_; | 250 // For access to monitor_; |
244 friend class EventHandlerImplementation; | 251 friend class EventHandlerImplementation; |
245 | 252 |
246 enum Flags { | 253 enum Flags { |
247 kClosing = 0, | 254 kClosing = 0, |
248 kCloseRead = 1, | 255 kCloseRead = 1, |
249 kCloseWrite = 2, | 256 kCloseWrite = 2, |
250 kDoesNotSupportOverlappedIO = 3, | 257 kDoesNotSupportOverlappedIO = 3, |
251 kError = 4 | 258 kError = 4 |
252 }; | 259 }; |
253 | 260 |
254 explicit Handle(intptr_t handle); | 261 explicit Handle(intptr_t handle); |
| 262 virtual ~Handle(); |
255 | 263 |
256 virtual void HandleIssueError(); | 264 virtual void HandleIssueError(); |
257 | 265 |
258 Monitor* monitor_; | 266 Monitor* monitor_; |
259 Type type_; | 267 Type type_; |
260 HANDLE handle_; | 268 HANDLE handle_; |
261 HANDLE completion_port_; | 269 HANDLE completion_port_; |
262 EventHandlerImplementation* event_handler_; | 270 EventHandlerImplementation* event_handler_; |
263 | 271 |
264 OverlappedBuffer* data_ready_; // Buffer for data ready to be read. | 272 OverlappedBuffer* data_ready_; // Buffer for data ready to be read. |
265 OverlappedBuffer* pending_read_; // Buffer for pending read. | 273 OverlappedBuffer* pending_read_; // Buffer for pending read. |
266 OverlappedBuffer* pending_write_; // Buffer for pending write | 274 OverlappedBuffer* pending_write_; // Buffer for pending write |
267 | 275 |
268 DWORD last_error_; | 276 DWORD last_error_; |
269 | 277 |
270 ThreadId read_thread_id_; | 278 ThreadId read_thread_id_; |
271 HANDLE read_thread_handle_; | 279 HANDLE read_thread_handle_; |
272 bool read_thread_starting_; | 280 bool read_thread_starting_; |
273 bool read_thread_finished_; | 281 bool read_thread_finished_; |
274 | 282 |
275 private: | 283 private: |
276 void WaitForReadThreadStarted(); | 284 void WaitForReadThreadStarted(); |
277 void NotifyReadThreadStarted(); | 285 void NotifyReadThreadStarted(); |
278 void WaitForReadThreadFinished(); | 286 void WaitForReadThreadFinished(); |
279 void NotifyReadThreadFinished(); | 287 void NotifyReadThreadFinished(); |
280 | 288 |
281 int flags_; | 289 int flags_; |
282 | 290 |
| 291 friend class ReferenceCounted<Handle>; |
283 DISALLOW_COPY_AND_ASSIGN(Handle); | 292 DISALLOW_COPY_AND_ASSIGN(Handle); |
284 }; | 293 }; |
285 | 294 |
286 | 295 |
287 class FileHandle : public DescriptorInfoSingleMixin<Handle> { | 296 class FileHandle : public DescriptorInfoSingleMixin<Handle> { |
288 public: | 297 public: |
289 explicit FileHandle(HANDLE handle) | 298 explicit FileHandle(HANDLE handle) |
290 : DescriptorInfoSingleMixin(reinterpret_cast<intptr_t>(handle), true) { | 299 : DescriptorInfoSingleMixin(reinterpret_cast<intptr_t>(handle), true) { |
291 type_ = kFile; | 300 type_ = kFile; |
292 } | 301 } |
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
461 virtual bool IsClosed(); | 470 virtual bool IsClosed(); |
462 | 471 |
463 ClientSocket* next() { return next_; } | 472 ClientSocket* next() { return next_; } |
464 void set_next(ClientSocket* next) { next_ = next; } | 473 void set_next(ClientSocket* next) { next_ = next; } |
465 | 474 |
466 void mark_connected() { connected_ = true; } | 475 void mark_connected() { connected_ = true; } |
467 bool is_connected() const { return connected_; } | 476 bool is_connected() const { return connected_; } |
468 | 477 |
469 void mark_closed() { closed_ = true; } | 478 void mark_closed() { closed_ = true; } |
470 | 479 |
| 480 #if defined(DEBUG) |
| 481 static intptr_t disconnecting() { return disconnecting_; } |
| 482 #endif |
| 483 |
471 private: | 484 private: |
472 bool LoadDisconnectEx(); | 485 bool LoadDisconnectEx(); |
473 | 486 |
474 LPFN_DISCONNECTEX DisconnectEx_; | 487 LPFN_DISCONNECTEX DisconnectEx_; |
475 ClientSocket* next_; | 488 ClientSocket* next_; |
476 bool connected_; | 489 bool connected_; |
477 bool closed_; | 490 bool closed_; |
478 | 491 |
| 492 #if defined(DEBUG) |
| 493 static intptr_t disconnecting_; |
| 494 #endif |
| 495 |
479 DISALLOW_COPY_AND_ASSIGN(ClientSocket); | 496 DISALLOW_COPY_AND_ASSIGN(ClientSocket); |
480 }; | 497 }; |
481 | 498 |
482 | 499 |
483 class DatagramSocket : public DescriptorInfoSingleMixin<SocketHandle> { | 500 class DatagramSocket : public DescriptorInfoSingleMixin<SocketHandle> { |
484 public: | 501 public: |
485 explicit DatagramSocket(intptr_t s) : DescriptorInfoSingleMixin(s, true) { | 502 explicit DatagramSocket(intptr_t s) : DescriptorInfoSingleMixin(s, true) { |
486 type_ = kDatagramSocket; | 503 type_ = kDatagramSocket; |
487 } | 504 } |
488 | 505 |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
526 void HandleRecvFrom(Handle* handle, int bytes, OverlappedBuffer* buffer); | 543 void HandleRecvFrom(Handle* handle, int bytes, OverlappedBuffer* buffer); |
527 void HandleWrite(Handle* handle, int bytes, OverlappedBuffer* buffer); | 544 void HandleWrite(Handle* handle, int bytes, OverlappedBuffer* buffer); |
528 void HandleDisconnect(ClientSocket* client_socket, | 545 void HandleDisconnect(ClientSocket* client_socket, |
529 int bytes, | 546 int bytes, |
530 OverlappedBuffer* buffer); | 547 OverlappedBuffer* buffer); |
531 void HandleConnect(ClientSocket* client_socket, | 548 void HandleConnect(ClientSocket* client_socket, |
532 int bytes, | 549 int bytes, |
533 OverlappedBuffer* buffer); | 550 OverlappedBuffer* buffer); |
534 void HandleIOCompletion(DWORD bytes, ULONG_PTR key, OVERLAPPED* overlapped); | 551 void HandleIOCompletion(DWORD bytes, ULONG_PTR key, OVERLAPPED* overlapped); |
535 | 552 |
| 553 void HandleCompletionOrInterrupt(BOOL ok, |
| 554 DWORD bytes, |
| 555 ULONG_PTR key, |
| 556 OVERLAPPED* overlapped); |
| 557 |
536 HANDLE completion_port() { return completion_port_; } | 558 HANDLE completion_port() { return completion_port_; } |
537 | 559 |
538 private: | 560 private: |
539 ClientSocket* client_sockets_head_; | |
540 | |
541 Monitor* startup_monitor_; | 561 Monitor* startup_monitor_; |
542 ThreadId handler_thread_id_; | 562 ThreadId handler_thread_id_; |
543 HANDLE handler_thread_handle_; | 563 HANDLE handler_thread_handle_; |
544 | 564 |
545 TimeoutQueue timeout_queue_; // Time for next timeout. | 565 TimeoutQueue timeout_queue_; // Time for next timeout. |
546 bool shutdown_; | 566 bool shutdown_; |
547 HANDLE completion_port_; | 567 HANDLE completion_port_; |
548 | 568 |
549 DISALLOW_COPY_AND_ASSIGN(EventHandlerImplementation); | 569 DISALLOW_COPY_AND_ASSIGN(EventHandlerImplementation); |
550 }; | 570 }; |
551 | 571 |
552 } // namespace bin | 572 } // namespace bin |
553 } // namespace dart | 573 } // namespace dart |
554 | 574 |
555 #endif // RUNTIME_BIN_EVENTHANDLER_WIN_H_ | 575 #endif // RUNTIME_BIN_EVENTHANDLER_WIN_H_ |
OLD | NEW |