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 18 matching lines...) Expand all Loading... |
29 Dart_Port dart_port; | 29 Dart_Port dart_port; |
30 int64_t data; | 30 int64_t data; |
31 }; | 31 }; |
32 | 32 |
33 | 33 |
34 // An IOBuffer encapsulates the OVERLAPPED structure and the | 34 // An IOBuffer encapsulates the OVERLAPPED structure and the |
35 // associated data buffer. For accept it also contains the pre-created | 35 // associated data buffer. For accept it also contains the pre-created |
36 // socket for the client. | 36 // socket for the client. |
37 class IOBuffer { | 37 class IOBuffer { |
38 public: | 38 public: |
39 enum Operation { kAccept, kRead, kWrite }; | 39 enum Operation { kAccept, kRead, kWrite, kDisconnect }; |
40 | 40 |
41 static IOBuffer* AllocateAcceptBuffer(int buffer_size); | 41 static IOBuffer* AllocateAcceptBuffer(int buffer_size); |
42 static IOBuffer* AllocateReadBuffer(int buffer_size); | 42 static IOBuffer* AllocateReadBuffer(int buffer_size); |
43 static IOBuffer* AllocateWriteBuffer(int buffer_size); | 43 static IOBuffer* AllocateWriteBuffer(int buffer_size); |
| 44 static IOBuffer* AllocateDisconnectBuffer(); |
44 static void DisposeBuffer(IOBuffer* buffer); | 45 static void DisposeBuffer(IOBuffer* buffer); |
45 | 46 |
46 // Find the IO buffer from the OVERLAPPED address. | 47 // Find the IO buffer from the OVERLAPPED address. |
47 static IOBuffer* GetFromOverlapped(OVERLAPPED* overlapped); | 48 static IOBuffer* GetFromOverlapped(OVERLAPPED* overlapped); |
48 | 49 |
49 // Read data from a buffer which has been received. It will read up | 50 // Read data from a buffer which has been received. It will read up |
50 // to num_bytes bytes of data returning the actual number of bytes | 51 // to num_bytes bytes of data returning the actual number of bytes |
51 // read. This will update the index of the next byte in the buffer | 52 // read. This will update the index of the next byte in the buffer |
52 // so calling Read several times will keep returning new data from | 53 // so calling Read several times will keep returning new data from |
53 // the buffer until all data have been read. | 54 // the buffer until all data have been read. |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
170 | 171 |
171 HANDLE handle() { return handle_; } | 172 HANDLE handle() { return handle_; } |
172 Dart_Port port() { return port_; } | 173 Dart_Port port() { return port_; } |
173 EventHandlerImplementation* event_handler() { return event_handler_; } | 174 EventHandlerImplementation* event_handler() { return event_handler_; } |
174 | 175 |
175 void Lock(); | 176 void Lock(); |
176 void Unlock(); | 177 void Unlock(); |
177 | 178 |
178 bool CreateCompletionPort(HANDLE completion_port); | 179 bool CreateCompletionPort(HANDLE completion_port); |
179 | 180 |
180 void close(); | 181 void Close(); |
| 182 virtual void DoClose(); |
181 virtual bool IsClosed() = 0; | 183 virtual bool IsClosed() = 0; |
182 | 184 |
183 void SetPortAndMask(Dart_Port port, intptr_t mask) { | 185 void SetPortAndMask(Dart_Port port, intptr_t mask) { |
184 port_ = port; | 186 port_ = port; |
185 mask_ = mask; | 187 mask_ = mask; |
186 } | 188 } |
187 Type type() { return type_; } | 189 Type type() { return type_; } |
188 bool is_file() { return type_ == kFile; } | 190 bool is_file() { return type_ == kFile; } |
189 bool is_socket() { return type_ == kListenSocket || type_ == kClientSocket; } | 191 bool is_socket() { return type_ == kListenSocket || type_ == kClientSocket; } |
190 bool is_listen_socket() { return type_ == kListenSocket; } | 192 bool is_listen_socket() { return type_ == kListenSocket; } |
(...skipping 18 matching lines...) Expand all Loading... |
209 kClosing = 0, | 211 kClosing = 0, |
210 kCloseRead = 1, | 212 kCloseRead = 1, |
211 kCloseWrite = 2, | 213 kCloseWrite = 2, |
212 kDoesNotSupportOverlappedIO = 3, | 214 kDoesNotSupportOverlappedIO = 3, |
213 kError = 4 | 215 kError = 4 |
214 }; | 216 }; |
215 | 217 |
216 explicit Handle(HANDLE handle); | 218 explicit Handle(HANDLE handle); |
217 Handle(HANDLE handle, Dart_Port port); | 219 Handle(HANDLE handle, Dart_Port port); |
218 | 220 |
219 virtual void AfterClose() = 0; | |
220 virtual void HandleIssueError(); | 221 virtual void HandleIssueError(); |
221 | 222 |
222 Type type_; | 223 Type type_; |
223 HANDLE handle_; | 224 HANDLE handle_; |
224 Dart_Port port_; // Dart port to communicate events for this socket. | 225 Dart_Port port_; // Dart port to communicate events for this socket. |
225 intptr_t mask_; // Mask of events to report through the port. | 226 intptr_t mask_; // Mask of events to report through the port. |
226 HANDLE completion_port_; | 227 HANDLE completion_port_; |
227 EventHandlerImplementation* event_handler_; | 228 EventHandlerImplementation* event_handler_; |
228 | 229 |
229 IOBuffer* data_ready_; // IO buffer for data ready to be read. | 230 IOBuffer* data_ready_; // IO buffer for data ready to be read. |
(...skipping 10 matching lines...) Expand all Loading... |
240 | 241 |
241 class FileHandle : public Handle { | 242 class FileHandle : public Handle { |
242 public: | 243 public: |
243 explicit FileHandle(HANDLE handle) | 244 explicit FileHandle(HANDLE handle) |
244 : Handle(reinterpret_cast<HANDLE>(handle)) { type_ = kFile; } | 245 : Handle(reinterpret_cast<HANDLE>(handle)) { type_ = kFile; } |
245 FileHandle(HANDLE handle, Dart_Port port) | 246 FileHandle(HANDLE handle, Dart_Port port) |
246 : Handle(reinterpret_cast<HANDLE>(handle), port) { type_ = kFile; } | 247 : Handle(reinterpret_cast<HANDLE>(handle), port) { type_ = kFile; } |
247 | 248 |
248 virtual void EnsureInitialized(EventHandlerImplementation* event_handler); | 249 virtual void EnsureInitialized(EventHandlerImplementation* event_handler); |
249 virtual bool IsClosed(); | 250 virtual bool IsClosed(); |
250 | |
251 private: | |
252 virtual void AfterClose(); | |
253 }; | 251 }; |
254 | 252 |
255 | 253 |
256 class SocketHandle : public Handle { | 254 class SocketHandle : public Handle { |
257 public: | 255 public: |
258 SOCKET socket() { return reinterpret_cast<SOCKET>(handle_); } | 256 SOCKET socket() { return reinterpret_cast<SOCKET>(handle_); } |
259 | 257 |
260 protected: | 258 protected: |
261 explicit SocketHandle(SOCKET s) : Handle(reinterpret_cast<HANDLE>(s)) {} | 259 explicit SocketHandle(SOCKET s) : Handle(reinterpret_cast<HANDLE>(s)) {} |
262 SocketHandle(SOCKET s, Dart_Port port) | 260 SocketHandle(SOCKET s, Dart_Port port) |
(...skipping 14 matching lines...) Expand all Loading... |
277 type_ = kListenSocket; | 275 type_ = kListenSocket; |
278 } | 276 } |
279 virtual ~ListenSocket() { | 277 virtual ~ListenSocket() { |
280 ASSERT(!HasPendingAccept()); | 278 ASSERT(!HasPendingAccept()); |
281 ASSERT(accepted_head_ == NULL); | 279 ASSERT(accepted_head_ == NULL); |
282 ASSERT(accepted_tail_ == NULL); | 280 ASSERT(accepted_tail_ == NULL); |
283 }; | 281 }; |
284 | 282 |
285 // Socket interface exposing normal socket operations. | 283 // Socket interface exposing normal socket operations. |
286 ClientSocket* Accept(); | 284 ClientSocket* Accept(); |
| 285 bool CanAccept(); |
287 | 286 |
288 // Internal interface used by the event handler. | 287 // Internal interface used by the event handler. |
289 bool HasPendingAccept() { return pending_accept_count_ > 0; } | 288 bool HasPendingAccept() { return pending_accept_count_ > 0; } |
290 bool IssueAccept(); | 289 bool IssueAccept(); |
291 void AcceptComplete(IOBuffer* buffer, HANDLE completion_port); | 290 void AcceptComplete(IOBuffer* buffer, HANDLE completion_port); |
292 | 291 |
293 virtual void EnsureInitialized( | 292 virtual void EnsureInitialized( |
294 EventHandlerImplementation* event_handler); | 293 EventHandlerImplementation* event_handler); |
| 294 virtual void DoClose(); |
295 virtual bool IsClosed(); | 295 virtual bool IsClosed(); |
296 | 296 |
297 int pending_accept_count() { return pending_accept_count_; } | 297 int pending_accept_count() { return pending_accept_count_; } |
298 | 298 |
299 private: | 299 private: |
300 bool LoadAcceptEx(); | 300 bool LoadAcceptEx(); |
301 virtual void AfterClose(); | |
302 | 301 |
303 LPFN_ACCEPTEX AcceptEx_; | 302 LPFN_ACCEPTEX AcceptEx_; |
304 int pending_accept_count_; | 303 int pending_accept_count_; |
305 // Linked list of accepted connections provided by completion code. Ready to | 304 // Linked list of accepted connections provided by completion code. Ready to |
306 // be handed over through accept. | 305 // be handed over through accept. |
307 ClientSocket* accepted_head_; | 306 ClientSocket* accepted_head_; |
308 ClientSocket* accepted_tail_; | 307 ClientSocket* accepted_tail_; |
309 }; | 308 }; |
310 | 309 |
311 | 310 |
312 // Information on connected sockets. | 311 // Information on connected sockets. |
313 class ClientSocket : public SocketHandle { | 312 class ClientSocket : public SocketHandle { |
314 public: | 313 public: |
315 explicit ClientSocket(SOCKET s) : SocketHandle(s), next_(NULL) { | 314 explicit ClientSocket(SOCKET s) : SocketHandle(s), |
| 315 DisconnectEx_(NULL), |
| 316 next_(NULL) { |
| 317 LoadDisconnectEx(); |
316 type_ = kClientSocket; | 318 type_ = kClientSocket; |
317 } | 319 } |
318 | 320 |
319 ClientSocket(SOCKET s, Dart_Port port) : SocketHandle(s, port), next_(NULL) { | 321 ClientSocket(SOCKET s, Dart_Port port) : SocketHandle(s, port), |
| 322 DisconnectEx_(NULL), |
| 323 next_(NULL) { |
| 324 LoadDisconnectEx(); |
320 type_ = kClientSocket; | 325 type_ = kClientSocket; |
321 } | 326 } |
322 | 327 |
323 virtual ~ClientSocket() { | 328 virtual ~ClientSocket() { |
324 // Don't delete this object until all pending requests have been handled. | 329 // Don't delete this object until all pending requests have been handled. |
325 ASSERT(!HasPendingRead()); | 330 ASSERT(!HasPendingRead()); |
326 ASSERT(!HasPendingWrite()); | 331 ASSERT(!HasPendingWrite()); |
327 ASSERT(next_ == NULL); | 332 ASSERT(next_ == NULL); |
328 }; | 333 }; |
329 | 334 |
330 void Shutdown(int how); | 335 void Shutdown(int how); |
331 | 336 |
332 // Internal interface used by the event handler. | 337 // Internal interface used by the event handler. |
333 virtual bool IssueRead(); | 338 virtual bool IssueRead(); |
334 virtual bool IssueWrite(); | 339 virtual bool IssueWrite(); |
| 340 void IssueDisconnect(); |
| 341 void DisconnectComplete(IOBuffer* buffer); |
335 | 342 |
336 virtual void EnsureInitialized( | 343 virtual void EnsureInitialized( |
337 EventHandlerImplementation* event_handler); | 344 EventHandlerImplementation* event_handler); |
| 345 virtual void DoClose(); |
338 virtual bool IsClosed(); | 346 virtual bool IsClosed(); |
339 | 347 |
340 ClientSocket* next() { return next_; } | 348 ClientSocket* next() { return next_; } |
341 void set_next(ClientSocket* next) { next_ = next; } | 349 void set_next(ClientSocket* next) { next_ = next; } |
342 | 350 |
343 private: | 351 private: |
344 virtual void AfterClose(); | 352 bool LoadDisconnectEx(); |
345 | 353 |
| 354 LPFN_DISCONNECTEX DisconnectEx_; |
346 ClientSocket* next_; | 355 ClientSocket* next_; |
347 }; | 356 }; |
348 | 357 |
349 | 358 |
350 // Event handler. | 359 // Event handler. |
351 class EventHandlerImplementation { | 360 class EventHandlerImplementation { |
352 public: | 361 public: |
353 EventHandlerImplementation(); | 362 EventHandlerImplementation(); |
354 virtual ~EventHandlerImplementation() {} | 363 virtual ~EventHandlerImplementation() {} |
355 | 364 |
356 void SendData(intptr_t id, Dart_Port dart_port, int64_t data); | 365 void SendData(intptr_t id, Dart_Port dart_port, int64_t data); |
357 void Start(); | 366 void Start(); |
358 void Shutdown(); | 367 void Shutdown(); |
359 | 368 |
360 static void EventHandlerEntry(uword args); | 369 static void EventHandlerEntry(uword args); |
361 | 370 |
362 DWORD GetTimeout(); | 371 DWORD GetTimeout(); |
363 void HandleInterrupt(InterruptMessage* msg); | 372 void HandleInterrupt(InterruptMessage* msg); |
364 void HandleTimeout(); | 373 void HandleTimeout(); |
365 void HandleAccept(ListenSocket* listen_socket, IOBuffer* buffer); | 374 void HandleAccept(ListenSocket* listen_socket, IOBuffer* buffer); |
366 void HandleClosed(Handle* handle); | 375 void HandleClosed(Handle* handle); |
367 void HandleError(Handle* handle); | 376 void HandleError(Handle* handle); |
368 void HandleRead(Handle* handle, int bytes, IOBuffer* buffer); | 377 void HandleRead(Handle* handle, int bytes, IOBuffer* buffer); |
369 void HandleWrite(Handle* handle, int bytes, IOBuffer* buffer); | 378 void HandleWrite(Handle* handle, int bytes, IOBuffer* buffer); |
370 void HandleClose(ClientSocket* client_socket); | 379 void HandleDisconnect(ClientSocket* client_socket, |
| 380 int bytes, |
| 381 IOBuffer* buffer); |
371 void HandleIOCompletion(DWORD bytes, ULONG_PTR key, OVERLAPPED* overlapped); | 382 void HandleIOCompletion(DWORD bytes, ULONG_PTR key, OVERLAPPED* overlapped); |
372 | 383 |
373 HANDLE completion_port() { return completion_port_; } | 384 HANDLE completion_port() { return completion_port_; } |
374 | 385 |
375 private: | 386 private: |
376 ClientSocket* client_sockets_head_; | 387 ClientSocket* client_sockets_head_; |
377 | 388 |
378 int64_t timeout_; // Time for next timeout. | 389 int64_t timeout_; // Time for next timeout. |
379 Dart_Port timeout_port_; | 390 Dart_Port timeout_port_; |
380 bool shutdown_; | 391 bool shutdown_; |
381 HANDLE completion_port_; | 392 HANDLE completion_port_; |
382 }; | 393 }; |
383 | 394 |
384 | 395 |
385 #endif // BIN_EVENTHANDLER_WIN_H_ | 396 #endif // BIN_EVENTHANDLER_WIN_H_ |
OLD | NEW |