Changeset 269128 in webkit
- Timestamp:
- Oct 28, 2020, 4:51:45 PM (6 years ago)
- Location:
- trunk/Source
- Files:
-
- 7 edited
-
JavaScriptCore/ChangeLog (modified) (1 diff)
-
JavaScriptCore/inspector/remote/socket/RemoteInspectorServer.h (modified) (1 diff)
-
JavaScriptCore/inspector/remote/socket/RemoteInspectorSocketEndpoint.cpp (modified) (8 diffs)
-
JavaScriptCore/inspector/remote/socket/RemoteInspectorSocketEndpoint.h (modified) (8 diffs)
-
WebDriver/ChangeLog (modified) (1 diff)
-
WebDriver/HTTPServer.h (modified) (1 diff)
-
WebDriver/socket/HTTPServerSocket.cpp (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r269115 r269128 1 2020-10-28 Basuke Suzuki <basuke.suzuki@sony.com> 2 3 [WinCairo][PlayStation] Add handling for accept failure case 4 https://bugs.webkit.org/show_bug.cgi?id=217353 5 6 Reviewed by Alex Christensen. 7 8 It is rare to happen, but listening socket can be invalid state (i.e. cable disconnection, interface error), 9 and accept() will be called because of the poll's false report. In that situation, it is required to rebuild 10 the listening socket from the scratch. The failure of accept is the good place to capture this situation. 11 12 This patch moves listening duty into Listener internal calss and it is possible to make the invalid state 13 while maintained by SocketEndpoint. Also in case of failure continues, the retry will be gradually increasing 14 the intervals. 15 16 * inspector/remote/socket/RemoteInspectorServer.h: 17 * inspector/remote/socket/RemoteInspectorSocketEndpoint.cpp: 18 (Inspector::RemoteInspectorSocketEndpoint::listenInet): 19 (Inspector::RemoteInspectorSocketEndpoint::pollingTimeout): 20 (Inspector::RemoteInspectorSocketEndpoint::workerThread): 21 (Inspector::RemoteInspectorSocketEndpoint::createClient): 22 (Inspector::RemoteInspectorSocketEndpoint::disconnect): 23 (Inspector::RemoteInspectorSocketEndpoint::acceptInetSocketIfEnabled): 24 * inspector/remote/socket/RemoteInspectorSocketEndpoint.h: 25 1 26 2020-10-28 Saam Barati <sbarati@apple.com> 2 27 -
trunk/Source/JavaScriptCore/inspector/remote/socket/RemoteInspectorServer.h
r267370 r269128 48 48 49 49 Optional<ConnectionID> doAccept(RemoteInspectorSocketEndpoint&, PlatformSocketType) final; 50 void didC lose(RemoteInspectorSocketEndpoint&, ConnectionID) final { };50 void didChangeStatus(RemoteInspectorSocketEndpoint&, ConnectionID, RemoteInspectorSocketEndpoint::Listener::Status) final { }; 51 51 52 52 Optional<ConnectionID> m_server; -
trunk/Source/JavaScriptCore/inspector/remote/socket/RemoteInspectorSocketEndpoint.cpp
r267370 r269128 32 32 #include <wtf/MainThread.h> 33 33 #include <wtf/RunLoop.h> 34 #include <wtf/text/WTFString.h>35 34 36 35 namespace Inspector { … … 91 90 Optional<ConnectionID> RemoteInspectorSocketEndpoint::listenInet(const char* address, uint16_t port, Listener& listener) 92 91 { 93 if (auto socket = Socket::listen(address, port)) 94 return createListener(*socket, listener); 95 96 return WTF::nullopt; 92 LockHolder lock(m_connectionsLock); 93 auto id = generateConnectionID(); 94 auto connection = makeUnique<ListenerConnection>(id, listener, address, port); 95 if (!connection->isListening()) 96 return WTF::nullopt; 97 98 m_listeners.add(id, WTFMove(connection)); 99 wakeupWorkerThread(); 100 return id; 97 101 } 98 102 … … 103 107 return true; 104 108 return false; 109 } 110 111 int RemoteInspectorSocketEndpoint::pollingTimeout() 112 { 113 Optional<MonotonicTime> mostRecentWakeup; 114 for (const auto& connection : m_listeners) { 115 if (connection.value->nextRetryTime) { 116 if (mostRecentWakeup) 117 mostRecentWakeup = std::min<MonotonicTime>(*mostRecentWakeup, *connection.value->nextRetryTime); 118 else 119 mostRecentWakeup = connection.value->nextRetryTime; 120 } 121 } 122 123 if (mostRecentWakeup) 124 return static_cast<int>((*mostRecentWakeup - MonotonicTime::now()).milliseconds()); 125 126 return -1; 105 127 } 106 128 … … 129 151 } 130 152 for (const auto& connection : m_listeners) { 131 pollfds.append(connection.value->poll); 132 ids.append(connection.key); 153 if (!connection.value->isListening() && connection.value->listen()) 154 connection.value->listener.didChangeStatus(*this, connection.key, Listener::Status::Listening); 155 if (connection.value->isListening()) { 156 pollfds.append(connection.value->poll); 157 ids.append(connection.key); 158 } 133 159 } 134 160 } 135 161 pollfds.append(wakeup); 136 162 137 if (!Socket::poll(pollfds, -1))163 if (!Socket::poll(pollfds, pollingTimeout())) 138 164 continue; 139 165 … … 181 207 auto id = generateConnectionID(); 182 208 auto connection = makeUnique<ClientConnection>(id, socket, client); 209 if (!Socket::isValid(connection->socket)) 210 return WTF::nullopt; 211 183 212 m_clients.add(id, WTFMove(connection)); 184 213 wakeupWorkerThread(); … … 195 224 Socket::close(connection->socket); 196 225 lock.unlockEarly(); 197 connection->listener.didC lose(*this, id);226 connection->listener.didChangeStatus(*this, id, Listener::Status::Closed); 198 227 } else if (const auto& connection = m_clients.get(id)) { 199 228 m_clients.remove(id); … … 203 232 } else 204 233 LOG_ERROR("Error: Cannot disconnect: Invalid id"); 205 }206 207 Optional<ConnectionID> RemoteInspectorSocketEndpoint::createListener(PlatformSocketType socket, Listener& listener)208 {209 ASSERT(Socket::isValid(socket));210 211 if (!Socket::setup(socket))212 return WTF::nullopt;213 214 LockHolder lock(m_connectionsLock);215 auto id = generateConnectionID();216 auto connection = makeUnique<ListenerConnection>(id, socket, listener);217 m_listeners.add(id, WTFMove(connection));218 wakeupWorkerThread();219 220 return id;221 }222 223 Optional<ConnectionID> RemoteInspectorSocketEndpoint::createListener(PlatformSocketType socket, Listener& listener, Client& client)224 {225 ASSERT(Socket::isValid(socket));226 227 if (!Socket::setup(socket))228 return WTF::nullopt;229 230 LockHolder lock(m_connectionsLock);231 auto id = generateConnectionID();232 auto connection = makeUnique<ListenerConnection>(id, socket, listener);233 m_listeners.add(id, WTFMove(connection));234 wakeupWorkerThread();235 236 return id;237 234 } 238 235 … … 360 357 if (connection->listener.doAccept(*this, socket.value())) 361 358 return; 359 362 360 Socket::close(*socket); 361 } else { 362 // If accept() returns error, we have to start over with bind() and listen(). 363 // By closing socket here, listen() will be called again at the next loop of worker thread. 364 Socket::close(connection->socket); 365 connection->listener.didChangeStatus(*this, id, Listener::Status::Invalid); 363 366 } 364 367 } -
trunk/Source/JavaScriptCore/inspector/remote/socket/RemoteInspectorSocketEndpoint.h
r267370 r269128 35 35 #include <wtf/Threading.h> 36 36 #include <wtf/Vector.h> 37 #include <wtf/text/WTFString.h> 37 38 38 39 namespace Inspector { … … 44 45 public: 45 46 virtual ~Client() { } 47 48 // These callbacks are not guaranteed to be called from the main thread. 46 49 virtual void didReceive(RemoteInspectorSocketEndpoint&, ConnectionID, Vector<uint8_t>&&) = 0; 47 50 virtual void didClose(RemoteInspectorSocketEndpoint&, ConnectionID) = 0; … … 50 53 class Listener { 51 54 public: 55 enum class Status : uint8_t { 56 Listening, 57 Invalid, 58 Closed, 59 }; 52 60 virtual ~Listener() { } 61 62 // These callbacks are not guaranteed to be called from the main thread. 53 63 virtual Optional<ConnectionID> doAccept(RemoteInspectorSocketEndpoint&, PlatformSocketType) = 0; 54 virtual void didC lose(RemoteInspectorSocketEndpoint&, ConnectionID) = 0;64 virtual void didChangeStatus(RemoteInspectorSocketEndpoint&, ConnectionID, Status) = 0; 55 65 }; 56 66 … … 70 80 71 81 Optional<ConnectionID> createClient(PlatformSocketType, Client&); 72 Optional<ConnectionID> createListener(PlatformSocketType, Listener&, Client&);73 82 74 83 Optional<uint16_t> getPort(ConnectionID) const; … … 80 89 WTF_MAKE_STRUCT_FAST_ALLOCATED; 81 90 82 BaseConnection(ConnectionID id , PlatformSocketType socket)91 BaseConnection(ConnectionID id) 83 92 : id { id } 84 , socket { socket } 85 , poll { Socket::preparePolling(socket) } 93 , socket { INVALID_SOCKET_VALUE } 86 94 { 87 ASSERT(Socket::isValid(socket)); 95 } 96 97 bool setSocket(PlatformSocketType newSocket) 98 { 99 ASSERT(Socket::isValid(newSocket)); 100 101 if (!Socket::setup(newSocket)) 102 return false; 103 104 if (Socket::isValid(socket)) 105 Socket::close(socket); 106 107 socket = newSocket; 108 poll = Socket::preparePolling(socket); 109 return true; 88 110 } 89 111 … … 95 117 struct ClientConnection : public BaseConnection { 96 118 ClientConnection(ConnectionID id, PlatformSocketType socket, Client& client) 97 : BaseConnection(id , socket)119 : BaseConnection(id) 98 120 , client { client } 99 121 { 122 setSocket(socket); 100 123 } 101 124 … … 105 128 106 129 struct ListenerConnection : public BaseConnection { 107 ListenerConnection(ConnectionID id, PlatformSocketType socket, Listener& listener) 108 : BaseConnection(id, socket) 130 static constexpr Seconds initialRetryInterval { 200_ms }; 131 static constexpr Seconds maxRetryInterval { 5_s }; 132 133 ListenerConnection(ConnectionID id, Listener& listener, const char* address, uint16_t port) 134 : BaseConnection(id) 135 , address { address } 136 , port { port } 109 137 , listener { listener } 110 138 { 139 listen(); 111 140 } 112 141 142 bool listen() 143 { 144 ASSERT(!isListening()); 145 146 if (nextRetryTime && *nextRetryTime > MonotonicTime::now()) 147 return false; 148 149 if (auto newSocket = Socket::listen(address.utf8().data(), port)) { 150 if (setSocket(*newSocket)) { 151 retryInterval = initialRetryInterval; 152 return true; 153 } 154 Socket::close(*newSocket); 155 } 156 157 nextRetryTime = MonotonicTime::now() + retryInterval; 158 retryInterval = std::min<Seconds>(retryInterval * 2, maxRetryInterval); 159 160 return false; 161 } 162 163 bool isListening() 164 { 165 return Socket::isListening(socket); 166 } 167 168 String address; 169 uint16_t port; 113 170 Listener& listener; 171 Optional<MonotonicTime> nextRetryTime; 172 Seconds retryInterval { initialRetryInterval }; 114 173 }; 115 174 116 175 ConnectionID generateConnectionID(); 117 Optional<ConnectionID> createListener(PlatformSocketType, Listener&);118 176 119 177 void recvIfEnabled(ConnectionID); … … 123 181 void acceptInetSocketIfEnabled(ConnectionID); 124 182 bool isListening(ConnectionID); 183 int pollingTimeout(); 125 184 126 185 mutable Lock m_connectionsLock; -
trunk/Source/WebDriver/ChangeLog
r268867 r269128 1 2020-10-28 Basuke Suzuki <basuke.suzuki@sony.com> 2 3 [WinCairo][PlayStation] Add handling for accept failure case 4 https://bugs.webkit.org/show_bug.cgi?id=217353 5 6 Reviewed by Alex Christensen. 7 8 Following the interface change. 9 10 * HTTPServer.h: 11 * socket/HTTPServerSocket.cpp: 12 (WebDriver::HTTPServer::didStatusChanged): 13 1 14 2020-10-22 Nitzan Uziely <linkgoron@gmail.com> 2 15 -
trunk/Source/WebDriver/HTTPServer.h
r267807 r269128 96 96 #if USE(INSPECTOR_SOCKET_SERVER) 97 97 Optional<ConnectionID> doAccept(RemoteInspectorSocketEndpoint&, PlatformSocketType) final; 98 void didC lose(RemoteInspectorSocketEndpoint&, ConnectionID) final;98 void didChangeStatus(RemoteInspectorSocketEndpoint&, ConnectionID, RemoteInspectorSocketEndpoint::Listener::Status) final; 99 99 #endif 100 100 -
trunk/Source/WebDriver/socket/HTTPServerSocket.cpp
r267807 r269128 57 57 } 58 58 59 void HTTPServer::didC lose(RemoteInspectorSocketEndpoint&, ConnectionID)59 void HTTPServer::didChangeStatus(RemoteInspectorSocketEndpoint&, ConnectionID, RemoteInspectorSocketEndpoint::Listener::Status status) 60 60 { 61 m_server = WTF::nullopt; 61 if (status == Status::Closed) 62 m_server = WTF::nullopt; 62 63 } 63 64
Note:
See TracChangeset
for help on using the changeset viewer.