Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(166)

Side by Side Diff: base/sync_socket_posix.cc

Issue 8965053: Implement support for a cancelable SyncSocket. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: addressed micro-nit Created 8 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « base/sync_socket.h ('k') | base/sync_socket_win.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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 <limits.h> 8 #include <limits.h>
9 #include <stdio.h> 9 #include <stdio.h>
10 #include <sys/types.h> 10 #include <sys/types.h>
(...skipping 12 matching lines...) Expand all
23 23
24 namespace { 24 namespace {
25 // To avoid users sending negative message lengths to Send/Receive 25 // To avoid users sending negative message lengths to Send/Receive
26 // we clamp message lengths, which are size_t, to no more than INT_MAX. 26 // we clamp message lengths, which are size_t, to no more than INT_MAX.
27 const size_t kMaxMessageLength = static_cast<size_t>(INT_MAX); 27 const size_t kMaxMessageLength = static_cast<size_t>(INT_MAX);
28 28
29 } // namespace 29 } // namespace
30 30
31 const SyncSocket::Handle SyncSocket::kInvalidHandle = -1; 31 const SyncSocket::Handle SyncSocket::kInvalidHandle = -1;
32 32
33 bool SyncSocket::CreatePair(SyncSocket* pair[2]) { 33 SyncSocket::SyncSocket() : handle_(kInvalidHandle) {}
34 Handle handles[2] = { kInvalidHandle, kInvalidHandle }; 34
35 SyncSocket* tmp_sockets[2] = { NULL, NULL }; 35 SyncSocket::~SyncSocket() {
36 Close();
37 }
38
39 // static
40 bool SyncSocket::CreatePair(SyncSocket* socket_a, SyncSocket* socket_b) {
41 DCHECK(socket_a != socket_b);
42 DCHECK(socket_a->handle_ == kInvalidHandle);
43 DCHECK(socket_b->handle_ == kInvalidHandle);
44
36 #if defined(OS_MACOSX) 45 #if defined(OS_MACOSX)
37 int nosigpipe = 1; 46 int nosigpipe = 1;
38 #endif // defined(OS_MACOSX) 47 #endif // defined(OS_MACOSX)
39 48
40 // Create the two SyncSocket objects first to avoid ugly cleanup issues. 49 Handle handles[2] = { kInvalidHandle, kInvalidHandle };
41 tmp_sockets[0] = new SyncSocket(kInvalidHandle); 50 if (socketpair(AF_UNIX, SOCK_STREAM, 0, handles) != 0)
42 if (tmp_sockets[0] == NULL) {
43 goto cleanup; 51 goto cleanup;
44 } 52
45 tmp_sockets[1] = new SyncSocket(kInvalidHandle);
46 if (tmp_sockets[1] == NULL) {
47 goto cleanup;
48 }
49 if (socketpair(AF_UNIX, SOCK_STREAM, 0, handles) != 0) {
50 goto cleanup;
51 }
52 #if defined(OS_MACOSX) 53 #if defined(OS_MACOSX)
53 // On OSX an attempt to read or write to a closed socket may generate a 54 // On OSX an attempt to read or write to a closed socket may generate a
54 // SIGPIPE rather than returning -1. setsockopt will shut this off. 55 // SIGPIPE rather than returning -1. setsockopt will shut this off.
55 if (0 != setsockopt(handles[0], SOL_SOCKET, SO_NOSIGPIPE, 56 if (0 != setsockopt(handles[0], SOL_SOCKET, SO_NOSIGPIPE,
56 &nosigpipe, sizeof nosigpipe) || 57 &nosigpipe, sizeof nosigpipe) ||
57 0 != setsockopt(handles[1], SOL_SOCKET, SO_NOSIGPIPE, 58 0 != setsockopt(handles[1], SOL_SOCKET, SO_NOSIGPIPE,
58 &nosigpipe, sizeof nosigpipe)) { 59 &nosigpipe, sizeof nosigpipe)) {
59 goto cleanup; 60 goto cleanup;
60 } 61 }
61 #endif 62 #endif
63
62 // Copy the handles out for successful return. 64 // Copy the handles out for successful return.
63 tmp_sockets[0]->handle_ = handles[0]; 65 socket_a->handle_ = handles[0];
64 pair[0] = tmp_sockets[0]; 66 socket_b->handle_ = handles[1];
65 tmp_sockets[1]->handle_ = handles[1]; 67
66 pair[1] = tmp_sockets[1];
67 return true; 68 return true;
68 69
69 cleanup: 70 cleanup:
70 if (handles[0] != kInvalidHandle) { 71 if (handles[0] != kInvalidHandle) {
71 if (HANDLE_EINTR(close(handles[0])) < 0) 72 if (HANDLE_EINTR(close(handles[0])) < 0)
72 DPLOG(ERROR) << "close"; 73 DPLOG(ERROR) << "close";
73 } 74 }
74 if (handles[1] != kInvalidHandle) { 75 if (handles[1] != kInvalidHandle) {
75 if (HANDLE_EINTR(close(handles[1])) < 0) 76 if (HANDLE_EINTR(close(handles[1])) < 0)
76 DPLOG(ERROR) << "close"; 77 DPLOG(ERROR) << "close";
77 } 78 }
78 delete tmp_sockets[0]; 79
79 delete tmp_sockets[1];
80 return false; 80 return false;
81 } 81 }
82 82
83 bool SyncSocket::Close() { 83 bool SyncSocket::Close() {
84 if (handle_ == kInvalidHandle) { 84 if (handle_ == kInvalidHandle) {
85 return false; 85 return false;
86 } 86 }
87 int retval = HANDLE_EINTR(close(handle_)); 87 int retval = HANDLE_EINTR(close(handle_));
88 if (retval < 0) 88 if (retval < 0)
89 DPLOG(ERROR) << "close"; 89 DPLOG(ERROR) << "close";
90 handle_ = kInvalidHandle; 90 handle_ = kInvalidHandle;
91 return (retval == 0); 91 return (retval == 0);
92 } 92 }
93 93
94 size_t SyncSocket::Send(const void* buffer, size_t length) { 94 size_t SyncSocket::Send(const void* buffer, size_t length) {
95 DCHECK_LE(length, kMaxMessageLength); 95 DCHECK_LE(length, kMaxMessageLength);
96 const char* charbuffer = static_cast<const char*>(buffer); 96 const char* charbuffer = static_cast<const char*>(buffer);
97 int len = file_util::WriteFileDescriptor(handle_, charbuffer, length); 97 int len = file_util::WriteFileDescriptor(handle_, charbuffer, length);
98 return static_cast<size_t>(len); 98 return static_cast<size_t>(len);
99 } 99 }
100 100
101 size_t SyncSocket::Receive(void* buffer, size_t length) { 101 size_t SyncSocket::Receive(void* buffer, size_t length) {
102 DCHECK_LE(length, kMaxMessageLength); 102 DCHECK_LE(length, kMaxMessageLength);
103 char* charbuffer = static_cast<char*>(buffer); 103 char* charbuffer = static_cast<char*>(buffer);
104 if (file_util::ReadFromFD(handle_, charbuffer, length)) { 104 if (file_util::ReadFromFD(handle_, charbuffer, length))
105 return length; 105 return length;
106 } else { 106 return 0;
107 return -1;
108 }
109 } 107 }
110 108
111 size_t SyncSocket::Peek() { 109 size_t SyncSocket::Peek() {
112 int number_chars; 110 int number_chars;
113 if (-1 == ioctl(handle_, FIONREAD, &number_chars)) { 111 if (-1 == ioctl(handle_, FIONREAD, &number_chars)) {
114 // If there is an error in ioctl, signal that the channel would block. 112 // If there is an error in ioctl, signal that the channel would block.
115 return 0; 113 return 0;
116 } 114 }
117 return (size_t) number_chars; 115 return (size_t) number_chars;
118 } 116 }
119 117
118 CancelableSyncSocket::CancelableSyncSocket() {}
119 CancelableSyncSocket::CancelableSyncSocket(Handle handle)
120 : SyncSocket(handle) {
121 }
122
123 bool CancelableSyncSocket::Shutdown() {
124 return HANDLE_EINTR(shutdown(handle(), SHUT_RDWR)) >= 0;
125 }
126
127 // static
128 bool CancelableSyncSocket::CreatePair(CancelableSyncSocket* socket_a,
129 CancelableSyncSocket* socket_b) {
130 return SyncSocket::CreatePair(socket_a, socket_b);
131 }
132
120 } // namespace base 133 } // namespace base
OLDNEW
« no previous file with comments | « base/sync_socket.h ('k') | base/sync_socket_win.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698