Diff
Modified: trunk/Source/_javascript_Core/ChangeLog (269127 => 269128)
--- trunk/Source/_javascript_Core/ChangeLog 2020-10-28 21:34:04 UTC (rev 269127)
+++ trunk/Source/_javascript_Core/ChangeLog 2020-10-28 23:51:45 UTC (rev 269128)
@@ -1,3 +1,28 @@
+2020-10-28 Basuke Suzuki <[email protected]>
+
+ [WinCairo][PlayStation] Add handling for accept failure case
+ https://bugs.webkit.org/show_bug.cgi?id=217353
+
+ Reviewed by Alex Christensen.
+
+ It is rare to happen, but listening socket can be invalid state (i.e. cable disconnection, interface error),
+ and accept() will be called because of the poll's false report. In that situation, it is required to rebuild
+ the listening socket from the scratch. The failure of accept is the good place to capture this situation.
+
+ This patch moves listening duty into Listener internal calss and it is possible to make the invalid state
+ while maintained by SocketEndpoint. Also in case of failure continues, the retry will be gradually increasing
+ the intervals.
+
+ * inspector/remote/socket/RemoteInspectorServer.h:
+ * inspector/remote/socket/RemoteInspectorSocketEndpoint.cpp:
+ (Inspector::RemoteInspectorSocketEndpoint::listenInet):
+ (Inspector::RemoteInspectorSocketEndpoint::pollingTimeout):
+ (Inspector::RemoteInspectorSocketEndpoint::workerThread):
+ (Inspector::RemoteInspectorSocketEndpoint::createClient):
+ (Inspector::RemoteInspectorSocketEndpoint::disconnect):
+ (Inspector::RemoteInspectorSocketEndpoint::acceptInetSocketIfEnabled):
+ * inspector/remote/socket/RemoteInspectorSocketEndpoint.h:
+
2020-10-28 Saam Barati <[email protected]>
Better cache our serialization of the outer TDZ environment when creating FunctionExecutables during bytecode generation
Modified: trunk/Source/_javascript_Core/inspector/remote/socket/RemoteInspectorServer.h (269127 => 269128)
--- trunk/Source/_javascript_Core/inspector/remote/socket/RemoteInspectorServer.h 2020-10-28 21:34:04 UTC (rev 269127)
+++ trunk/Source/_javascript_Core/inspector/remote/socket/RemoteInspectorServer.h 2020-10-28 23:51:45 UTC (rev 269128)
@@ -47,7 +47,7 @@
RemoteInspectorServer() { Socket::init(); }
Optional<ConnectionID> doAccept(RemoteInspectorSocketEndpoint&, PlatformSocketType) final;
- void didClose(RemoteInspectorSocketEndpoint&, ConnectionID) final { };
+ void didChangeStatus(RemoteInspectorSocketEndpoint&, ConnectionID, RemoteInspectorSocketEndpoint::Listener::Status) final { };
Optional<ConnectionID> m_server;
};
Modified: trunk/Source/_javascript_Core/inspector/remote/socket/RemoteInspectorSocketEndpoint.cpp (269127 => 269128)
--- trunk/Source/_javascript_Core/inspector/remote/socket/RemoteInspectorSocketEndpoint.cpp 2020-10-28 21:34:04 UTC (rev 269127)
+++ trunk/Source/_javascript_Core/inspector/remote/socket/RemoteInspectorSocketEndpoint.cpp 2020-10-28 23:51:45 UTC (rev 269128)
@@ -31,7 +31,6 @@
#include <wtf/CryptographicallyRandomNumber.h>
#include <wtf/MainThread.h>
#include <wtf/RunLoop.h>
-#include <wtf/text/WTFString.h>
namespace Inspector {
@@ -90,10 +89,15 @@
Optional<ConnectionID> RemoteInspectorSocketEndpoint::listenInet(const char* address, uint16_t port, Listener& listener)
{
- if (auto socket = Socket::listen(address, port))
- return createListener(*socket, listener);
+ LockHolder lock(m_connectionsLock);
+ auto id = generateConnectionID();
+ auto connection = makeUnique<ListenerConnection>(id, listener, address, port);
+ if (!connection->isListening())
+ return WTF::nullopt;
- return WTF::nullopt;
+ m_listeners.add(id, WTFMove(connection));
+ wakeupWorkerThread();
+ return id;
}
bool RemoteInspectorSocketEndpoint::isListening(ConnectionID id)
@@ -104,6 +108,24 @@
return false;
}
+int RemoteInspectorSocketEndpoint::pollingTimeout()
+{
+ Optional<MonotonicTime> mostRecentWakeup;
+ for (const auto& connection : m_listeners) {
+ if (connection.value->nextRetryTime) {
+ if (mostRecentWakeup)
+ mostRecentWakeup = std::min<MonotonicTime>(*mostRecentWakeup, *connection.value->nextRetryTime);
+ else
+ mostRecentWakeup = connection.value->nextRetryTime;
+ }
+ }
+
+ if (mostRecentWakeup)
+ return static_cast<int>((*mostRecentWakeup - MonotonicTime::now()).milliseconds());
+
+ return -1;
+}
+
void RemoteInspectorSocketEndpoint::workerThread()
{
PollingDescriptor wakeup = Socket::preparePolling(m_wakeupReceiveSocket);
@@ -128,13 +150,17 @@
ids.append(connection.key);
}
for (const auto& connection : m_listeners) {
- pollfds.append(connection.value->poll);
- ids.append(connection.key);
+ if (!connection.value->isListening() && connection.value->listen())
+ connection.value->listener.didChangeStatus(*this, connection.key, Listener::Status::Listening);
+ if (connection.value->isListening()) {
+ pollfds.append(connection.value->poll);
+ ids.append(connection.key);
+ }
}
}
pollfds.append(wakeup);
- if (!Socket::poll(pollfds, -1))
+ if (!Socket::poll(pollfds, pollingTimeout()))
continue;
if (Socket::isReadable(pollfds.last())) {
@@ -180,6 +206,9 @@
LockHolder lock(m_connectionsLock);
auto id = generateConnectionID();
auto connection = makeUnique<ClientConnection>(id, socket, client);
+ if (!Socket::isValid(connection->socket))
+ return WTF::nullopt;
+
m_clients.add(id, WTFMove(connection));
wakeupWorkerThread();
@@ -194,7 +223,7 @@
m_listeners.remove(id);
Socket::close(connection->socket);
lock.unlockEarly();
- connection->listener.didClose(*this, id);
+ connection->listener.didChangeStatus(*this, id, Listener::Status::Closed);
} else if (const auto& connection = m_clients.get(id)) {
m_clients.remove(id);
Socket::close(connection->socket);
@@ -204,38 +233,6 @@
LOG_ERROR("Error: Cannot disconnect: Invalid id");
}
-Optional<ConnectionID> RemoteInspectorSocketEndpoint::createListener(PlatformSocketType socket, Listener& listener)
-{
- ASSERT(Socket::isValid(socket));
-
- if (!Socket::setup(socket))
- return WTF::nullopt;
-
- LockHolder lock(m_connectionsLock);
- auto id = generateConnectionID();
- auto connection = makeUnique<ListenerConnection>(id, socket, listener);
- m_listeners.add(id, WTFMove(connection));
- wakeupWorkerThread();
-
- return id;
-}
-
-Optional<ConnectionID> RemoteInspectorSocketEndpoint::createListener(PlatformSocketType socket, Listener& listener, Client& client)
-{
- ASSERT(Socket::isValid(socket));
-
- if (!Socket::setup(socket))
- return WTF::nullopt;
-
- LockHolder lock(m_connectionsLock);
- auto id = generateConnectionID();
- auto connection = makeUnique<ListenerConnection>(id, socket, listener);
- m_listeners.add(id, WTFMove(connection));
- wakeupWorkerThread();
-
- return id;
-}
-
void RemoteInspectorSocketEndpoint::invalidateClient(Client& client)
{
LockHolder lock(m_connectionsLock);
@@ -359,7 +356,13 @@
lock.unlockEarly();
if (connection->listener.doAccept(*this, socket.value()))
return;
+
Socket::close(*socket);
+ } else {
+ // If accept() returns error, we have to start over with bind() and listen().
+ // By closing socket here, listen() will be called again at the next loop of worker thread.
+ Socket::close(connection->socket);
+ connection->listener.didChangeStatus(*this, id, Listener::Status::Invalid);
}
}
}
Modified: trunk/Source/_javascript_Core/inspector/remote/socket/RemoteInspectorSocketEndpoint.h (269127 => 269128)
--- trunk/Source/_javascript_Core/inspector/remote/socket/RemoteInspectorSocketEndpoint.h 2020-10-28 21:34:04 UTC (rev 269127)
+++ trunk/Source/_javascript_Core/inspector/remote/socket/RemoteInspectorSocketEndpoint.h 2020-10-28 23:51:45 UTC (rev 269128)
@@ -34,6 +34,7 @@
#include <wtf/Lock.h>
#include <wtf/Threading.h>
#include <wtf/Vector.h>
+#include <wtf/text/WTFString.h>
namespace Inspector {
@@ -43,6 +44,8 @@
class Client {
public:
virtual ~Client() { }
+
+ // These callbacks are not guaranteed to be called from the main thread.
virtual void didReceive(RemoteInspectorSocketEndpoint&, ConnectionID, Vector<uint8_t>&&) = 0;
virtual void didClose(RemoteInspectorSocketEndpoint&, ConnectionID) = 0;
};
@@ -49,9 +52,16 @@
class Listener {
public:
+ enum class Status : uint8_t {
+ Listening,
+ Invalid,
+ Closed,
+ };
virtual ~Listener() { }
+
+ // These callbacks are not guaranteed to be called from the main thread.
virtual Optional<ConnectionID> doAccept(RemoteInspectorSocketEndpoint&, PlatformSocketType) = 0;
- virtual void didClose(RemoteInspectorSocketEndpoint&, ConnectionID) = 0;
+ virtual void didChangeStatus(RemoteInspectorSocketEndpoint&, ConnectionID, Status) = 0;
};
static RemoteInspectorSocketEndpoint& singleton();
@@ -69,7 +79,6 @@
inline void send(ConnectionID id, const char* data, size_t length) { send(id, reinterpret_cast<const uint8_t*>(data), length); }
Optional<ConnectionID> createClient(PlatformSocketType, Client&);
- Optional<ConnectionID> createListener(PlatformSocketType, Listener&, Client&);
Optional<uint16_t> getPort(ConnectionID) const;
@@ -79,14 +88,27 @@
struct BaseConnection {
WTF_MAKE_STRUCT_FAST_ALLOCATED;
- BaseConnection(ConnectionID id, PlatformSocketType socket)
+ BaseConnection(ConnectionID id)
: id { id }
- , socket { socket }
- , poll { Socket::preparePolling(socket) }
+ , socket { INVALID_SOCKET_VALUE }
{
- ASSERT(Socket::isValid(socket));
}
+ bool setSocket(PlatformSocketType newSocket)
+ {
+ ASSERT(Socket::isValid(newSocket));
+
+ if (!Socket::setup(newSocket))
+ return false;
+
+ if (Socket::isValid(socket))
+ Socket::close(socket);
+
+ socket = newSocket;
+ poll = Socket::preparePolling(socket);
+ return true;
+ }
+
ConnectionID id;
PlatformSocketType socket;
PollingDescriptor poll;
@@ -94,9 +116,10 @@
struct ClientConnection : public BaseConnection {
ClientConnection(ConnectionID id, PlatformSocketType socket, Client& client)
- : BaseConnection(id, socket)
+ : BaseConnection(id)
, client { client }
{
+ setSocket(socket);
}
Client& client;
@@ -104,17 +127,52 @@
};
struct ListenerConnection : public BaseConnection {
- ListenerConnection(ConnectionID id, PlatformSocketType socket, Listener& listener)
- : BaseConnection(id, socket)
+ static constexpr Seconds initialRetryInterval { 200_ms };
+ static constexpr Seconds maxRetryInterval { 5_s };
+
+ ListenerConnection(ConnectionID id, Listener& listener, const char* address, uint16_t port)
+ : BaseConnection(id)
+ , address { address }
+ , port { port }
, listener { listener }
{
+ listen();
}
+ bool listen()
+ {
+ ASSERT(!isListening());
+
+ if (nextRetryTime && *nextRetryTime > MonotonicTime::now())
+ return false;
+
+ if (auto newSocket = Socket::listen(address.utf8().data(), port)) {
+ if (setSocket(*newSocket)) {
+ retryInterval = initialRetryInterval;
+ return true;
+ }
+ Socket::close(*newSocket);
+ }
+
+ nextRetryTime = MonotonicTime::now() + retryInterval;
+ retryInterval = std::min<Seconds>(retryInterval * 2, maxRetryInterval);
+
+ return false;
+ }
+
+ bool isListening()
+ {
+ return Socket::isListening(socket);
+ }
+
+ String address;
+ uint16_t port;
Listener& listener;
+ Optional<MonotonicTime> nextRetryTime;
+ Seconds retryInterval { initialRetryInterval };
};
ConnectionID generateConnectionID();
- Optional<ConnectionID> createListener(PlatformSocketType, Listener&);
void recvIfEnabled(ConnectionID);
void sendIfEnabled(ConnectionID);
@@ -122,6 +180,7 @@
void wakeupWorkerThread();
void acceptInetSocketIfEnabled(ConnectionID);
bool isListening(ConnectionID);
+ int pollingTimeout();
mutable Lock m_connectionsLock;
HashMap<ConnectionID, std::unique_ptr<ClientConnection>> m_clients;
Modified: trunk/Source/WebDriver/ChangeLog (269127 => 269128)
--- trunk/Source/WebDriver/ChangeLog 2020-10-28 21:34:04 UTC (rev 269127)
+++ trunk/Source/WebDriver/ChangeLog 2020-10-28 23:51:45 UTC (rev 269128)
@@ -1,3 +1,16 @@
+2020-10-28 Basuke Suzuki <[email protected]>
+
+ [WinCairo][PlayStation] Add handling for accept failure case
+ https://bugs.webkit.org/show_bug.cgi?id=217353
+
+ Reviewed by Alex Christensen.
+
+ Following the interface change.
+
+ * HTTPServer.h:
+ * socket/HTTPServerSocket.cpp:
+ (WebDriver::HTTPServer::didStatusChanged):
+
2020-10-22 Nitzan Uziely <[email protected]>
Elements in Shadow DOM are wrongly marked as stale by the WebDriver
Modified: trunk/Source/WebDriver/HTTPServer.h (269127 => 269128)
--- trunk/Source/WebDriver/HTTPServer.h 2020-10-28 21:34:04 UTC (rev 269127)
+++ trunk/Source/WebDriver/HTTPServer.h 2020-10-28 23:51:45 UTC (rev 269128)
@@ -95,7 +95,7 @@
private:
#if USE(INSPECTOR_SOCKET_SERVER)
Optional<ConnectionID> doAccept(RemoteInspectorSocketEndpoint&, PlatformSocketType) final;
- void didClose(RemoteInspectorSocketEndpoint&, ConnectionID) final;
+ void didChangeStatus(RemoteInspectorSocketEndpoint&, ConnectionID, RemoteInspectorSocketEndpoint::Listener::Status) final;
#endif
HTTPRequestHandler& m_requestHandler;
Modified: trunk/Source/WebDriver/socket/HTTPServerSocket.cpp (269127 => 269128)
--- trunk/Source/WebDriver/socket/HTTPServerSocket.cpp 2020-10-28 21:34:04 UTC (rev 269127)
+++ trunk/Source/WebDriver/socket/HTTPServerSocket.cpp 2020-10-28 23:51:45 UTC (rev 269128)
@@ -56,9 +56,10 @@
return WTF::nullopt;
}
-void HTTPServer::didClose(RemoteInspectorSocketEndpoint&, ConnectionID)
+void HTTPServer::didChangeStatus(RemoteInspectorSocketEndpoint&, ConnectionID, RemoteInspectorSocketEndpoint::Listener::Status status)
{
- m_server = WTF::nullopt;
+ if (status == Status::Closed)
+ m_server = WTF::nullopt;
}
void HTTPRequestHandler::connect(ConnectionID id)