| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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 "platform/globals.h" | 5 #include "platform/globals.h" |
| 6 #if defined(TARGET_OS_WINDOWS) | 6 #if defined(TARGET_OS_WINDOWS) |
| 7 | 7 |
| 8 #include "bin/eventhandler.h" | 8 #include "bin/eventhandler.h" |
| 9 | 9 |
| 10 #include <process.h> // NOLINT | 10 #include <process.h> // NOLINT |
| 11 #include <winsock2.h> // NOLINT | 11 #include <winsock2.h> // NOLINT |
| 12 #include <ws2tcpip.h> // NOLINT | 12 #include <ws2tcpip.h> // NOLINT |
| 13 #include <mswsock.h> // NOLINT | 13 #include <mswsock.h> // NOLINT |
| 14 #include <io.h> // NOLINT | 14 #include <io.h> // NOLINT |
| 15 #include <fcntl.h> // NOLINT | 15 #include <fcntl.h> // NOLINT |
| 16 | 16 |
| 17 #include "bin/builtin.h" | 17 #include "bin/builtin.h" |
| 18 #include "bin/dartutils.h" | 18 #include "bin/dartutils.h" |
| 19 #include "bin/log.h" | 19 #include "bin/log.h" |
| 20 #include "bin/socket.h" | 20 #include "bin/socket.h" |
| 21 #include "bin/utils.h" | 21 #include "bin/utils.h" |
| 22 #include "platform/thread.h" | 22 #include "platform/thread.h" |
| 23 | 23 |
| 24 | 24 |
| 25 namespace dart { | 25 namespace dart { |
| 26 namespace bin { | 26 namespace bin { |
| 27 | 27 |
| 28 static const int kBufferSize = 64 * 1024; | 28 static const int kBufferSize = 64 * 1024; |
| 29 static const int kStdioBufferSize = 16 * 1024; | 29 static const int kStdOverlappedBufferSize = 16 * 1024; |
| 30 | 30 |
| 31 static const int kInfinityTimeout = -1; | 31 static const int kInfinityTimeout = -1; |
| 32 static const int kTimeoutId = -1; | 32 static const int kTimeoutId = -1; |
| 33 static const int kShutdownId = -2; | 33 static const int kShutdownId = -2; |
| 34 | 34 |
| 35 IOBuffer* IOBuffer::AllocateBuffer(int buffer_size, Operation operation) { | 35 OverlappedBuffer* OverlappedBuffer::AllocateBuffer(int buffer_size, |
| 36 IOBuffer* buffer = new(buffer_size) IOBuffer(buffer_size, operation); | 36 Operation operation) { |
| 37 OverlappedBuffer* buffer = |
| 38 new(buffer_size) OverlappedBuffer(buffer_size, operation); |
| 37 return buffer; | 39 return buffer; |
| 38 } | 40 } |
| 39 | 41 |
| 40 | 42 |
| 41 IOBuffer* IOBuffer::AllocateAcceptBuffer(int buffer_size) { | 43 OverlappedBuffer* OverlappedBuffer::AllocateAcceptBuffer(int buffer_size) { |
| 42 IOBuffer* buffer = AllocateBuffer(buffer_size, kAccept); | 44 OverlappedBuffer* buffer = AllocateBuffer(buffer_size, kAccept); |
| 43 return buffer; | 45 return buffer; |
| 44 } | 46 } |
| 45 | 47 |
| 46 | 48 |
| 47 IOBuffer* IOBuffer::AllocateReadBuffer(int buffer_size) { | 49 OverlappedBuffer* OverlappedBuffer::AllocateReadBuffer(int buffer_size) { |
| 48 return AllocateBuffer(buffer_size, kRead); | 50 return AllocateBuffer(buffer_size, kRead); |
| 49 } | 51 } |
| 50 | 52 |
| 51 | 53 |
| 52 IOBuffer* IOBuffer::AllocateWriteBuffer(int buffer_size) { | 54 OverlappedBuffer* OverlappedBuffer::AllocateWriteBuffer(int buffer_size) { |
| 53 return AllocateBuffer(buffer_size, kWrite); | 55 return AllocateBuffer(buffer_size, kWrite); |
| 54 } | 56 } |
| 55 | 57 |
| 56 | 58 |
| 57 IOBuffer* IOBuffer::AllocateDisconnectBuffer() { | 59 OverlappedBuffer* OverlappedBuffer::AllocateDisconnectBuffer() { |
| 58 return AllocateBuffer(0, kDisconnect); | 60 return AllocateBuffer(0, kDisconnect); |
| 59 } | 61 } |
| 60 | 62 |
| 61 | 63 |
| 62 void IOBuffer::DisposeBuffer(IOBuffer* buffer) { | 64 void OverlappedBuffer::DisposeBuffer(OverlappedBuffer* buffer) { |
| 63 delete buffer; | 65 delete buffer; |
| 64 } | 66 } |
| 65 | 67 |
| 66 | 68 |
| 67 IOBuffer* IOBuffer::GetFromOverlapped(OVERLAPPED* overlapped) { | 69 OverlappedBuffer* OverlappedBuffer::GetFromOverlapped(OVERLAPPED* overlapped) { |
| 68 IOBuffer* buffer = CONTAINING_RECORD(overlapped, IOBuffer, overlapped_); | 70 OverlappedBuffer* buffer = |
| 71 CONTAINING_RECORD(overlapped, OverlappedBuffer, overlapped_); |
| 69 return buffer; | 72 return buffer; |
| 70 } | 73 } |
| 71 | 74 |
| 72 | 75 |
| 73 int IOBuffer::Read(void* buffer, int num_bytes) { | 76 int OverlappedBuffer::Read(void* buffer, int num_bytes) { |
| 74 if (num_bytes > GetRemainingLength()) { | 77 if (num_bytes > GetRemainingLength()) { |
| 75 num_bytes = GetRemainingLength(); | 78 num_bytes = GetRemainingLength(); |
| 76 } | 79 } |
| 77 memcpy(buffer, GetBufferStart() + index_, num_bytes); | 80 memcpy(buffer, GetBufferStart() + index_, num_bytes); |
| 78 index_ += num_bytes; | 81 index_ += num_bytes; |
| 79 return num_bytes; | 82 return num_bytes; |
| 80 } | 83 } |
| 81 | 84 |
| 82 | 85 |
| 83 int IOBuffer::Write(const void* buffer, int num_bytes) { | 86 int OverlappedBuffer::Write(const void* buffer, int num_bytes) { |
| 84 ASSERT(num_bytes == buflen_); | 87 ASSERT(num_bytes == buflen_); |
| 85 memcpy(GetBufferStart(), buffer, num_bytes); | 88 memcpy(GetBufferStart(), buffer, num_bytes); |
| 86 data_length_ = num_bytes; | 89 data_length_ = num_bytes; |
| 87 return num_bytes; | 90 return num_bytes; |
| 88 } | 91 } |
| 89 | 92 |
| 90 | 93 |
| 91 int IOBuffer::GetRemainingLength() { | 94 int OverlappedBuffer::GetRemainingLength() { |
| 92 ASSERT(operation_ == kRead); | 95 ASSERT(operation_ == kRead); |
| 93 return data_length_ - index_; | 96 return data_length_ - index_; |
| 94 } | 97 } |
| 95 | 98 |
| 96 | 99 |
| 97 Handle::Handle(HANDLE handle) | 100 Handle::Handle(HANDLE handle) |
| 98 : handle_(reinterpret_cast<HANDLE>(handle)), | 101 : handle_(reinterpret_cast<HANDLE>(handle)), |
| 99 port_(0), | 102 port_(0), |
| 100 mask_(0), | 103 mask_(0), |
| 101 completion_port_(INVALID_HANDLE_VALUE), | 104 completion_port_(INVALID_HANDLE_VALUE), |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 176 return pending_read_ != NULL; | 179 return pending_read_ != NULL; |
| 177 } | 180 } |
| 178 | 181 |
| 179 | 182 |
| 180 bool Handle::HasPendingWrite() { | 183 bool Handle::HasPendingWrite() { |
| 181 ScopedLock lock(this); | 184 ScopedLock lock(this); |
| 182 return pending_write_ != NULL; | 185 return pending_write_ != NULL; |
| 183 } | 186 } |
| 184 | 187 |
| 185 | 188 |
| 186 void Handle::ReadComplete(IOBuffer* buffer) { | 189 void Handle::ReadComplete(OverlappedBuffer* buffer) { |
| 187 ScopedLock lock(this); | 190 ScopedLock lock(this); |
| 188 // Currently only one outstanding read at the time. | 191 // Currently only one outstanding read at the time. |
| 189 ASSERT(pending_read_ == buffer); | 192 ASSERT(pending_read_ == buffer); |
| 190 ASSERT(data_ready_ == NULL); | 193 ASSERT(data_ready_ == NULL); |
| 191 if (!IsClosing() && !buffer->IsEmpty()) { | 194 if (!IsClosing() && !buffer->IsEmpty()) { |
| 192 data_ready_ = pending_read_; | 195 data_ready_ = pending_read_; |
| 193 } else { | 196 } else { |
| 194 IOBuffer::DisposeBuffer(buffer); | 197 OverlappedBuffer::DisposeBuffer(buffer); |
| 195 } | 198 } |
| 196 pending_read_ = NULL; | 199 pending_read_ = NULL; |
| 197 } | 200 } |
| 198 | 201 |
| 199 | 202 |
| 200 void Handle::WriteComplete(IOBuffer* buffer) { | 203 void Handle::WriteComplete(OverlappedBuffer* buffer) { |
| 201 ScopedLock lock(this); | 204 ScopedLock lock(this); |
| 202 // Currently only one outstanding write at the time. | 205 // Currently only one outstanding write at the time. |
| 203 ASSERT(pending_write_ == buffer); | 206 ASSERT(pending_write_ == buffer); |
| 204 IOBuffer::DisposeBuffer(buffer); | 207 OverlappedBuffer::DisposeBuffer(buffer); |
| 205 pending_write_ = NULL; | 208 pending_write_ = NULL; |
| 206 } | 209 } |
| 207 | 210 |
| 208 | 211 |
| 209 static unsigned int __stdcall ReadFileThread(void* args) { | 212 static unsigned int __stdcall ReadFileThread(void* args) { |
| 210 Handle* handle = reinterpret_cast<Handle*>(args); | 213 Handle* handle = reinterpret_cast<Handle*>(args); |
| 211 handle->ReadSyncCompleteAsync(); | 214 handle->ReadSyncCompleteAsync(); |
| 212 return 0; | 215 return 0; |
| 213 } | 216 } |
| 214 | 217 |
| 215 | 218 |
| 216 void Handle::ReadSyncCompleteAsync() { | 219 void Handle::ReadSyncCompleteAsync() { |
| 217 ASSERT(pending_read_ != NULL); | 220 ASSERT(pending_read_ != NULL); |
| 218 ASSERT(pending_read_->GetBufferSize() >= kStdioBufferSize); | 221 ASSERT(pending_read_->GetBufferSize() >= kStdOverlappedBufferSize); |
| 219 | 222 |
| 220 DWORD buffer_size = pending_read_->GetBufferSize(); | 223 DWORD buffer_size = pending_read_->GetBufferSize(); |
| 221 if (GetFileType(handle_) == FILE_TYPE_CHAR) { | 224 if (GetFileType(handle_) == FILE_TYPE_CHAR) { |
| 222 buffer_size = kStdioBufferSize; | 225 buffer_size = kStdOverlappedBufferSize; |
| 223 } | 226 } |
| 224 DWORD bytes_read = 0; | 227 DWORD bytes_read = 0; |
| 225 BOOL ok = ReadFile(handle_, | 228 BOOL ok = ReadFile(handle_, |
| 226 pending_read_->GetBufferStart(), | 229 pending_read_->GetBufferStart(), |
| 227 buffer_size, | 230 buffer_size, |
| 228 &bytes_read, | 231 &bytes_read, |
| 229 NULL); | 232 NULL); |
| 230 if (!ok) { | 233 if (!ok) { |
| 231 if (GetLastError() != ERROR_BROKEN_PIPE) { | 234 if (GetLastError() != ERROR_BROKEN_PIPE) { |
| 232 Log::PrintErr("ReadFile failed %d\n", GetLastError()); | 235 Log::PrintErr("ReadFile failed %d\n", GetLastError()); |
| 233 } | 236 } |
| 234 bytes_read = 0; | 237 bytes_read = 0; |
| 235 } | 238 } |
| 236 OVERLAPPED* overlapped = pending_read_->GetCleanOverlapped(); | 239 OVERLAPPED* overlapped = pending_read_->GetCleanOverlapped(); |
| 237 ok = PostQueuedCompletionStatus(event_handler_->completion_port(), | 240 ok = PostQueuedCompletionStatus(event_handler_->completion_port(), |
| 238 bytes_read, | 241 bytes_read, |
| 239 reinterpret_cast<ULONG_PTR>(this), | 242 reinterpret_cast<ULONG_PTR>(this), |
| 240 overlapped); | 243 overlapped); |
| 241 if (!ok) { | 244 if (!ok) { |
| 242 FATAL("PostQueuedCompletionStatus failed"); | 245 FATAL("PostQueuedCompletionStatus failed"); |
| 243 } | 246 } |
| 244 } | 247 } |
| 245 | 248 |
| 246 | 249 |
| 247 bool Handle::IssueRead() { | 250 bool Handle::IssueRead() { |
| 248 ScopedLock lock(this); | 251 ScopedLock lock(this); |
| 249 ASSERT(type_ != kListenSocket); | 252 ASSERT(type_ != kListenSocket); |
| 250 ASSERT(pending_read_ == NULL); | 253 ASSERT(pending_read_ == NULL); |
| 251 IOBuffer* buffer = IOBuffer::AllocateReadBuffer(kBufferSize); | 254 OverlappedBuffer* buffer = OverlappedBuffer::AllocateReadBuffer(kBufferSize); |
| 252 if (SupportsOverlappedIO()) { | 255 if (SupportsOverlappedIO()) { |
| 253 ASSERT(completion_port_ != INVALID_HANDLE_VALUE); | 256 ASSERT(completion_port_ != INVALID_HANDLE_VALUE); |
| 254 | 257 |
| 255 BOOL ok = ReadFile(handle_, | 258 BOOL ok = ReadFile(handle_, |
| 256 buffer->GetBufferStart(), | 259 buffer->GetBufferStart(), |
| 257 buffer->GetBufferSize(), | 260 buffer->GetBufferSize(), |
| 258 NULL, | 261 NULL, |
| 259 buffer->GetCleanOverlapped()); | 262 buffer->GetCleanOverlapped()); |
| 260 if (ok || GetLastError() == ERROR_IO_PENDING) { | 263 if (ok || GetLastError() == ERROR_IO_PENDING) { |
| 261 // Completing asynchronously. | 264 // Completing asynchronously. |
| 262 pending_read_ = buffer; | 265 pending_read_ = buffer; |
| 263 return true; | 266 return true; |
| 264 } | 267 } |
| 265 IOBuffer::DisposeBuffer(buffer); | 268 OverlappedBuffer::DisposeBuffer(buffer); |
| 266 HandleIssueError(); | 269 HandleIssueError(); |
| 267 return false; | 270 return false; |
| 268 } else { | 271 } else { |
| 269 // Completing asynchronously through thread. | 272 // Completing asynchronously through thread. |
| 270 pending_read_ = buffer; | 273 pending_read_ = buffer; |
| 271 uint32_t tid; | 274 uint32_t tid; |
| 272 uintptr_t thread_handle = | 275 uintptr_t thread_handle = |
| 273 _beginthreadex(NULL, 32 * 1024, ReadFileThread, this, 0, &tid); | 276 _beginthreadex(NULL, 32 * 1024, ReadFileThread, this, 0, &tid); |
| 274 if (thread_handle == -1) { | 277 if (thread_handle == -1) { |
| 275 FATAL("Failed to start read file thread"); | 278 FATAL("Failed to start read file thread"); |
| 276 } | 279 } |
| 277 return true; | 280 return true; |
| 278 } | 281 } |
| 279 } | 282 } |
| 280 | 283 |
| 281 | 284 |
| 282 bool Handle::IssueWrite() { | 285 bool Handle::IssueWrite() { |
| 283 ScopedLock lock(this); | 286 ScopedLock lock(this); |
| 284 ASSERT(type_ != kListenSocket); | 287 ASSERT(type_ != kListenSocket); |
| 285 ASSERT(completion_port_ != INVALID_HANDLE_VALUE); | 288 ASSERT(completion_port_ != INVALID_HANDLE_VALUE); |
| 286 ASSERT(pending_write_ != NULL); | 289 ASSERT(pending_write_ != NULL); |
| 287 ASSERT(pending_write_->operation() == IOBuffer::kWrite); | 290 ASSERT(pending_write_->operation() == OverlappedBuffer::kWrite); |
| 288 | 291 |
| 289 IOBuffer* buffer = pending_write_; | 292 OverlappedBuffer* buffer = pending_write_; |
| 290 BOOL ok = WriteFile(handle_, | 293 BOOL ok = WriteFile(handle_, |
| 291 buffer->GetBufferStart(), | 294 buffer->GetBufferStart(), |
| 292 buffer->GetBufferSize(), | 295 buffer->GetBufferSize(), |
| 293 NULL, | 296 NULL, |
| 294 buffer->GetCleanOverlapped()); | 297 buffer->GetCleanOverlapped()); |
| 295 if (ok || GetLastError() == ERROR_IO_PENDING) { | 298 if (ok || GetLastError() == ERROR_IO_PENDING) { |
| 296 // Completing asynchronously. | 299 // Completing asynchronously. |
| 297 pending_write_ = buffer; | 300 pending_write_ = buffer; |
| 298 return true; | 301 return true; |
| 299 } | 302 } |
| 300 IOBuffer::DisposeBuffer(buffer); | 303 OverlappedBuffer::DisposeBuffer(buffer); |
| 301 HandleIssueError(); | 304 HandleIssueError(); |
| 302 return false; | 305 return false; |
| 303 } | 306 } |
| 304 | 307 |
| 305 | 308 |
| 306 void Handle::HandleIssueError() { | 309 void Handle::HandleIssueError() { |
| 307 DWORD error = GetLastError(); | 310 DWORD error = GetLastError(); |
| 308 if (error == ERROR_BROKEN_PIPE) { | 311 if (error == ERROR_BROKEN_PIPE) { |
| 309 event_handler_->HandleClosed(this); | 312 event_handler_->HandleClosed(this); |
| 310 } else { | 313 } else { |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 376 ScopedLock lock(this); | 379 ScopedLock lock(this); |
| 377 | 380 |
| 378 // For AcceptEx there needs to be buffer storage for address | 381 // For AcceptEx there needs to be buffer storage for address |
| 379 // information for two addresses (local and remote address). The | 382 // information for two addresses (local and remote address). The |
| 380 // AcceptEx documentation says: "This value must be at least 16 | 383 // AcceptEx documentation says: "This value must be at least 16 |
| 381 // bytes more than the maximum address length for the transport | 384 // bytes more than the maximum address length for the transport |
| 382 // protocol in use." | 385 // protocol in use." |
| 383 static const int kAcceptExAddressAdditionalBytes = 16; | 386 static const int kAcceptExAddressAdditionalBytes = 16; |
| 384 static const int kAcceptExAddressStorageSize = | 387 static const int kAcceptExAddressStorageSize = |
| 385 sizeof(SOCKADDR_STORAGE) + kAcceptExAddressAdditionalBytes; | 388 sizeof(SOCKADDR_STORAGE) + kAcceptExAddressAdditionalBytes; |
| 386 IOBuffer* buffer = | 389 OverlappedBuffer* buffer = |
| 387 IOBuffer::AllocateAcceptBuffer(2 * kAcceptExAddressStorageSize); | 390 OverlappedBuffer::AllocateAcceptBuffer(2 * kAcceptExAddressStorageSize); |
| 388 DWORD received; | 391 DWORD received; |
| 389 BOOL ok; | 392 BOOL ok; |
| 390 ok = AcceptEx_(socket(), | 393 ok = AcceptEx_(socket(), |
| 391 buffer->client(), | 394 buffer->client(), |
| 392 buffer->GetBufferStart(), | 395 buffer->GetBufferStart(), |
| 393 0, // For now don't receive data with accept. | 396 0, // For now don't receive data with accept. |
| 394 kAcceptExAddressStorageSize, | 397 kAcceptExAddressStorageSize, |
| 395 kAcceptExAddressStorageSize, | 398 kAcceptExAddressStorageSize, |
| 396 &received, | 399 &received, |
| 397 buffer->GetCleanOverlapped()); | 400 buffer->GetCleanOverlapped()); |
| 398 if (!ok) { | 401 if (!ok) { |
| 399 if (WSAGetLastError() != WSA_IO_PENDING) { | 402 if (WSAGetLastError() != WSA_IO_PENDING) { |
| 400 Log::PrintErr("AcceptEx failed: %d\n", WSAGetLastError()); | 403 Log::PrintErr("AcceptEx failed: %d\n", WSAGetLastError()); |
| 401 closesocket(buffer->client()); | 404 closesocket(buffer->client()); |
| 402 IOBuffer::DisposeBuffer(buffer); | 405 OverlappedBuffer::DisposeBuffer(buffer); |
| 403 return false; | 406 return false; |
| 404 } | 407 } |
| 405 } | 408 } |
| 406 | 409 |
| 407 pending_accept_count_++; | 410 pending_accept_count_++; |
| 408 | 411 |
| 409 return true; | 412 return true; |
| 410 } | 413 } |
| 411 | 414 |
| 412 | 415 |
| 413 void ListenSocket::AcceptComplete(IOBuffer* buffer, HANDLE completion_port) { | 416 void ListenSocket::AcceptComplete(OverlappedBuffer* buffer, |
| 417 HANDLE completion_port) { |
| 414 ScopedLock lock(this); | 418 ScopedLock lock(this); |
| 415 if (!IsClosing()) { | 419 if (!IsClosing()) { |
| 416 // Update the accepted socket to support the full range of API calls. | 420 // Update the accepted socket to support the full range of API calls. |
| 417 SOCKET s = socket(); | 421 SOCKET s = socket(); |
| 418 int rc = setsockopt(buffer->client(), | 422 int rc = setsockopt(buffer->client(), |
| 419 SOL_SOCKET, | 423 SOL_SOCKET, |
| 420 SO_UPDATE_ACCEPT_CONTEXT, | 424 SO_UPDATE_ACCEPT_CONTEXT, |
| 421 reinterpret_cast<char*>(&s), sizeof(s)); | 425 reinterpret_cast<char*>(&s), sizeof(s)); |
| 422 if (rc == NO_ERROR) { | 426 if (rc == NO_ERROR) { |
| 423 // Insert the accepted socket into the list. | 427 // Insert the accepted socket into the list. |
| (...skipping 10 matching lines...) Expand all Loading... |
| 434 } else { | 438 } else { |
| 435 Log::PrintErr("setsockopt failed: %d\n", WSAGetLastError()); | 439 Log::PrintErr("setsockopt failed: %d\n", WSAGetLastError()); |
| 436 closesocket(buffer->client()); | 440 closesocket(buffer->client()); |
| 437 } | 441 } |
| 438 } else { | 442 } else { |
| 439 // Close the socket, as it's already accepted. | 443 // Close the socket, as it's already accepted. |
| 440 closesocket(buffer->client()); | 444 closesocket(buffer->client()); |
| 441 } | 445 } |
| 442 | 446 |
| 443 pending_accept_count_--; | 447 pending_accept_count_--; |
| 444 IOBuffer::DisposeBuffer(buffer); | 448 OverlappedBuffer::DisposeBuffer(buffer); |
| 445 } | 449 } |
| 446 | 450 |
| 447 | 451 |
| 448 void ListenSocket::DoClose() { | 452 void ListenSocket::DoClose() { |
| 449 closesocket(socket()); | 453 closesocket(socket()); |
| 450 handle_ = INVALID_HANDLE_VALUE; | 454 handle_ = INVALID_HANDLE_VALUE; |
| 451 while (CanAccept()) { | 455 while (CanAccept()) { |
| 452 // Get rid of connections already accepted. | 456 // Get rid of connections already accepted. |
| 453 ClientSocket *client = Accept(); | 457 ClientSocket *client = Accept(); |
| 454 if (client != NULL) { | 458 if (client != NULL) { |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 501 ASSERT(!data_ready_->IsEmpty()); | 505 ASSERT(!data_ready_->IsEmpty()); |
| 502 return data_ready_->GetRemainingLength(); | 506 return data_ready_->GetRemainingLength(); |
| 503 } | 507 } |
| 504 | 508 |
| 505 | 509 |
| 506 int Handle::Read(void* buffer, int num_bytes) { | 510 int Handle::Read(void* buffer, int num_bytes) { |
| 507 ScopedLock lock(this); | 511 ScopedLock lock(this); |
| 508 if (data_ready_ == NULL) return 0; | 512 if (data_ready_ == NULL) return 0; |
| 509 num_bytes = data_ready_->Read(buffer, num_bytes); | 513 num_bytes = data_ready_->Read(buffer, num_bytes); |
| 510 if (data_ready_->IsEmpty()) { | 514 if (data_ready_->IsEmpty()) { |
| 511 IOBuffer::DisposeBuffer(data_ready_); | 515 OverlappedBuffer::DisposeBuffer(data_ready_); |
| 512 data_ready_ = NULL; | 516 data_ready_ = NULL; |
| 513 } | 517 } |
| 514 return num_bytes; | 518 return num_bytes; |
| 515 } | 519 } |
| 516 | 520 |
| 517 | 521 |
| 518 int Handle::Write(const void* buffer, int num_bytes) { | 522 int Handle::Write(const void* buffer, int num_bytes) { |
| 519 ScopedLock lock(this); | 523 ScopedLock lock(this); |
| 520 if (SupportsOverlappedIO()) { | 524 if (SupportsOverlappedIO()) { |
| 521 if (pending_write_ != NULL) return 0; | 525 if (pending_write_ != NULL) return 0; |
| 522 if (completion_port_ == INVALID_HANDLE_VALUE) return 0; | 526 if (completion_port_ == INVALID_HANDLE_VALUE) return 0; |
| 523 if (num_bytes > kBufferSize) num_bytes = kBufferSize; | 527 if (num_bytes > kBufferSize) num_bytes = kBufferSize; |
| 524 pending_write_ = IOBuffer::AllocateWriteBuffer(num_bytes); | 528 pending_write_ = OverlappedBuffer::AllocateWriteBuffer(num_bytes); |
| 525 pending_write_->Write(buffer, num_bytes); | 529 pending_write_->Write(buffer, num_bytes); |
| 526 if (!IssueWrite()) return -1; | 530 if (!IssueWrite()) return -1; |
| 527 return num_bytes; | 531 return num_bytes; |
| 528 } else { | 532 } else { |
| 529 DWORD bytes_written = -1; | 533 DWORD bytes_written = -1; |
| 530 BOOL ok = WriteFile(handle_, | 534 BOOL ok = WriteFile(handle_, |
| 531 buffer, | 535 buffer, |
| 532 num_bytes, | 536 num_bytes, |
| 533 &bytes_written, | 537 &bytes_written, |
| 534 NULL); | 538 NULL); |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 580 shutdown(socket(), SD_BOTH); | 584 shutdown(socket(), SD_BOTH); |
| 581 IssueDisconnect(); | 585 IssueDisconnect(); |
| 582 } | 586 } |
| 583 | 587 |
| 584 | 588 |
| 585 bool ClientSocket::IssueRead() { | 589 bool ClientSocket::IssueRead() { |
| 586 ScopedLock lock(this); | 590 ScopedLock lock(this); |
| 587 ASSERT(completion_port_ != INVALID_HANDLE_VALUE); | 591 ASSERT(completion_port_ != INVALID_HANDLE_VALUE); |
| 588 ASSERT(pending_read_ == NULL); | 592 ASSERT(pending_read_ == NULL); |
| 589 | 593 |
| 590 IOBuffer* buffer = IOBuffer::AllocateReadBuffer(1024); | 594 OverlappedBuffer* buffer = OverlappedBuffer::AllocateReadBuffer(1024); |
| 591 | 595 |
| 592 DWORD flags; | 596 DWORD flags; |
| 593 flags = 0; | 597 flags = 0; |
| 594 int rc = WSARecv(socket(), | 598 int rc = WSARecv(socket(), |
| 595 buffer->GetWASBUF(), | 599 buffer->GetWASBUF(), |
| 596 1, | 600 1, |
| 597 NULL, | 601 NULL, |
| 598 &flags, | 602 &flags, |
| 599 buffer->GetCleanOverlapped(), | 603 buffer->GetCleanOverlapped(), |
| 600 NULL); | 604 NULL); |
| 601 if (rc == NO_ERROR || WSAGetLastError() == WSA_IO_PENDING) { | 605 if (rc == NO_ERROR || WSAGetLastError() == WSA_IO_PENDING) { |
| 602 pending_read_ = buffer; | 606 pending_read_ = buffer; |
| 603 return true; | 607 return true; |
| 604 } | 608 } |
| 605 IOBuffer::DisposeBuffer(buffer); | 609 OverlappedBuffer::DisposeBuffer(buffer); |
| 606 pending_read_ = NULL; | 610 pending_read_ = NULL; |
| 607 HandleIssueError(); | 611 HandleIssueError(); |
| 608 return false; | 612 return false; |
| 609 } | 613 } |
| 610 | 614 |
| 611 | 615 |
| 612 bool ClientSocket::IssueWrite() { | 616 bool ClientSocket::IssueWrite() { |
| 613 ScopedLock lock(this); | 617 ScopedLock lock(this); |
| 614 ASSERT(completion_port_ != INVALID_HANDLE_VALUE); | 618 ASSERT(completion_port_ != INVALID_HANDLE_VALUE); |
| 615 ASSERT(pending_write_ != NULL); | 619 ASSERT(pending_write_ != NULL); |
| 616 ASSERT(pending_write_->operation() == IOBuffer::kWrite); | 620 ASSERT(pending_write_->operation() == OverlappedBuffer::kWrite); |
| 617 | 621 |
| 618 int rc = WSASend(socket(), | 622 int rc = WSASend(socket(), |
| 619 pending_write_->GetWASBUF(), | 623 pending_write_->GetWASBUF(), |
| 620 1, | 624 1, |
| 621 NULL, | 625 NULL, |
| 622 0, | 626 0, |
| 623 pending_write_->GetCleanOverlapped(), | 627 pending_write_->GetCleanOverlapped(), |
| 624 NULL); | 628 NULL); |
| 625 if (rc == NO_ERROR || WSAGetLastError() == WSA_IO_PENDING) { | 629 if (rc == NO_ERROR || WSAGetLastError() == WSA_IO_PENDING) { |
| 626 return true; | 630 return true; |
| 627 } | 631 } |
| 628 IOBuffer::DisposeBuffer(pending_write_); | 632 OverlappedBuffer::DisposeBuffer(pending_write_); |
| 629 pending_write_ = NULL; | 633 pending_write_ = NULL; |
| 630 HandleIssueError(); | 634 HandleIssueError(); |
| 631 return false; | 635 return false; |
| 632 } | 636 } |
| 633 | 637 |
| 634 | 638 |
| 635 void ClientSocket::IssueDisconnect() { | 639 void ClientSocket::IssueDisconnect() { |
| 636 Dart_Port p = port(); | 640 Dart_Port p = port(); |
| 637 IOBuffer* buffer = IOBuffer::AllocateDisconnectBuffer(); | 641 OverlappedBuffer* buffer = OverlappedBuffer::AllocateDisconnectBuffer(); |
| 638 BOOL ok = DisconnectEx_( | 642 BOOL ok = DisconnectEx_( |
| 639 socket(), buffer->GetCleanOverlapped(), TF_REUSE_SOCKET, 0); | 643 socket(), buffer->GetCleanOverlapped(), TF_REUSE_SOCKET, 0); |
| 640 if (!ok && WSAGetLastError() != WSA_IO_PENDING) { | 644 if (!ok && WSAGetLastError() != WSA_IO_PENDING) { |
| 641 DisconnectComplete(buffer); | 645 DisconnectComplete(buffer); |
| 642 } | 646 } |
| 643 if (p != ILLEGAL_PORT) DartUtils::PostInt32(p, 1 << kDestroyedEvent); | 647 if (p != ILLEGAL_PORT) DartUtils::PostInt32(p, 1 << kDestroyedEvent); |
| 644 } | 648 } |
| 645 | 649 |
| 646 | 650 |
| 647 void ClientSocket::DisconnectComplete(IOBuffer* buffer) { | 651 void ClientSocket::DisconnectComplete(OverlappedBuffer* buffer) { |
| 648 IOBuffer::DisposeBuffer(buffer); | 652 OverlappedBuffer::DisposeBuffer(buffer); |
| 649 closesocket(socket()); | 653 closesocket(socket()); |
| 650 if (data_ready_ != NULL) { | 654 if (data_ready_ != NULL) { |
| 651 IOBuffer::DisposeBuffer(data_ready_); | 655 OverlappedBuffer::DisposeBuffer(data_ready_); |
| 652 } | 656 } |
| 653 // When disconnect is complete get rid of the object. | 657 // When disconnect is complete get rid of the object. |
| 654 delete this; | 658 delete this; |
| 655 } | 659 } |
| 656 | 660 |
| 657 | 661 |
| 658 void ClientSocket::EnsureInitialized( | 662 void ClientSocket::EnsureInitialized( |
| 659 EventHandlerImplementation* event_handler) { | 663 EventHandlerImplementation* event_handler) { |
| 660 ScopedLock lock(this); | 664 ScopedLock lock(this); |
| 661 if (completion_port_ == INVALID_HANDLE_VALUE) { | 665 if (completion_port_ == INVALID_HANDLE_VALUE) { |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 769 handle->SetPortAndMask(msg->dart_port, msg->data); | 773 handle->SetPortAndMask(msg->dart_port, msg->data); |
| 770 handle->Close(); | 774 handle->Close(); |
| 771 } | 775 } |
| 772 } | 776 } |
| 773 DeleteIfClosed(handle); | 777 DeleteIfClosed(handle); |
| 774 } | 778 } |
| 775 } | 779 } |
| 776 | 780 |
| 777 | 781 |
| 778 void EventHandlerImplementation::HandleAccept(ListenSocket* listen_socket, | 782 void EventHandlerImplementation::HandleAccept(ListenSocket* listen_socket, |
| 779 IOBuffer* buffer) { | 783 OverlappedBuffer* buffer) { |
| 780 listen_socket->AcceptComplete(buffer, completion_port_); | 784 listen_socket->AcceptComplete(buffer, completion_port_); |
| 781 | 785 |
| 782 if (!listen_socket->IsClosing()) { | 786 if (!listen_socket->IsClosing()) { |
| 783 int event_mask = 1 << kInEvent; | 787 int event_mask = 1 << kInEvent; |
| 784 if ((listen_socket->mask() & event_mask) != 0) { | 788 if ((listen_socket->mask() & event_mask) != 0) { |
| 785 DartUtils::PostInt32(listen_socket->port(), event_mask); | 789 DartUtils::PostInt32(listen_socket->port(), event_mask); |
| 786 } | 790 } |
| 787 } | 791 } |
| 788 | 792 |
| 789 DeleteIfClosed(listen_socket); | 793 DeleteIfClosed(listen_socket); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 803 handle->MarkError(); | 807 handle->MarkError(); |
| 804 if (!handle->IsClosing()) { | 808 if (!handle->IsClosing()) { |
| 805 int event_mask = 1 << kErrorEvent; | 809 int event_mask = 1 << kErrorEvent; |
| 806 DartUtils::PostInt32(handle->port(), event_mask); | 810 DartUtils::PostInt32(handle->port(), event_mask); |
| 807 } | 811 } |
| 808 } | 812 } |
| 809 | 813 |
| 810 | 814 |
| 811 void EventHandlerImplementation::HandleRead(Handle* handle, | 815 void EventHandlerImplementation::HandleRead(Handle* handle, |
| 812 int bytes, | 816 int bytes, |
| 813 IOBuffer* buffer) { | 817 OverlappedBuffer* buffer) { |
| 814 buffer->set_data_length(bytes); | 818 buffer->set_data_length(bytes); |
| 815 handle->ReadComplete(buffer); | 819 handle->ReadComplete(buffer); |
| 816 if (bytes > 0) { | 820 if (bytes > 0) { |
| 817 if (!handle->IsClosing()) { | 821 if (!handle->IsClosing()) { |
| 818 int event_mask = 1 << kInEvent; | 822 int event_mask = 1 << kInEvent; |
| 819 if ((handle->mask() & event_mask) != 0) { | 823 if ((handle->mask() & event_mask) != 0) { |
| 820 DartUtils::PostInt32(handle->port(), event_mask); | 824 DartUtils::PostInt32(handle->port(), event_mask); |
| 821 } | 825 } |
| 822 } | 826 } |
| 823 } else { | 827 } else { |
| 824 handle->MarkClosedRead(); | 828 handle->MarkClosedRead(); |
| 825 if (bytes == 0) { | 829 if (bytes == 0) { |
| 826 HandleClosed(handle); | 830 HandleClosed(handle); |
| 827 } else { | 831 } else { |
| 828 HandleError(handle); | 832 HandleError(handle); |
| 829 } | 833 } |
| 830 } | 834 } |
| 831 | 835 |
| 832 DeleteIfClosed(handle); | 836 DeleteIfClosed(handle); |
| 833 } | 837 } |
| 834 | 838 |
| 835 | 839 |
| 836 void EventHandlerImplementation::HandleWrite(Handle* handle, | 840 void EventHandlerImplementation::HandleWrite(Handle* handle, |
| 837 int bytes, | 841 int bytes, |
| 838 IOBuffer* buffer) { | 842 OverlappedBuffer* buffer) { |
| 839 handle->WriteComplete(buffer); | 843 handle->WriteComplete(buffer); |
| 840 | 844 |
| 841 if (bytes > 0) { | 845 if (bytes > 0) { |
| 842 if (!handle->IsError() && !handle->IsClosing()) { | 846 if (!handle->IsError() && !handle->IsClosing()) { |
| 843 int event_mask = 1 << kOutEvent; | 847 int event_mask = 1 << kOutEvent; |
| 844 if ((handle->mask() & event_mask) != 0) { | 848 if ((handle->mask() & event_mask) != 0) { |
| 845 DartUtils::PostInt32(handle->port(), event_mask); | 849 DartUtils::PostInt32(handle->port(), event_mask); |
| 846 } | 850 } |
| 847 } | 851 } |
| 848 } else if (bytes == 0) { | 852 } else if (bytes == 0) { |
| 849 HandleClosed(handle); | 853 HandleClosed(handle); |
| 850 } else { | 854 } else { |
| 851 HandleError(handle); | 855 HandleError(handle); |
| 852 } | 856 } |
| 853 | 857 |
| 854 DeleteIfClosed(handle); | 858 DeleteIfClosed(handle); |
| 855 } | 859 } |
| 856 | 860 |
| 857 | 861 |
| 858 void EventHandlerImplementation::HandleDisconnect( | 862 void EventHandlerImplementation::HandleDisconnect( |
| 859 ClientSocket* client_socket, | 863 ClientSocket* client_socket, |
| 860 int bytes, | 864 int bytes, |
| 861 IOBuffer* buffer) { | 865 OverlappedBuffer* buffer) { |
| 862 client_socket->DisconnectComplete(buffer); | 866 client_socket->DisconnectComplete(buffer); |
| 863 } | 867 } |
| 864 | 868 |
| 865 void EventHandlerImplementation::HandleTimeout() { | 869 void EventHandlerImplementation::HandleTimeout() { |
| 866 if (!timeout_queue_.HasTimeout()) return; | 870 if (!timeout_queue_.HasTimeout()) return; |
| 867 DartUtils::PostNull(timeout_queue_.CurrentPort()); | 871 DartUtils::PostNull(timeout_queue_.CurrentPort()); |
| 868 timeout_queue_.RemoveCurrent(); | 872 timeout_queue_.RemoveCurrent(); |
| 869 } | 873 } |
| 870 | 874 |
| 871 | 875 |
| 872 void EventHandlerImplementation::HandleIOCompletion(DWORD bytes, | 876 void EventHandlerImplementation::HandleIOCompletion(DWORD bytes, |
| 873 ULONG_PTR key, | 877 ULONG_PTR key, |
| 874 OVERLAPPED* overlapped) { | 878 OVERLAPPED* overlapped) { |
| 875 IOBuffer* buffer = IOBuffer::GetFromOverlapped(overlapped); | 879 OverlappedBuffer* buffer = OverlappedBuffer::GetFromOverlapped(overlapped); |
| 876 switch (buffer->operation()) { | 880 switch (buffer->operation()) { |
| 877 case IOBuffer::kAccept: { | 881 case OverlappedBuffer::kAccept: { |
| 878 ListenSocket* listen_socket = reinterpret_cast<ListenSocket*>(key); | 882 ListenSocket* listen_socket = reinterpret_cast<ListenSocket*>(key); |
| 879 HandleAccept(listen_socket, buffer); | 883 HandleAccept(listen_socket, buffer); |
| 880 break; | 884 break; |
| 881 } | 885 } |
| 882 case IOBuffer::kRead: { | 886 case OverlappedBuffer::kRead: { |
| 883 Handle* handle = reinterpret_cast<Handle*>(key); | 887 Handle* handle = reinterpret_cast<Handle*>(key); |
| 884 HandleRead(handle, bytes, buffer); | 888 HandleRead(handle, bytes, buffer); |
| 885 break; | 889 break; |
| 886 } | 890 } |
| 887 case IOBuffer::kWrite: { | 891 case OverlappedBuffer::kWrite: { |
| 888 Handle* handle = reinterpret_cast<Handle*>(key); | 892 Handle* handle = reinterpret_cast<Handle*>(key); |
| 889 HandleWrite(handle, bytes, buffer); | 893 HandleWrite(handle, bytes, buffer); |
| 890 break; | 894 break; |
| 891 } | 895 } |
| 892 case IOBuffer::kDisconnect: { | 896 case OverlappedBuffer::kDisconnect: { |
| 893 ClientSocket* client_socket = reinterpret_cast<ClientSocket*>(key); | 897 ClientSocket* client_socket = reinterpret_cast<ClientSocket*>(key); |
| 894 HandleDisconnect(client_socket, bytes, buffer); | 898 HandleDisconnect(client_socket, bytes, buffer); |
| 895 break; | 899 break; |
| 896 } | 900 } |
| 897 default: | 901 default: |
| 898 UNREACHABLE(); | 902 UNREACHABLE(); |
| 899 } | 903 } |
| 900 } | 904 } |
| 901 | 905 |
| 902 | 906 |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1012 | 1016 |
| 1013 | 1017 |
| 1014 void EventHandlerImplementation::Shutdown() { | 1018 void EventHandlerImplementation::Shutdown() { |
| 1015 SendData(kShutdownId, 0, 0); | 1019 SendData(kShutdownId, 0, 0); |
| 1016 } | 1020 } |
| 1017 | 1021 |
| 1018 } // namespace bin | 1022 } // namespace bin |
| 1019 } // namespace dart | 1023 } // namespace dart |
| 1020 | 1024 |
| 1021 #endif // defined(TARGET_OS_WINDOWS) | 1025 #endif // defined(TARGET_OS_WINDOWS) |
| OLD | NEW |