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

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
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 bool ListeningSocketRegistry::Initialize() {
Søren Gjesse 2015/02/11 08:51:05 Just void return type?
kustermann 2015/02/11 09:56:08 Done.
28 globalTcpListeningSocketRegistry = new ListeningSocketRegistry();
29 return true;
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 return
86 // the file descriptor.
Søren Gjesse 2015/02/11 08:51:05 'return the file descriptor' -> 'reuse the file de
kustermann 2015/02/11 09:56:08 Done.
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) {
Søren Gjesse 2015/02/11 08:51:05 Please add a few comments here 1. Removed last el
kustermann 2015/02/11 09:56:08 Done.
150 sockets_by_port_.erase(os_socket->port);
151 } else if (prev == NULL) {
152 sockets_by_port_[os_socket->port] = current->next;
153 } else {
154 prev->next = os_socket->next;
155 }
156
157 delete os_socket;
158 return true;
159 }
160 return false;
161 } else {
162 // It should be impossible for the event handler to close something that
163 // hasn't been created before.
164 UNREACHABLE();
165 return false;
166 }
167 }
168
169
170 Dart_Handle ListeningSocketRegistry::MarkSocketFdAsSharableHack(
171 intptr_t socketfd) {
172 MutexLocker ml(ListeningSocketRegistry::mutex_);
173
174 SocketsIterator it = sockets_by_fd_.find(socketfd);
175 if (it != sockets_by_fd_.end()) {
176 it->second->shared = true;
177 return Dart_True();
178 } else {
179 return Dart_False();
180 }
181 }
182
183
22 void FUNCTION_NAME(InternetAddress_Parse)(Dart_NativeArguments args) { 184 void FUNCTION_NAME(InternetAddress_Parse)(Dart_NativeArguments args) {
23 const char* address = 185 const char* address =
24 DartUtils::GetStringValue(Dart_GetNativeArgument(args, 0)); 186 DartUtils::GetStringValue(Dart_GetNativeArgument(args, 0));
25 ASSERT(address != NULL); 187 ASSERT(address != NULL);
26 RawAddr raw; 188 RawAddr raw;
27 memset(&raw, 0, sizeof(raw)); 189 memset(&raw, 0, sizeof(raw));
28 int type = strchr(address, ':') == NULL ? SocketAddress::TYPE_IPV4 190 int type = strchr(address, ':') == NULL ? SocketAddress::TYPE_IPV4
29 : SocketAddress::TYPE_IPV6; 191 : SocketAddress::TYPE_IPV6;
30 if (type == SocketAddress::TYPE_IPV4) { 192 if (type == SocketAddress::TYPE_IPV4) {
31 raw.addr.sa_family = AF_INET; 193 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); 550 SocketAddress::GetSockAddr(Dart_GetNativeArgument(args, 1), &addr);
389 int64_t port = DartUtils::GetInt64ValueCheckRange( 551 int64_t port = DartUtils::GetInt64ValueCheckRange(
390 Dart_GetNativeArgument(args, 2), 552 Dart_GetNativeArgument(args, 2),
391 0, 553 0,
392 65535); 554 65535);
393 int64_t backlog = DartUtils::GetInt64ValueCheckRange( 555 int64_t backlog = DartUtils::GetInt64ValueCheckRange(
394 Dart_GetNativeArgument(args, 3), 556 Dart_GetNativeArgument(args, 3),
395 0, 557 0,
396 65535); 558 65535);
397 bool v6_only = DartUtils::GetBooleanValue(Dart_GetNativeArgument(args, 4)); 559 bool v6_only = DartUtils::GetBooleanValue(Dart_GetNativeArgument(args, 4));
398 intptr_t socket = ServerSocket::CreateBindListen( 560 bool shared = DartUtils::GetBooleanValue(Dart_GetNativeArgument(args, 5));
399 addr, port, backlog, v6_only); 561
400 OSError error; 562 Dart_Handle socket_object = Dart_GetNativeArgument(args, 0);
401 if (socket >= 0 && ServerSocket::StartAccept(socket)) { 563 Dart_Handle result = ListeningSocketRegistry::Instance()->CreateBindListen(
402 Socket::SetSocketIdNativeField(Dart_GetNativeArgument(args, 0), socket); 564 socket_object, addr, port, backlog, v6_only, shared);
403 Dart_SetReturnValue(args, Dart_True()); 565 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 } 566 }
413 567
414 568
415 void FUNCTION_NAME(ServerSocket_Accept)(Dart_NativeArguments args) { 569 void FUNCTION_NAME(ServerSocket_Accept)(Dart_NativeArguments args) {
416 intptr_t socket = 570 intptr_t socket =
417 Socket::GetSocketIdNativeField(Dart_GetNativeArgument(args, 0)); 571 Socket::GetSocketIdNativeField(Dart_GetNativeArgument(args, 0));
418 intptr_t new_socket = ServerSocket::Accept(socket); 572 intptr_t new_socket = ServerSocket::Accept(socket);
419 if (new_socket >= 0) { 573 if (new_socket >= 0) {
420 Socket::SetSocketIdNativeField(Dart_GetNativeArgument(args, 1), new_socket); 574 Socket::SetSocketIdNativeField(Dart_GetNativeArgument(args, 1), new_socket);
421 Dart_SetReturnValue(args, Dart_True()); 575 Dart_SetReturnValue(args, Dart_True());
(...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after
690 int interfaceIndex = 844 int interfaceIndex =
691 DartUtils::GetIntegerValue(Dart_GetNativeArgument(args, 3)); 845 DartUtils::GetIntegerValue(Dart_GetNativeArgument(args, 3));
692 if (Socket::LeaveMulticast(socket, &addr, &interface, interfaceIndex)) { 846 if (Socket::LeaveMulticast(socket, &addr, &interface, interfaceIndex)) {
693 Dart_SetReturnValue(args, Dart_Null()); 847 Dart_SetReturnValue(args, Dart_Null());
694 } else { 848 } else {
695 Dart_SetReturnValue(args, DartUtils::NewDartOSError()); 849 Dart_SetReturnValue(args, DartUtils::NewDartOSError());
696 } 850 }
697 } 851 }
698 852
699 853
854 void FUNCTION_NAME(Socket_MarkSocketAsSharedHack)(Dart_NativeArguments args) {
855 intptr_t socketfd =
856 Socket::GetSocketIdNativeField(Dart_GetNativeArgument(args, 0));
857
858 ListeningSocketRegistry *registry = ListeningSocketRegistry::Instance();
859 Dart_SetReturnValue(args, registry->MarkSocketFdAsSharableHack(socketfd));
860 }
861
862
700 void Socket::SetSocketIdNativeField(Dart_Handle socket, intptr_t id) { 863 void Socket::SetSocketIdNativeField(Dart_Handle socket, intptr_t id) {
701 Dart_Handle err = 864 Dart_Handle err =
702 Dart_SetNativeInstanceField(socket, kSocketIdNativeField, id); 865 Dart_SetNativeInstanceField(socket, kSocketIdNativeField, id);
703 if (Dart_IsError(err)) Dart_PropagateError(err); 866 if (Dart_IsError(err)) Dart_PropagateError(err);
704 } 867 }
705 868
706 869
707 intptr_t Socket::GetSocketIdNativeField(Dart_Handle socket_obj) { 870 intptr_t Socket::GetSocketIdNativeField(Dart_Handle socket_obj) {
708 intptr_t socket = 0; 871 intptr_t socket = 0;
709 Dart_Handle err = 872 Dart_Handle err =
710 Dart_GetNativeInstanceField(socket_obj, kSocketIdNativeField, &socket); 873 Dart_GetNativeInstanceField(socket_obj, kSocketIdNativeField, &socket);
711 if (Dart_IsError(err)) Dart_PropagateError(err); 874 if (Dart_IsError(err)) Dart_PropagateError(err);
712 return socket; 875 return socket;
713 } 876 }
714 877
715 } // namespace bin 878 } // namespace bin
716 } // namespace dart 879 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698