Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(21)

Side by Side Diff: runtime/bin/eventhandler_win.h

Issue 85993002: Add UDP support to dart:io (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Update test Created 7 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | runtime/bin/eventhandler_win.cc » ('j') | runtime/bin/eventhandler_win.cc » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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_
OLDNEW
« no previous file with comments | « no previous file | runtime/bin/eventhandler_win.cc » ('j') | runtime/bin/eventhandler_win.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698