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

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

Issue 2540013002: VM: Fix segfault during shutdown of socket listening registry (Closed)
Patch Set: addressed comments Created 4 years 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
« no previous file with comments | « no previous file | no next file » | 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 #if !defined(DART_IO_DISABLED) 5 #if !defined(DART_IO_DISABLED)
6 6
7 #include "bin/socket.h" 7 #include "bin/socket.h"
8 8
9 #include "bin/dartutils.h" 9 #include "bin/dartutils.h"
10 #include "bin/io_buffer.h" 10 #include "bin/io_buffer.h"
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
94 sockets_by_fd_.Remove(GetHashmapKeyFromIntptr(fd), 94 sockets_by_fd_.Remove(GetHashmapKeyFromIntptr(fd),
95 GetHashmapHashFromIntptr(fd)); 95 GetHashmapHashFromIntptr(fd));
96 } 96 }
97 97
98 98
99 Dart_Handle ListeningSocketRegistry::CreateBindListen(Dart_Handle socket_object, 99 Dart_Handle ListeningSocketRegistry::CreateBindListen(Dart_Handle socket_object,
100 RawAddr addr, 100 RawAddr addr,
101 intptr_t backlog, 101 intptr_t backlog,
102 bool v6_only, 102 bool v6_only,
103 bool shared) { 103 bool shared) {
104 MutexLocker ml(ListeningSocketRegistry::mutex_); 104 MutexLocker ml(mutex_);
105 105
106 OSSocket* first_os_socket = NULL;
106 intptr_t port = SocketAddress::GetAddrPort(addr); 107 intptr_t port = SocketAddress::GetAddrPort(addr);
107 OSSocket* first_os_socket = LookupByPort(port); 108 if (port > 0) {
108 if (first_os_socket != NULL) { 109 first_os_socket = LookupByPort(port);
109 // There is already a socket listening on this port. We need to ensure 110 if (first_os_socket != NULL) {
110 // that if there is one also listening on the same address, it was created 111 // There is already a socket listening on this port. We need to ensure
111 // with `shared = true`, ... 112 // that if there is one also listening on the same address, it was created
112 OSSocket* os_socket = first_os_socket; 113 // with `shared = true`, ...
113 OSSocket* os_socket_same_addr = findOSSocketWithAddress(os_socket, addr); 114 OSSocket* os_socket = first_os_socket;
115 OSSocket* os_socket_same_addr = findOSSocketWithAddress(os_socket, addr);
114 116
115 if (os_socket_same_addr != NULL) { 117 if (os_socket_same_addr != NULL) {
116 if (!os_socket_same_addr->shared || !shared) { 118 if (!os_socket_same_addr->shared || !shared) {
117 OSError os_error(-1, 119 OSError os_error(-1,
118 "The shared flag to bind() needs to be `true` if " 120 "The shared flag to bind() needs to be `true` if "
119 "binding multiple times on the same (address, port) " 121 "binding multiple times on the same (address, port) "
120 "combination.", 122 "combination.",
121 OSError::kUnknown); 123 OSError::kUnknown);
122 return DartUtils::NewDartOSError(&os_error); 124 return DartUtils::NewDartOSError(&os_error);
125 }
126 if (os_socket_same_addr->v6_only != v6_only) {
127 OSError os_error(-1,
128 "The v6Only flag to bind() needs to be the same if "
129 "binding multiple times on the same (address, port) "
130 "combination.",
131 OSError::kUnknown);
132 return DartUtils::NewDartOSError(&os_error);
133 }
134
135 // This socket creation is the exact same as the one which originally
136 // created the socket. We therefore increment the refcount and reuse
137 // the file descriptor.
138 os_socket->ref_count++;
139
140 // We set as a side-effect the file descriptor on the dart
141 // socket_object.
142 Socket::SetSocketIdNativeField(socket_object, os_socket->socketfd);
143
144 return Dart_True();
123 } 145 }
124 if (os_socket_same_addr->v6_only != v6_only) {
125 OSError os_error(-1,
126 "The v6Only flag to bind() needs to be the same if "
127 "binding multiple times on the same (address, port) "
128 "combination.",
129 OSError::kUnknown);
130 return DartUtils::NewDartOSError(&os_error);
131 }
132
133 // This socket creation is the exact same as the one which originally
134 // created the socket. We therefore increment the refcount and reuse
135 // the file descriptor.
136 os_socket->ref_count++;
137
138 // We set as a side-effect the file descriptor on the dart socket_object.
139 Socket::SetSocketIdNativeField(socket_object, os_socket->socketfd);
140
141 return Dart_True();
142 } 146 }
143 } 147 }
144 148
145 // There is no socket listening on that (address, port), so we create new one. 149 // There is no socket listening on that (address, port), so we create new one.
146 intptr_t socketfd = ServerSocket::CreateBindListen(addr, backlog, v6_only); 150 intptr_t socketfd = ServerSocket::CreateBindListen(addr, backlog, v6_only);
147 if (socketfd == -5) { 151 if (socketfd == -5) {
148 OSError os_error(-1, "Invalid host", OSError::kUnknown); 152 OSError os_error(-1, "Invalid host", OSError::kUnknown);
149 return DartUtils::NewDartOSError(&os_error); 153 return DartUtils::NewDartOSError(&os_error);
150 } 154 }
151 if (socketfd < 0) { 155 if (socketfd < 0) {
152 OSError error; 156 OSError error;
153 return DartUtils::NewDartOSError(&error); 157 return DartUtils::NewDartOSError(&error);
154 } 158 }
155 if (!ServerSocket::StartAccept(socketfd)) { 159 if (!ServerSocket::StartAccept(socketfd)) {
156 OSError os_error(-1, "Failed to start accept", OSError::kUnknown); 160 OSError os_error(-1, "Failed to start accept", OSError::kUnknown);
157 return DartUtils::NewDartOSError(&os_error); 161 return DartUtils::NewDartOSError(&os_error);
158 } 162 }
159 intptr_t allocated_port = Socket::GetPort(socketfd); 163 intptr_t allocated_port = Socket::GetPort(socketfd);
160 ASSERT(allocated_port > 0); 164 ASSERT(allocated_port > 0);
161 165
166 if (allocated_port != port) {
167 // There are two cases to consider:
168 //
169 // a) The user requested (address, port) where port != 0 which means
170 // we re-use an existing socket if available (and it is shared) or we
171 // create a new one. The new socket is guaranteed to have that
172 // selected port.
173 //
174 // b) The user requested (address, 0). This will make us *always* create a
175 // new socket. The OS will assign it a new `allocated_port` and we will
176 // insert into our data structures. *BUT* There might already be an
177 // existing (address2, `allocated_port`) where address != address2. So
178 // we need to do another `LookupByPort(allocated_port)` and link them
179 // via `OSSocket->next`.
180 ASSERT(port == 0);
181 first_os_socket = LookupByPort(allocated_port);
182 }
183
162 OSSocket* os_socket = 184 OSSocket* os_socket =
163 new OSSocket(addr, allocated_port, v6_only, shared, socketfd); 185 new OSSocket(addr, allocated_port, v6_only, shared, socketfd);
164 os_socket->ref_count = 1; 186 os_socket->ref_count = 1;
165 os_socket->next = first_os_socket; 187 os_socket->next = first_os_socket;
166 188
167 InsertByPort(allocated_port, os_socket); 189 InsertByPort(allocated_port, os_socket);
168 InsertByFd(socketfd, os_socket); 190 InsertByFd(socketfd, os_socket);
169 191
170 // We set as a side-effect the port on the dart socket_object. 192 // We set as a side-effect the port on the dart socket_object.
171 Socket::SetSocketIdNativeField(socket_object, socketfd); 193 Socket::SetSocketIdNativeField(socket_object, socketfd);
(...skipping 747 matching lines...) Expand 10 before | Expand all | Expand 10 after
919 if (Dart_IsError(err)) { 941 if (Dart_IsError(err)) {
920 Dart_PropagateError(err); 942 Dart_PropagateError(err);
921 } 943 }
922 return socket; 944 return socket;
923 } 945 }
924 946
925 } // namespace bin 947 } // namespace bin
926 } // namespace dart 948 } // namespace dart
927 949
928 #endif // !defined(DART_IO_DISABLED) 950 #endif // !defined(DART_IO_DISABLED)
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698