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

Side by Side Diff: dart/runtime/bin/socket.cc

Issue 913753002: Reland "Introduce optional 'bool shared' parameter to ServerSocket.bind() ..." (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 5 years, 10 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 | « dart/runtime/bin/socket.h ('k') | dart/runtime/bin/socket_patch.dart » ('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) 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 "bin/io_buffer.h" 5 #include "bin/io_buffer.h"
6 #include "bin/isolate_data.h" 6 #include "bin/isolate_data.h"
7 #include "bin/dartutils.h" 7 #include "bin/dartutils.h"
8 #include "bin/socket.h" 8 #include "bin/socket.h"
9 #include "bin/thread.h" 9 #include "bin/thread.h"
10 #include "bin/lockers.h"
10 #include "bin/utils.h" 11 #include "bin/utils.h"
11 12
12 #include "platform/globals.h" 13 #include "platform/globals.h"
13 #include "platform/utils.h" 14 #include "platform/utils.h"
14 15
15 #include "include/dart_api.h" 16 #include "include/dart_api.h"
16 17
17 namespace dart { 18 namespace dart {
18 namespace bin { 19 namespace bin {
19 20
20 static const int kSocketIdNativeField = 0; 21 static const int kSocketIdNativeField = 0;
21 22
23
24 ListeningSocketRegistry *globalTcpListeningSocketRegistry = NULL;
25
26
27 void ListeningSocketRegistry::Initialize() {
28 ASSERT(globalTcpListeningSocketRegistry == NULL);
29 globalTcpListeningSocketRegistry = new ListeningSocketRegistry();
30 }
31
32
33 ListeningSocketRegistry *ListeningSocketRegistry::Instance() {
34 return globalTcpListeningSocketRegistry;
35 }
36
37
38 void ListeningSocketRegistry::Cleanup() {
39 delete globalTcpListeningSocketRegistry;
40 globalTcpListeningSocketRegistry = NULL;
41 }
42
43
44 Dart_Handle ListeningSocketRegistry::CreateBindListen(Dart_Handle socket_object,
45 RawAddr addr,
46 intptr_t port,
47 intptr_t backlog,
48 bool v6_only,
49 bool shared) {
50 MutexLocker ml(ListeningSocketRegistry::mutex_);
51
52 SocketsIterator it = sockets_by_port_.find(port);
53 OSSocket *first_os_socket = NULL;
54 if (it != sockets_by_port_.end()) {
55 first_os_socket = it->second;
56 }
57
58 if (first_os_socket != NULL) {
59 // There is already a socket listening on this port. We need to ensure
60 // that if there is one also listening on the same address, it was created
61 // with `shared = true`, ...
62
63 OSSocket *os_socket = it->second;
64 OSSocket *os_socket_same_addr = findOSSocketWithAddress(os_socket, addr);
65
66 if (os_socket_same_addr != NULL) {
67 if (!os_socket_same_addr->shared || !shared) {
68 OSError os_error(-1,
69 "The shared flag to bind() needs to be `true` if "
70 "binding multiple times on the same (address, port) "
71 "combination.",
72 OSError::kUnknown);
73 return DartUtils::NewDartOSError(&os_error);
74 }
75 if (os_socket_same_addr->v6_only != v6_only) {
76 OSError os_error(-1,
77 "The v6Only flag to bind() needs to be the same if "
78 "binding multiple times on the same (address, port) "
79 "combination.",
80 OSError::kUnknown);
81 return DartUtils::NewDartOSError(&os_error);
82 }
83
84 // This socket creation is the exact same as the one which originally
85 // created the socket. We therefore increment the refcount and reuse
86 // the file descriptor.
87 os_socket->ref_count++;
88
89 // We set as a side-effect the file descriptor on the dart socket_object.
90 Socket::SetSocketIdNativeField(socket_object, os_socket->socketfd);
91
92 return Dart_True();
93 }
94 }
95
96 // There is no socket listening on that (address, port), so we create new one.
97 intptr_t socketfd = ServerSocket::CreateBindListen(
98 addr, port, backlog, v6_only);
99 if (socketfd == -5) {
100 OSError os_error(-1, "Invalid host", OSError::kUnknown);
101 return DartUtils::NewDartOSError(&os_error);
102 }
103 if (socketfd < 0) {
104 OSError error;
105 return DartUtils::NewDartOSError(&error);
106 }
107 if (!ServerSocket::StartAccept(socketfd)) {
108 OSError os_error(-1, "Failed to start accept", OSError::kUnknown);
109 return DartUtils::NewDartOSError(&os_error);
110 }
111 intptr_t allocated_port = Socket::GetPort(socketfd);
112 ASSERT(allocated_port > 0);
113
114 OSSocket *os_socket =
115 new OSSocket(addr, allocated_port, v6_only, shared, socketfd);
116 os_socket->ref_count = 1;
117 os_socket->next = first_os_socket;
118 sockets_by_port_[allocated_port] = os_socket;
119 sockets_by_fd_[socketfd] = os_socket;
120
121 // We set as a side-effect the port on the dart socket_object.
122 Socket::SetSocketIdNativeField(socket_object, socketfd);
123
124 return Dart_True();
125 }
126
127
128 bool ListeningSocketRegistry::CloseSafe(intptr_t socketfd) {
129 ASSERT(!mutex_->TryLock());
130
131 SocketsIterator it = sockets_by_fd_.find(socketfd);
132 if (it != sockets_by_fd_.end()) {
133 OSSocket *os_socket = it->second;
134
135 ASSERT(os_socket->ref_count > 0);
136 os_socket->ref_count--;
137 if (os_socket->ref_count == 0) {
138 // We free the OS socket by removing it from two datastructures.
139 sockets_by_fd_.erase(socketfd);
140
141 OSSocket *prev = NULL;
142 OSSocket *current = sockets_by_port_[os_socket->port];
143 while (current != os_socket) {
144 ASSERT(current != NULL);
145 prev = current;
146 current = current->next;
147 }
148
149 if (prev == NULL && current->next == NULL) {
150 // Remove last element from the list.
151 sockets_by_port_.erase(os_socket->port);
152 } else if (prev == NULL) {
153 // Remove first element of the list.
154 sockets_by_port_[os_socket->port] = current->next;
155 } else {
156 // Remove element from the list which is not the first one.
157 prev->next = os_socket->next;
158 }
159
160 delete os_socket;
161 return true;
162 }
163 return false;
164 } else {
165 // It should be impossible for the event handler to close something that
166 // hasn't been created before.
167 UNREACHABLE();
168 return false;
169 }
170 }
171
172
173 Dart_Handle ListeningSocketRegistry::MarkSocketFdAsSharableHack(
174 intptr_t socketfd) {
175 MutexLocker ml(ListeningSocketRegistry::mutex_);
176
177 SocketsIterator it = sockets_by_fd_.find(socketfd);
178 if (it != sockets_by_fd_.end()) {
179 it->second->shared = true;
180 return Dart_True();
181 } else {
182 return Dart_False();
183 }
184 }
185
186
22 void FUNCTION_NAME(InternetAddress_Parse)(Dart_NativeArguments args) { 187 void FUNCTION_NAME(InternetAddress_Parse)(Dart_NativeArguments args) {
23 const char* address = 188 const char* address =
24 DartUtils::GetStringValue(Dart_GetNativeArgument(args, 0)); 189 DartUtils::GetStringValue(Dart_GetNativeArgument(args, 0));
25 ASSERT(address != NULL); 190 ASSERT(address != NULL);
26 RawAddr raw; 191 RawAddr raw;
27 memset(&raw, 0, sizeof(raw)); 192 memset(&raw, 0, sizeof(raw));
28 int type = strchr(address, ':') == NULL ? SocketAddress::TYPE_IPV4 193 int type = strchr(address, ':') == NULL ? SocketAddress::TYPE_IPV4
29 : SocketAddress::TYPE_IPV6; 194 : SocketAddress::TYPE_IPV6;
30 if (type == SocketAddress::TYPE_IPV4) { 195 if (type == SocketAddress::TYPE_IPV4) {
31 raw.addr.sa_family = AF_INET; 196 raw.addr.sa_family = AF_INET;
(...skipping 356 matching lines...) Expand 10 before | Expand all | Expand 10 after
388 SocketAddress::GetSockAddr(Dart_GetNativeArgument(args, 1), &addr); 553 SocketAddress::GetSockAddr(Dart_GetNativeArgument(args, 1), &addr);
389 int64_t port = DartUtils::GetInt64ValueCheckRange( 554 int64_t port = DartUtils::GetInt64ValueCheckRange(
390 Dart_GetNativeArgument(args, 2), 555 Dart_GetNativeArgument(args, 2),
391 0, 556 0,
392 65535); 557 65535);
393 int64_t backlog = DartUtils::GetInt64ValueCheckRange( 558 int64_t backlog = DartUtils::GetInt64ValueCheckRange(
394 Dart_GetNativeArgument(args, 3), 559 Dart_GetNativeArgument(args, 3),
395 0, 560 0,
396 65535); 561 65535);
397 bool v6_only = DartUtils::GetBooleanValue(Dart_GetNativeArgument(args, 4)); 562 bool v6_only = DartUtils::GetBooleanValue(Dart_GetNativeArgument(args, 4));
398 intptr_t socket = ServerSocket::CreateBindListen( 563 bool shared = DartUtils::GetBooleanValue(Dart_GetNativeArgument(args, 5));
399 addr, port, backlog, v6_only); 564
400 OSError error; 565 Dart_Handle socket_object = Dart_GetNativeArgument(args, 0);
401 if (socket >= 0 && ServerSocket::StartAccept(socket)) { 566 Dart_Handle result = ListeningSocketRegistry::Instance()->CreateBindListen(
402 Socket::SetSocketIdNativeField(Dart_GetNativeArgument(args, 0), socket); 567 socket_object, addr, port, backlog, v6_only, shared);
403 Dart_SetReturnValue(args, Dart_True()); 568 Dart_SetReturnValue(args, result);
404 } else {
405 if (socket == -5) {
406 OSError os_error(-1, "Invalid host", OSError::kUnknown);
407 Dart_SetReturnValue(args, DartUtils::NewDartOSError(&os_error));
408 } else {
409 Dart_SetReturnValue(args, DartUtils::NewDartOSError(&error));
410 }
411 }
412 } 569 }
413 570
414 571
415 void FUNCTION_NAME(ServerSocket_Accept)(Dart_NativeArguments args) { 572 void FUNCTION_NAME(ServerSocket_Accept)(Dart_NativeArguments args) {
416 intptr_t socket = 573 intptr_t socket =
417 Socket::GetSocketIdNativeField(Dart_GetNativeArgument(args, 0)); 574 Socket::GetSocketIdNativeField(Dart_GetNativeArgument(args, 0));
418 intptr_t new_socket = ServerSocket::Accept(socket); 575 intptr_t new_socket = ServerSocket::Accept(socket);
419 if (new_socket >= 0) { 576 if (new_socket >= 0) {
420 Socket::SetSocketIdNativeField(Dart_GetNativeArgument(args, 1), new_socket); 577 Socket::SetSocketIdNativeField(Dart_GetNativeArgument(args, 1), new_socket);
421 Dart_SetReturnValue(args, Dart_True()); 578 Dart_SetReturnValue(args, Dart_True());
(...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after
690 int interfaceIndex = 847 int interfaceIndex =
691 DartUtils::GetIntegerValue(Dart_GetNativeArgument(args, 3)); 848 DartUtils::GetIntegerValue(Dart_GetNativeArgument(args, 3));
692 if (Socket::LeaveMulticast(socket, &addr, &interface, interfaceIndex)) { 849 if (Socket::LeaveMulticast(socket, &addr, &interface, interfaceIndex)) {
693 Dart_SetReturnValue(args, Dart_Null()); 850 Dart_SetReturnValue(args, Dart_Null());
694 } else { 851 } else {
695 Dart_SetReturnValue(args, DartUtils::NewDartOSError()); 852 Dart_SetReturnValue(args, DartUtils::NewDartOSError());
696 } 853 }
697 } 854 }
698 855
699 856
857 void FUNCTION_NAME(Socket_MarkSocketAsSharedHack)(Dart_NativeArguments args) {
858 intptr_t socketfd =
859 Socket::GetSocketIdNativeField(Dart_GetNativeArgument(args, 0));
860
861 ListeningSocketRegistry *registry = ListeningSocketRegistry::Instance();
862 Dart_SetReturnValue(args, registry->MarkSocketFdAsSharableHack(socketfd));
863 }
864
865
700 void Socket::SetSocketIdNativeField(Dart_Handle socket, intptr_t id) { 866 void Socket::SetSocketIdNativeField(Dart_Handle socket, intptr_t id) {
701 Dart_Handle err = 867 Dart_Handle err =
702 Dart_SetNativeInstanceField(socket, kSocketIdNativeField, id); 868 Dart_SetNativeInstanceField(socket, kSocketIdNativeField, id);
703 if (Dart_IsError(err)) Dart_PropagateError(err); 869 if (Dart_IsError(err)) Dart_PropagateError(err);
704 } 870 }
705 871
706 872
707 intptr_t Socket::GetSocketIdNativeField(Dart_Handle socket_obj) { 873 intptr_t Socket::GetSocketIdNativeField(Dart_Handle socket_obj) {
708 intptr_t socket = 0; 874 intptr_t socket = 0;
709 Dart_Handle err = 875 Dart_Handle err =
710 Dart_GetNativeInstanceField(socket_obj, kSocketIdNativeField, &socket); 876 Dart_GetNativeInstanceField(socket_obj, kSocketIdNativeField, &socket);
711 if (Dart_IsError(err)) Dart_PropagateError(err); 877 if (Dart_IsError(err)) Dart_PropagateError(err);
712 return socket; 878 return socket;
713 } 879 }
714 880
715 } // namespace bin 881 } // namespace bin
716 } // namespace dart 882 } // namespace dart
OLDNEW
« no previous file with comments | « dart/runtime/bin/socket.h ('k') | dart/runtime/bin/socket_patch.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698