Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "base/sync_socket.h" | 5 #include "base/sync_socket.h" |
| 6 | 6 |
| 7 #include <errno.h> | 7 #include <errno.h> |
| 8 #include <fcntl.h> | 8 #include <fcntl.h> |
| 9 #include <limits.h> | 9 #include <limits.h> |
| 10 #include <stdio.h> | 10 #include <stdio.h> |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 33 const void* buffer, | 33 const void* buffer, |
| 34 size_t length) { | 34 size_t length) { |
| 35 DCHECK_GT(length, 0u); | 35 DCHECK_GT(length, 0u); |
| 36 DCHECK_LE(length, kMaxMessageLength); | 36 DCHECK_LE(length, kMaxMessageLength); |
| 37 DCHECK_NE(handle, SyncSocket::kInvalidHandle); | 37 DCHECK_NE(handle, SyncSocket::kInvalidHandle); |
| 38 const char* charbuffer = static_cast<const char*>(buffer); | 38 const char* charbuffer = static_cast<const char*>(buffer); |
| 39 const int len = file_util::WriteFileDescriptor(handle, charbuffer, length); | 39 const int len = file_util::WriteFileDescriptor(handle, charbuffer, length); |
| 40 return len < 0 ? 0 : static_cast<size_t>(len); | 40 return len < 0 ? 0 : static_cast<size_t>(len); |
| 41 } | 41 } |
| 42 | 42 |
| 43 bool CloseHandle(SyncSocket::Handle handle) { | |
| 44 if (handle != SyncSocket::kInvalidHandle && close(handle) < 0) { | |
|
DaleCurtis
2013/11/01 00:15:59
Removed the EINTR here per http://crbug.com/269623
| |
| 45 DPLOG(ERROR) << "close"; | |
| 46 return false; | |
| 47 } | |
| 48 | |
| 49 return true; | |
| 50 } | |
| 51 | |
| 43 } // namespace | 52 } // namespace |
| 44 | 53 |
| 45 const SyncSocket::Handle SyncSocket::kInvalidHandle = -1; | 54 const SyncSocket::Handle SyncSocket::kInvalidHandle = -1; |
| 46 | 55 |
| 47 SyncSocket::SyncSocket() : handle_(kInvalidHandle) {} | 56 SyncSocket::SyncSocket() : handle_(kInvalidHandle) {} |
| 48 | 57 |
| 49 SyncSocket::~SyncSocket() { | 58 SyncSocket::~SyncSocket() { |
| 50 Close(); | 59 Close(); |
| 51 } | 60 } |
| 52 | 61 |
| 53 // static | 62 // static |
| 54 bool SyncSocket::CreatePair(SyncSocket* socket_a, SyncSocket* socket_b) { | 63 bool SyncSocket::CreatePair(SyncSocket* socket_a, SyncSocket* socket_b) { |
| 55 DCHECK_NE(socket_a, socket_b); | 64 DCHECK_NE(socket_a, socket_b); |
| 56 DCHECK_EQ(socket_a->handle_, kInvalidHandle); | 65 DCHECK_EQ(socket_a->handle_, kInvalidHandle); |
| 57 DCHECK_EQ(socket_b->handle_, kInvalidHandle); | 66 DCHECK_EQ(socket_b->handle_, kInvalidHandle); |
| 58 | 67 |
| 59 #if defined(OS_MACOSX) | 68 #if defined(OS_MACOSX) |
| 60 int nosigpipe = 1; | 69 int nosigpipe = 1; |
| 61 #endif // defined(OS_MACOSX) | 70 #endif // defined(OS_MACOSX) |
| 62 | 71 |
| 63 Handle handles[2] = { kInvalidHandle, kInvalidHandle }; | 72 Handle handles[2] = { kInvalidHandle, kInvalidHandle }; |
| 64 if (socketpair(AF_UNIX, SOCK_STREAM, 0, handles) != 0) | 73 if (socketpair(AF_UNIX, SOCK_STREAM, 0, handles) != 0) { |
| 65 goto cleanup; | 74 CloseHandle(handles[0]); |
| 75 CloseHandle(handles[1]); | |
| 76 return false; | |
| 77 } | |
| 66 | 78 |
| 67 #if defined(OS_MACOSX) | 79 #if defined(OS_MACOSX) |
| 68 // On OSX an attempt to read or write to a closed socket may generate a | 80 // On OSX an attempt to read or write to a closed socket may generate a |
| 69 // SIGPIPE rather than returning -1. setsockopt will shut this off. | 81 // SIGPIPE rather than returning -1. setsockopt will shut this off. |
| 70 if (0 != setsockopt(handles[0], SOL_SOCKET, SO_NOSIGPIPE, | 82 if (0 != setsockopt(handles[0], SOL_SOCKET, SO_NOSIGPIPE, |
| 71 &nosigpipe, sizeof nosigpipe) || | 83 &nosigpipe, sizeof nosigpipe) || |
| 72 0 != setsockopt(handles[1], SOL_SOCKET, SO_NOSIGPIPE, | 84 0 != setsockopt(handles[1], SOL_SOCKET, SO_NOSIGPIPE, |
| 73 &nosigpipe, sizeof nosigpipe)) { | 85 &nosigpipe, sizeof nosigpipe)) { |
| 74 goto cleanup; | 86 CloseHandle(handles[0]); |
| 87 CloseHandle(handles[1]); | |
| 88 return false; | |
| 75 } | 89 } |
| 76 #endif | 90 #endif |
| 77 | 91 |
| 78 // Copy the handles out for successful return. | 92 // Copy the handles out for successful return. |
| 79 socket_a->handle_ = handles[0]; | 93 socket_a->handle_ = handles[0]; |
| 80 socket_b->handle_ = handles[1]; | 94 socket_b->handle_ = handles[1]; |
| 81 | 95 |
| 82 return true; | 96 return true; |
| 83 | |
| 84 cleanup: | |
| 85 if (handles[0] != kInvalidHandle) { | |
| 86 if (HANDLE_EINTR(close(handles[0])) < 0) | |
| 87 DPLOG(ERROR) << "close"; | |
| 88 } | |
| 89 if (handles[1] != kInvalidHandle) { | |
| 90 if (HANDLE_EINTR(close(handles[1])) < 0) | |
| 91 DPLOG(ERROR) << "close"; | |
| 92 } | |
| 93 | |
| 94 return false; | |
| 95 } | 97 } |
| 96 | 98 |
| 97 bool SyncSocket::Close() { | 99 bool SyncSocket::Close() { |
| 98 if (handle_ == kInvalidHandle) | 100 const bool retval = CloseHandle(handle_); |
| 99 return true; | |
| 100 const int retval = HANDLE_EINTR(close(handle_)); | |
| 101 DPLOG_IF(ERROR, retval < 0) << "close"; | |
| 102 handle_ = kInvalidHandle; | 101 handle_ = kInvalidHandle; |
| 103 return retval == 0; | 102 return retval; |
| 104 } | 103 } |
| 105 | 104 |
| 106 size_t SyncSocket::Send(const void* buffer, size_t length) { | 105 size_t SyncSocket::Send(const void* buffer, size_t length) { |
| 107 ThreadRestrictions::AssertIOAllowed(); | 106 ThreadRestrictions::AssertIOAllowed(); |
| 108 return SendHelper(handle_, buffer, length); | 107 return SendHelper(handle_, buffer, length); |
| 109 } | 108 } |
| 110 | 109 |
| 111 size_t SyncSocket::Receive(void* buffer, size_t length) { | 110 size_t SyncSocket::Receive(void* buffer, size_t length) { |
| 112 ThreadRestrictions::AssertIOAllowed(); | 111 ThreadRestrictions::AssertIOAllowed(); |
| 113 DCHECK_GT(length, 0u); | 112 DCHECK_GT(length, 0u); |
| 114 DCHECK_LE(length, kMaxMessageLength); | 113 DCHECK_LE(length, kMaxMessageLength); |
| 115 DCHECK_NE(handle_, kInvalidHandle); | 114 DCHECK_NE(handle_, kInvalidHandle); |
| 116 char* charbuffer = static_cast<char*>(buffer); | 115 char* charbuffer = static_cast<char*>(buffer); |
| 117 if (file_util::ReadFromFD(handle_, charbuffer, length)) | 116 if (file_util::ReadFromFD(handle_, charbuffer, length)) |
| 118 return length; | 117 return length; |
| 119 return 0; | 118 return 0; |
| 120 } | 119 } |
| 121 | 120 |
| 122 size_t SyncSocket::ReceiveWithTimeout(void* buffer, | 121 size_t SyncSocket::ReceiveWithTimeout(void* buffer, |
| 123 size_t length, | 122 size_t length, |
| 124 TimeDelta timeout) { | 123 TimeDelta timeout) { |
| 125 ThreadRestrictions::AssertIOAllowed(); | 124 ThreadRestrictions::AssertIOAllowed(); |
| 126 DCHECK_GT(length, 0u); | 125 DCHECK_GT(length, 0u); |
| 127 DCHECK_LE(length, kMaxMessageLength); | 126 DCHECK_LE(length, kMaxMessageLength); |
| 128 DCHECK_NE(handle_, kInvalidHandle); | 127 DCHECK_NE(handle_, kInvalidHandle); |
| 129 DCHECK_LT(handle_, FD_SETSIZE); | 128 CHECK_LT(handle_, FD_SETSIZE); |
| 130 | 129 |
| 131 // Only timeouts greater than zero and less than one second are allowed. | 130 // Only timeouts greater than zero and less than one second are allowed. |
| 132 DCHECK_GT(timeout.InMicroseconds(), 0); | 131 DCHECK_GT(timeout.InMicroseconds(), 0); |
| 133 DCHECK_LT(timeout.InMicroseconds(), | 132 DCHECK_LT(timeout.InMicroseconds(), |
| 134 base::TimeDelta::FromSeconds(1).InMicroseconds()); | 133 base::TimeDelta::FromSeconds(1).InMicroseconds()); |
| 135 | 134 |
| 136 // Track the start time so we can reduce the timeout as data is read. | 135 // Track the start time so we can reduce the timeout as data is read. |
| 137 TimeTicks start_time = TimeTicks::Now(); | 136 TimeTicks start_time = TimeTicks::Now(); |
| 138 const TimeTicks finish_time = start_time + timeout; | 137 const TimeTicks finish_time = start_time + timeout; |
| 139 | 138 |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 218 return len; | 217 return len; |
| 219 } | 218 } |
| 220 | 219 |
| 221 // static | 220 // static |
| 222 bool CancelableSyncSocket::CreatePair(CancelableSyncSocket* socket_a, | 221 bool CancelableSyncSocket::CreatePair(CancelableSyncSocket* socket_a, |
| 223 CancelableSyncSocket* socket_b) { | 222 CancelableSyncSocket* socket_b) { |
| 224 return SyncSocket::CreatePair(socket_a, socket_b); | 223 return SyncSocket::CreatePair(socket_a, socket_b); |
| 225 } | 224 } |
| 226 | 225 |
| 227 } // namespace base | 226 } // namespace base |
| OLD | NEW |