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 |
11 | 11 |
12 #include <winsock2.h> | 12 #include <winsock2.h> |
13 #include <ws2tcpip.h> | |
Anders Johnsen
2013/12/12 12:19:58
This looks odd - importing a TCP/IP header for UDP
Søren Gjesse
2013/12/12 15:44:39
It contains the typedef for socklen_t.
| |
13 #include <mswsock.h> | 14 #include <mswsock.h> |
14 | 15 |
15 #include "bin/builtin.h" | 16 #include "bin/builtin.h" |
16 #include "platform/thread.h" | 17 #include "platform/thread.h" |
17 | 18 |
18 | 19 |
19 namespace dart { | 20 namespace dart { |
20 namespace bin { | 21 namespace bin { |
21 | 22 |
22 // Forward declarations. | 23 // Forward declarations. |
(...skipping 10 matching lines...) Expand all Loading... | |
33 Dart_Port dart_port; | 34 Dart_Port dart_port; |
34 int64_t data; | 35 int64_t data; |
35 }; | 36 }; |
36 | 37 |
37 | 38 |
38 // An OverlappedBuffer encapsulates the OVERLAPPED structure and the | 39 // An OverlappedBuffer encapsulates the OVERLAPPED structure and the |
39 // associated data buffer. For accept it also contains the pre-created | 40 // associated data buffer. For accept it also contains the pre-created |
40 // socket for the client. | 41 // socket for the client. |
41 class OverlappedBuffer { | 42 class OverlappedBuffer { |
42 public: | 43 public: |
43 enum Operation { kAccept, kRead, kWrite, kDisconnect }; | 44 enum Operation { kAccept, kRead, kRecvFrom, kWrite, kSendTo, kDisconnect }; |
44 | 45 |
45 static OverlappedBuffer* AllocateAcceptBuffer(int buffer_size); | 46 static OverlappedBuffer* AllocateAcceptBuffer(int buffer_size); |
46 static OverlappedBuffer* AllocateReadBuffer(int buffer_size); | 47 static OverlappedBuffer* AllocateReadBuffer(int buffer_size); |
48 static OverlappedBuffer* AllocateRecvFromBuffer(int buffer_size); | |
47 static OverlappedBuffer* AllocateWriteBuffer(int buffer_size); | 49 static OverlappedBuffer* AllocateWriteBuffer(int buffer_size); |
50 static OverlappedBuffer* AllocateSendToBuffer(int buffer_size); | |
48 static OverlappedBuffer* AllocateDisconnectBuffer(); | 51 static OverlappedBuffer* AllocateDisconnectBuffer(); |
49 static void DisposeBuffer(OverlappedBuffer* buffer); | 52 static void DisposeBuffer(OverlappedBuffer* buffer); |
50 | 53 |
51 // Find the IO buffer from the OVERLAPPED address. | 54 // Find the IO buffer from the OVERLAPPED address. |
52 static OverlappedBuffer* GetFromOverlapped(OVERLAPPED* overlapped); | 55 static OverlappedBuffer* GetFromOverlapped(OVERLAPPED* overlapped); |
53 | 56 |
54 // Read data from a buffer which has been received. It will read up | 57 // Read data from a buffer which has been received. It will read up |
55 // to num_bytes bytes of data returning the actual number of bytes | 58 // to num_bytes bytes of data returning the actual number of bytes |
56 // read. This will update the index of the next byte in the buffer | 59 // read. This will update the index of the next byte in the buffer |
57 // so calling Read several times will keep returning new data from | 60 // so calling Read several times will keep returning new data from |
58 // the buffer until all data have been read. | 61 // the buffer until all data have been read. |
59 int Read(void* buffer, int num_bytes); | 62 int Read(void* buffer, int num_bytes); |
60 | 63 |
61 // Write data to a buffer before sending it. Returns the number of bytes | 64 // Write data to a buffer before sending it. Returns the number of bytes |
62 // actually written to the buffer. Calls to Write will always write to | 65 // actually written to the buffer. Calls to Write will always write to |
63 // the buffer from the begining. | 66 // the buffer from the begining. |
64 int Write(const void* buffer, int num_bytes); | 67 int Write(const void* buffer, int num_bytes); |
65 | 68 |
66 // Check the amount of data in a read buffer which has not been read yet. | 69 // Check the amount of data in a read buffer which has not been read yet. |
67 int GetRemainingLength(); | 70 int GetRemainingLength(); |
68 bool IsEmpty() { return GetRemainingLength() == 0; } | 71 bool IsEmpty() { return GetRemainingLength() == 0; } |
69 | 72 |
70 Operation operation() { return operation_; } | 73 Operation operation() { return operation_; } |
71 SOCKET client() { return client_; } | 74 SOCKET client() { return client_; } |
72 char* GetBufferStart() { return reinterpret_cast<char*>(&buffer_data_); } | 75 char* GetBufferStart() { return reinterpret_cast<char*>(&buffer_data_); } |
73 int GetBufferSize() { return buflen_; } | 76 int GetBufferSize() { return buflen_; } |
77 struct sockaddr* from() { return from_; } | |
78 socklen_t* from_len_addr() { return from_len_addr_; } | |
79 socklen_t from_len() { return from_ == NULL ? 0 : *from_len_addr_; } | |
74 | 80 |
75 // Returns the address of the OVERLAPPED structure with all fields | 81 // Returns the address of the OVERLAPPED structure with all fields |
76 // initialized to zero. | 82 // initialized to zero. |
77 OVERLAPPED* GetCleanOverlapped() { | 83 OVERLAPPED* GetCleanOverlapped() { |
78 memset(&overlapped_, 0, sizeof(overlapped_)); | 84 memset(&overlapped_, 0, sizeof(overlapped_)); |
79 return &overlapped_; | 85 return &overlapped_; |
80 } | 86 } |
81 | 87 |
82 // Returns a WASBUF structure initialized with the data in this IO buffer. | 88 // Returns a WASBUF structure initialized with the data in this IO buffer. |
83 WSABUF* GetWASBUF() { | 89 WSABUF* GetWASBUF() { |
84 wbuf_.buf = GetBufferStart(); | 90 wbuf_.buf = GetBufferStart(); |
85 wbuf_.len = GetBufferSize(); | 91 wbuf_.len = GetBufferSize(); |
86 return &wbuf_; | 92 return &wbuf_; |
87 }; | 93 }; |
88 | 94 |
89 void set_data_length(int data_length) { data_length_ = data_length; } | 95 void set_data_length(int data_length) { data_length_ = data_length; } |
90 | 96 |
91 private: | 97 private: |
92 OverlappedBuffer(int buffer_size, Operation operation) | 98 OverlappedBuffer(int buffer_size, Operation operation) |
93 : operation_(operation), buflen_(buffer_size) { | 99 : operation_(operation), buflen_(buffer_size) { |
94 memset(GetBufferStart(), 0, GetBufferSize()); | 100 memset(GetBufferStart(), 0, GetBufferSize()); |
101 if (operation == kRecvFrom) { | |
102 // Reserve part of the buffer for the length of source sockaddr | |
103 // and source sockaddr. | |
104 static int additional_size = | |
Anders Johnsen
2013/12/12 12:19:58
static -> const?
Søren Gjesse
2013/12/12 15:44:39
Done.
| |
105 sizeof(struct sockaddr_storage) + sizeof(socklen_t); | |
Anders Johnsen
2013/12/12 12:19:58
Indentation
Søren Gjesse
2013/12/12 15:44:39
Done.
| |
106 ASSERT(buflen_ > additional_size); | |
107 buflen_ -= additional_size; | |
108 from_len_addr_ = reinterpret_cast<socklen_t*>( | |
109 GetBufferStart() + GetBufferSize()); | |
110 *from_len_addr_ = sizeof(struct sockaddr_storage); | |
111 from_ = reinterpret_cast<struct sockaddr*>(from_len_addr_ + 1); | |
112 } else { | |
113 from_len_addr_ = NULL; | |
114 from_ = NULL; | |
115 } | |
95 index_ = 0; | 116 index_ = 0; |
96 data_length_ = 0; | 117 data_length_ = 0; |
97 if (operation_ == kAccept) { | 118 if (operation_ == kAccept) { |
98 client_ = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); | 119 client_ = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); |
99 } | 120 } |
100 } | 121 } |
101 | 122 |
102 void* operator new(size_t size, int buffer_size) { | 123 void* operator new(size_t size, int buffer_size) { |
103 return malloc(size + buffer_size); | 124 return malloc(size + buffer_size); |
104 } | 125 } |
105 | 126 |
106 void operator delete(void* buffer) { | 127 void operator delete(void* buffer) { |
107 free(buffer); | 128 free(buffer); |
108 } | 129 } |
109 | 130 |
131 // Allocate an overlapped buffer for thse specified amount of data and | |
132 // operation. Some operations need additional buffer space, which is | |
133 // handled by this method. | |
110 static OverlappedBuffer* AllocateBuffer(int buffer_size, | 134 static OverlappedBuffer* AllocateBuffer(int buffer_size, |
111 Operation operation); | 135 Operation operation); |
112 | 136 |
113 OVERLAPPED overlapped_; // OVERLAPPED structure for overlapped IO. | 137 OVERLAPPED overlapped_; // OVERLAPPED structure for overlapped IO. |
114 SOCKET client_; // Used for AcceptEx client socket. | 138 SOCKET client_; // Used for AcceptEx client socket. |
115 int buflen_; // Length of the buffer. | 139 int buflen_; // Length of the buffer. |
116 Operation operation_; // Type of operation issued. | 140 Operation operation_; // Type of operation issued. |
117 | 141 |
118 int index_; // Index for next read from read buffer. | 142 int index_; // Index for next read from read buffer. |
119 int data_length_; // Length of the actual data in the buffer. | 143 int data_length_; // Length of the actual data in the buffer. |
120 | 144 |
121 WSABUF wbuf_; // Structure for passing buffer to WSA functions. | 145 WSABUF wbuf_; // Structure for passing buffer to WSA functions. |
122 | 146 |
147 // For the recvfrom operation additional storace is allocated for the | |
148 // source sockaddr. | |
149 socklen_t* from_len_addr_; // Pointer to source sockaddr size storage. | |
150 struct sockaddr* from_; // Pointer to source sockaddr storage. | |
151 | |
123 // Buffer for recv/send/AcceptEx. This must be at the end of the | 152 // Buffer for recv/send/AcceptEx. This must be at the end of the |
124 // object as the object is allocated larger than it's definition | 153 // object as the object is allocated larger than it's definition |
125 // indicate to extend this array. | 154 // indicate to extend this array. |
126 uint8_t buffer_data_[1]; | 155 uint8_t buffer_data_[1]; |
127 }; | 156 }; |
128 | 157 |
129 | 158 |
130 // Abstract super class for holding information on listen and connected | 159 // Abstract super class for holding information on listen and connected |
131 // sockets. | 160 // sockets. |
132 class Handle { | 161 class Handle { |
133 public: | 162 public: |
134 enum Type { | 163 enum Type { |
135 kFile, | 164 kFile, |
136 kStd, | 165 kStd, |
137 kDirectoryWatch, | 166 kDirectoryWatch, |
138 kClientSocket, | 167 kClientSocket, |
139 kListenSocket | 168 kListenSocket, |
169 kDatagramSocket | |
140 }; | 170 }; |
141 | 171 |
142 class ScopedLock { | 172 class ScopedLock { |
143 public: | 173 public: |
144 explicit ScopedLock(Handle* handle) | 174 explicit ScopedLock(Handle* handle) |
145 : handle_(handle) { | 175 : handle_(handle) { |
146 handle_->Lock(); | 176 handle_->Lock(); |
147 } | 177 } |
148 ~ScopedLock() { | 178 ~ScopedLock() { |
149 handle_->Unlock(); | 179 handle_->Unlock(); |
150 } | 180 } |
151 | 181 |
152 private: | 182 private: |
153 Handle* handle_; | 183 Handle* handle_; |
154 }; | 184 }; |
155 | 185 |
156 virtual ~Handle(); | 186 virtual ~Handle(); |
157 | 187 |
158 // Socket interface exposing normal socket operations. | 188 // Socket interface exposing normal socket operations. |
159 int Available(); | 189 int Available(); |
160 int Read(void* buffer, int num_bytes); | 190 int Read(void* buffer, int num_bytes); |
191 int RecvFrom( | |
192 void* buffer, int num_bytes, struct sockaddr* sa, socklen_t addr_len); | |
161 virtual int Write(const void* buffer, int num_bytes); | 193 virtual int Write(const void* buffer, int num_bytes); |
194 virtual int SendTo(const void* buffer, | |
195 int num_bytes, | |
196 struct sockaddr* sa, | |
197 socklen_t sa_len); | |
162 | 198 |
163 // Internal interface used by the event handler. | 199 // Internal interface used by the event handler. |
164 virtual bool IssueRead(); | 200 virtual bool IssueRead(); |
201 virtual bool IssueRecvFrom(); | |
165 virtual bool IssueWrite(); | 202 virtual bool IssueWrite(); |
203 virtual bool IssueSendTo(struct sockaddr* sa, socklen_t sa_len); | |
166 bool HasPendingRead(); | 204 bool HasPendingRead(); |
167 bool HasPendingWrite(); | 205 bool HasPendingWrite(); |
168 void ReadComplete(OverlappedBuffer* buffer); | 206 void ReadComplete(OverlappedBuffer* buffer); |
207 void RecvFromComplete(OverlappedBuffer* buffer); | |
169 void WriteComplete(OverlappedBuffer* buffer); | 208 void WriteComplete(OverlappedBuffer* buffer); |
170 | 209 |
171 bool IsClosing() { return (flags_ & (1 << kClosing)) != 0; } | 210 bool IsClosing() { return (flags_ & (1 << kClosing)) != 0; } |
172 bool IsClosedRead() { return (flags_ & (1 << kCloseRead)) != 0; } | 211 bool IsClosedRead() { return (flags_ & (1 << kCloseRead)) != 0; } |
173 bool IsClosedWrite() { return (flags_ & (1 << kCloseWrite)) != 0; } | 212 bool IsClosedWrite() { return (flags_ & (1 << kCloseWrite)) != 0; } |
174 bool IsError() { return (flags_ & (1 << kError)) != 0; } | 213 bool IsError() { return (flags_ & (1 << kError)) != 0; } |
175 void MarkClosing() { flags_ |= (1 << kClosing); } | 214 void MarkClosing() { flags_ |= (1 << kClosing); } |
176 void MarkClosedRead() { flags_ |= (1 << kCloseRead); } | 215 void MarkClosedRead() { flags_ |= (1 << kCloseRead); } |
177 void MarkClosedWrite() { flags_ |= (1 << kCloseWrite); } | 216 void MarkClosedWrite() { flags_ |= (1 << kCloseWrite); } |
178 void MarkError() { flags_ |= (1 << kError); } | 217 void MarkError() { flags_ |= (1 << kError); } |
(...skipping 13 matching lines...) Expand all Loading... | |
192 void Close(); | 231 void Close(); |
193 virtual void DoClose(); | 232 virtual void DoClose(); |
194 virtual bool IsClosed() = 0; | 233 virtual bool IsClosed() = 0; |
195 | 234 |
196 void SetPortAndMask(Dart_Port port, intptr_t mask) { | 235 void SetPortAndMask(Dart_Port port, intptr_t mask) { |
197 port_ = port; | 236 port_ = port; |
198 mask_ = mask; | 237 mask_ = mask; |
199 } | 238 } |
200 Type type() { return type_; } | 239 Type type() { return type_; } |
201 bool is_file() { return type_ == kFile; } | 240 bool is_file() { return type_ == kFile; } |
202 bool is_socket() { return type_ == kListenSocket || type_ == kClientSocket; } | 241 bool is_socket() { return type_ == kListenSocket || |
242 type_ == kClientSocket || | |
243 type_ == kDatagramSocket; } | |
203 bool is_listen_socket() { return type_ == kListenSocket; } | 244 bool is_listen_socket() { return type_ == kListenSocket; } |
204 bool is_client_socket() { return type_ == kClientSocket; } | 245 bool is_client_socket() { return type_ == kClientSocket; } |
246 bool is_datagram_socket() { return type_ == kDatagramSocket; } | |
205 void set_mask(intptr_t mask) { mask_ = mask; } | 247 void set_mask(intptr_t mask) { mask_ = mask; } |
206 intptr_t mask() { return mask_; } | 248 intptr_t mask() { return mask_; } |
207 | 249 |
208 void MarkDoesNotSupportOverlappedIO() { | 250 void MarkDoesNotSupportOverlappedIO() { |
209 flags_ |= (1 << kDoesNotSupportOverlappedIO); | 251 flags_ |= (1 << kDoesNotSupportOverlappedIO); |
210 } | 252 } |
211 bool SupportsOverlappedIO() { | 253 bool SupportsOverlappedIO() { |
212 return (flags_ & (1 << kDoesNotSupportOverlappedIO)) == 0; | 254 return (flags_ & (1 << kDoesNotSupportOverlappedIO)) == 0; |
213 } | 255 } |
214 | 256 |
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
409 void set_next(ClientSocket* next) { next_ = next; } | 451 void set_next(ClientSocket* next) { next_ = next; } |
410 | 452 |
411 private: | 453 private: |
412 bool LoadDisconnectEx(); | 454 bool LoadDisconnectEx(); |
413 | 455 |
414 LPFN_DISCONNECTEX DisconnectEx_; | 456 LPFN_DISCONNECTEX DisconnectEx_; |
415 ClientSocket* next_; | 457 ClientSocket* next_; |
416 }; | 458 }; |
417 | 459 |
418 | 460 |
461 class DatagramSocket : public SocketHandle { | |
462 public: | |
463 explicit DatagramSocket(SOCKET s) : SocketHandle(s) { | |
464 type_ = kDatagramSocket; | |
465 } | |
466 | |
467 virtual ~DatagramSocket() { | |
468 // Don't delete this object until all pending requests have been handled. | |
469 ASSERT(!HasPendingRead()); | |
470 ASSERT(!HasPendingWrite()); | |
471 }; | |
472 | |
473 // Internal interface used by the event handler. | |
474 virtual bool IssueRecvFrom(); | |
475 virtual bool IssueSendTo(sockaddr* sa, socklen_t sa_len); | |
476 | |
477 virtual void EnsureInitialized(EventHandlerImplementation* event_handler); | |
478 virtual void DoClose(); | |
479 virtual bool IsClosed(); | |
480 }; | |
481 | |
419 // Event handler. | 482 // Event handler. |
420 class EventHandlerImplementation { | 483 class EventHandlerImplementation { |
421 public: | 484 public: |
422 EventHandlerImplementation(); | 485 EventHandlerImplementation(); |
423 virtual ~EventHandlerImplementation(); | 486 virtual ~EventHandlerImplementation(); |
424 | 487 |
425 void SendData(intptr_t id, Dart_Port dart_port, int64_t data); | 488 void SendData(intptr_t id, Dart_Port dart_port, int64_t data); |
426 void Start(EventHandler* handler); | 489 void Start(EventHandler* handler); |
427 void Shutdown(); | 490 void Shutdown(); |
428 | 491 |
429 static void EventHandlerEntry(uword args); | 492 static void EventHandlerEntry(uword args); |
430 | 493 |
431 int64_t GetTimeout(); | 494 int64_t GetTimeout(); |
432 void HandleInterrupt(InterruptMessage* msg); | 495 void HandleInterrupt(InterruptMessage* msg); |
433 void HandleTimeout(); | 496 void HandleTimeout(); |
434 void HandleAccept(ListenSocket* listen_socket, OverlappedBuffer* buffer); | 497 void HandleAccept(ListenSocket* listen_socket, OverlappedBuffer* buffer); |
435 void HandleClosed(Handle* handle); | 498 void HandleClosed(Handle* handle); |
436 void HandleError(Handle* handle); | 499 void HandleError(Handle* handle); |
437 void HandleRead(Handle* handle, int bytes, OverlappedBuffer* buffer); | 500 void HandleRead(Handle* handle, int bytes, OverlappedBuffer* buffer); |
501 void HandleRecvFrom(Handle* handle, int bytes, OverlappedBuffer* buffer); | |
438 void HandleWrite(Handle* handle, int bytes, OverlappedBuffer* buffer); | 502 void HandleWrite(Handle* handle, int bytes, OverlappedBuffer* buffer); |
439 void HandleDisconnect(ClientSocket* client_socket, | 503 void HandleDisconnect(ClientSocket* client_socket, |
440 int bytes, | 504 int bytes, |
441 OverlappedBuffer* buffer); | 505 OverlappedBuffer* buffer); |
442 void HandleIOCompletion(DWORD bytes, ULONG_PTR key, OVERLAPPED* overlapped); | 506 void HandleIOCompletion(DWORD bytes, ULONG_PTR key, OVERLAPPED* overlapped); |
443 | 507 |
444 HANDLE completion_port() { return completion_port_; } | 508 HANDLE completion_port() { return completion_port_; } |
445 | 509 |
446 private: | 510 private: |
447 ClientSocket* client_sockets_head_; | 511 ClientSocket* client_sockets_head_; |
448 | 512 |
449 TimeoutQueue timeout_queue_; // Time for next timeout. | 513 TimeoutQueue timeout_queue_; // Time for next timeout. |
450 bool shutdown_; | 514 bool shutdown_; |
451 HANDLE completion_port_; | 515 HANDLE completion_port_; |
452 }; | 516 }; |
453 | 517 |
454 } // namespace bin | 518 } // namespace bin |
455 } // namespace dart | 519 } // namespace dart |
456 | 520 |
457 #endif // BIN_EVENTHANDLER_WIN_H_ | 521 #endif // BIN_EVENTHANDLER_WIN_H_ |
OLD | NEW |