| OLD | NEW |
| 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, 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 #include <process.h> | 5 #include <process.h> |
| 6 #include <winsock2.h> | 6 #include <winsock2.h> |
| 7 #include <ws2tcpip.h> | 7 #include <ws2tcpip.h> |
| 8 #include <mswsock.h> | 8 #include <mswsock.h> |
| 9 | 9 |
| 10 #include "bin/builtin.h" | 10 #include "bin/builtin.h" |
| (...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 193 | 193 |
| 194 void Handle::WriteComplete(IOBuffer* buffer) { | 194 void Handle::WriteComplete(IOBuffer* buffer) { |
| 195 ScopedLock lock(this); | 195 ScopedLock lock(this); |
| 196 // Currently only one outstanding write at the time. | 196 // Currently only one outstanding write at the time. |
| 197 ASSERT(pending_write_ == buffer); | 197 ASSERT(pending_write_ == buffer); |
| 198 IOBuffer::DisposeBuffer(buffer); | 198 IOBuffer::DisposeBuffer(buffer); |
| 199 pending_write_ = NULL; | 199 pending_write_ = NULL; |
| 200 } | 200 } |
| 201 | 201 |
| 202 | 202 |
| 203 static unsigned int __stdcall ReadFileThread(void* args) { |
| 204 Handle* handle = reinterpret_cast<Handle*>(args); |
| 205 handle->ReadSyncCompleteAsync(); |
| 206 return 0; |
| 207 } |
| 208 |
| 209 |
| 210 void Handle::ReadSyncCompleteAsync() { |
| 211 ASSERT(pending_read_ != NULL); |
| 212 DWORD bytes_read; |
| 213 BOOL ok = ReadFile(handle_, |
| 214 pending_read_->GetBufferStart(), |
| 215 pending_read_->GetBufferSize(), |
| 216 &bytes_read, |
| 217 NULL); |
| 218 if (!ok) { |
| 219 fprintf(stderr, "ReadFile failed %d\n", GetLastError()); |
| 220 bytes_read = 0; |
| 221 } |
| 222 OVERLAPPED* overlapped = pending_read_->GetCleanOverlapped(); |
| 223 ok = PostQueuedCompletionStatus(event_handler_->completion_port(), |
| 224 bytes_read, |
| 225 reinterpret_cast<ULONG_PTR>(this), |
| 226 overlapped); |
| 227 if (!ok) { |
| 228 FATAL("PostQueuedCompletionStatus failed"); |
| 229 } |
| 230 } |
| 231 |
| 232 |
| 203 bool Handle::IssueRead() { | 233 bool Handle::IssueRead() { |
| 204 ScopedLock lock(this); | 234 ScopedLock lock(this); |
| 205 ASSERT(type_ != kListenSocket); | 235 ASSERT(type_ != kListenSocket); |
| 206 ASSERT(completion_port_ != INVALID_HANDLE_VALUE); | |
| 207 ASSERT(pending_read_ == NULL); | 236 ASSERT(pending_read_ == NULL); |
| 237 IOBuffer* buffer = IOBuffer::AllocateReadBuffer(1024); |
| 238 if (SupportsOverlappedIO()) { |
| 239 ASSERT(completion_port_ != INVALID_HANDLE_VALUE); |
| 208 | 240 |
| 209 IOBuffer* buffer = IOBuffer::AllocateReadBuffer(1024); | 241 BOOL ok = ReadFile(handle_, |
| 210 BOOL ok = ReadFile(handle_, | 242 buffer->GetBufferStart(), |
| 211 buffer->GetBufferStart(), | 243 buffer->GetBufferSize(), |
| 212 buffer->GetBufferSize(), | 244 NULL, |
| 213 NULL, | 245 buffer->GetCleanOverlapped()); |
| 214 buffer->GetCleanOverlapped()); | 246 if (ok || GetLastError() == ERROR_IO_PENDING) { |
| 215 if (ok || GetLastError() == ERROR_IO_PENDING) { | 247 // Completing asynchronously. |
| 216 // Completing asynchronously. | 248 pending_read_ = buffer; |
| 249 return true; |
| 250 } |
| 251 |
| 252 if (GetLastError() != ERROR_BROKEN_PIPE) { |
| 253 fprintf(stderr, "ReadFile failed: %d\n", GetLastError()); |
| 254 } |
| 255 event_handler_->HandleClosed(this); |
| 256 IOBuffer::DisposeBuffer(buffer); |
| 257 return false; |
| 258 } else { |
| 259 // Completing asynchronously through thread. |
| 217 pending_read_ = buffer; | 260 pending_read_ = buffer; |
| 261 uint32_t tid; |
| 262 uintptr_t thread_handle = |
| 263 _beginthreadex(NULL, 32 * 1024, ReadFileThread, this, 0, &tid); |
| 264 if (thread_handle == -1) { |
| 265 FATAL("Failed to start read file thread"); |
| 266 } |
| 218 return true; | 267 return true; |
| 219 } | 268 } |
| 220 | |
| 221 if (GetLastError() != ERROR_BROKEN_PIPE) { | |
| 222 fprintf(stderr, "ReadFile failed: %d\n", GetLastError()); | |
| 223 } | |
| 224 event_handler_->HandleClosed(this); | |
| 225 IOBuffer::DisposeBuffer(buffer); | |
| 226 return false; | |
| 227 } | 269 } |
| 228 | 270 |
| 229 | 271 |
| 230 bool Handle::IssueWrite() { | 272 bool Handle::IssueWrite() { |
| 231 ScopedLock lock(this); | 273 ScopedLock lock(this); |
| 232 ASSERT(type_ != kListenSocket); | 274 ASSERT(type_ != kListenSocket); |
| 233 ASSERT(completion_port_ != INVALID_HANDLE_VALUE); | 275 ASSERT(completion_port_ != INVALID_HANDLE_VALUE); |
| 234 ASSERT(pending_write_ != NULL); | 276 ASSERT(pending_write_ != NULL); |
| 235 ASSERT(pending_write_->operation() == IOBuffer::kWrite); | 277 ASSERT(pending_write_->operation() == IOBuffer::kWrite); |
| 236 | 278 |
| (...skipping 13 matching lines...) Expand all Loading... |
| 250 fprintf(stderr, "WriteFile failed: %d\n", GetLastError()); | 292 fprintf(stderr, "WriteFile failed: %d\n", GetLastError()); |
| 251 } | 293 } |
| 252 event_handler_->HandleClosed(this); | 294 event_handler_->HandleClosed(this); |
| 253 IOBuffer::DisposeBuffer(buffer); | 295 IOBuffer::DisposeBuffer(buffer); |
| 254 return false; | 296 return false; |
| 255 } | 297 } |
| 256 | 298 |
| 257 | 299 |
| 258 void FileHandle::EnsureInitialized(EventHandlerImplementation* event_handler) { | 300 void FileHandle::EnsureInitialized(EventHandlerImplementation* event_handler) { |
| 259 ScopedLock lock(this); | 301 ScopedLock lock(this); |
| 260 if (completion_port_ == INVALID_HANDLE_VALUE) { | 302 event_handler_ = event_handler; |
| 303 if (SupportsOverlappedIO() && completion_port_ == INVALID_HANDLE_VALUE) { |
| 261 ASSERT(event_handler_ == NULL); | 304 ASSERT(event_handler_ == NULL); |
| 262 event_handler_ = event_handler; | |
| 263 CreateCompletionPort(event_handler_->completion_port()); | 305 CreateCompletionPort(event_handler_->completion_port()); |
| 264 } | 306 } |
| 265 } | 307 } |
| 266 | 308 |
| 267 | 309 |
| 268 bool FileHandle::IsClosed() { | 310 bool FileHandle::IsClosed() { |
| 269 return false; | 311 return false; |
| 270 } | 312 } |
| 271 | 313 |
| 272 | 314 |
| (...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 429 if (data_ready_->IsEmpty()) { | 471 if (data_ready_->IsEmpty()) { |
| 430 IOBuffer::DisposeBuffer(data_ready_); | 472 IOBuffer::DisposeBuffer(data_ready_); |
| 431 data_ready_ = NULL; | 473 data_ready_ = NULL; |
| 432 } | 474 } |
| 433 return num_bytes; | 475 return num_bytes; |
| 434 } | 476 } |
| 435 | 477 |
| 436 | 478 |
| 437 int Handle::Write(const void* buffer, int num_bytes) { | 479 int Handle::Write(const void* buffer, int num_bytes) { |
| 438 ScopedLock lock(this); | 480 ScopedLock lock(this); |
| 439 if (pending_write_ != NULL) return 0; | 481 if (SupportsOverlappedIO()) { |
| 440 if (completion_port_ == INVALID_HANDLE_VALUE) return 0; | 482 if (pending_write_ != NULL) return 0; |
| 441 if (num_bytes > 4096) num_bytes = 4096; | 483 if (completion_port_ == INVALID_HANDLE_VALUE) return 0; |
| 442 pending_write_ = IOBuffer::AllocateWriteBuffer(num_bytes); | 484 if (num_bytes > 4096) num_bytes = 4096; |
| 443 pending_write_->Write(buffer, num_bytes); | 485 pending_write_ = IOBuffer::AllocateWriteBuffer(num_bytes); |
| 444 IssueWrite(); | 486 pending_write_->Write(buffer, num_bytes); |
| 445 return num_bytes; | 487 IssueWrite(); |
| 488 return num_bytes; |
| 489 } else { |
| 490 DWORD bytes_written; |
| 491 BOOL ok = WriteFile(handle_, |
| 492 buffer, |
| 493 num_bytes, |
| 494 &bytes_written, |
| 495 NULL); |
| 496 if (!ok) { |
| 497 if (GetLastError() != ERROR_BROKEN_PIPE) { |
| 498 fprintf(stderr, "WriteFile failed: %d\n", GetLastError()); |
| 499 } |
| 500 event_handler_->HandleClosed(this); |
| 501 } |
| 502 return bytes_written; |
| 503 } |
| 446 } | 504 } |
| 447 | 505 |
| 506 |
| 448 void ClientSocket::Shutdown(int how) { | 507 void ClientSocket::Shutdown(int how) { |
| 449 int rc = shutdown(socket(), how); | 508 int rc = shutdown(socket(), how); |
| 450 if (rc == SOCKET_ERROR) { | 509 if (rc == SOCKET_ERROR) { |
| 451 fprintf(stderr, "shutdown failed: %d %d\n", socket(), WSAGetLastError()); | 510 fprintf(stderr, "shutdown failed: %d %d\n", socket(), WSAGetLastError()); |
| 452 } | 511 } |
| 453 if (how == SD_RECEIVE) MarkClosedRead(); | 512 if (how == SD_RECEIVE) MarkClosedRead(); |
| 454 if (how == SD_SEND) MarkClosedWrite(); | 513 if (how == SD_SEND) MarkClosedWrite(); |
| 455 if (how == SD_BOTH) { | 514 if (how == SD_BOTH) { |
| 456 MarkClosedRead(); | 515 MarkClosedRead(); |
| 457 MarkClosedWrite(); | 516 MarkClosedWrite(); |
| (...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 636 | 695 |
| 637 if (listen_socket->IsClosed()) { | 696 if (listen_socket->IsClosed()) { |
| 638 delete listen_socket; | 697 delete listen_socket; |
| 639 } | 698 } |
| 640 } | 699 } |
| 641 | 700 |
| 642 | 701 |
| 643 void EventHandlerImplementation::HandleClosed(Handle* handle) { | 702 void EventHandlerImplementation::HandleClosed(Handle* handle) { |
| 644 if (!handle->IsClosing()) { | 703 if (!handle->IsClosing()) { |
| 645 int event_mask = 1 << kCloseEvent; | 704 int event_mask = 1 << kCloseEvent; |
| 646 if ((handle->mask() & event_mask) != 0) { | 705 Dart_PostIntArray(handle->port(), 1, &event_mask); |
| 647 Dart_PostIntArray(handle->port(), 1, &event_mask); | |
| 648 } | |
| 649 } | 706 } |
| 650 } | 707 } |
| 651 | 708 |
| 652 | 709 |
| 653 void EventHandlerImplementation::HandleRead(Handle* handle, | 710 void EventHandlerImplementation::HandleRead(Handle* handle, |
| 654 int bytes, | 711 int bytes, |
| 655 IOBuffer* buffer) { | 712 IOBuffer* buffer) { |
| 656 buffer->set_data_length(bytes); | 713 buffer->set_data_length(bytes); |
| 657 handle->ReadComplete(buffer); | 714 handle->ReadComplete(buffer); |
| 658 if (bytes > 0) { | 715 if (bytes > 0) { |
| (...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 826 _beginthreadex(NULL, 32 * 1024, EventHandlerThread, this, 0, &tid); | 883 _beginthreadex(NULL, 32 * 1024, EventHandlerThread, this, 0, &tid); |
| 827 if (thread_handle == -1) { | 884 if (thread_handle == -1) { |
| 828 FATAL("Failed to start event handler thread"); | 885 FATAL("Failed to start event handler thread"); |
| 829 } | 886 } |
| 830 | 887 |
| 831 // Initialize Winsock32 | 888 // Initialize Winsock32 |
| 832 if (!Socket::Initialize()) { | 889 if (!Socket::Initialize()) { |
| 833 FATAL("Failed to initialized Windows sockets"); | 890 FATAL("Failed to initialized Windows sockets"); |
| 834 } | 891 } |
| 835 } | 892 } |
| OLD | NEW |