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