⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 278413 in webkit


Ignore:
Timestamp:
Jun 3, 2021, 12:32:22 PM (5 years ago)
Author:
Patrick Angle
Message:

Web Inspector: [Cocoa] RemoteInspector won't connect to a new relay if it hasn't yet failed to communicate with a previously connected relay
​https://bugs.webkit.org/show_bug.cgi?id=226539

Reviewed by Devin Rousso.

RemoteInspector communicates with a relay daemon running on the same device in order to send updates like new
or removed inspectable targets and receive changes to settings like automatic debugging. The relay daemon then
communicates with a client that connects for debugging. Only one relay daemon should ever be running at a time,
and its lifecycle is managed separately from JavaScriptCore.

RemoteInspector holds a RefPtr to its connection to this relay, and only clears this pointer upon a failure to
communicate over the XPC connection or a known disconnection. However, it is possible, and in some cases likely
(for example the relay restarting from a brief client disconnection and reconnection), that we can be informed
of a newly launched relay being available while still thinking we are connected to the old relay, as we have not
yet sent a message and triggered a failure in the interim period of time.

To correct this we now send a simple message any time setupXPCConnectionIfNeeded is called if we have an
existing RefPtr to a relay connection in order to verify the connection is still functional. We now also retry
to connect to a relay upon failure in order to create a new connection to the current relay.

In order to prevent entering a retry loop where every subsequent retry's failure results in another retry
forever, a flag to retry connecting is set when a call to setupXPCConnectionIfNeeded is made while we already
have a RefPtr to a relay connection. On failure if we are in this special state we will retry once to connect
but subsequent failures will not automatically reattempt a connection.

  • inspector/remote/RemoteInspector.h:
  • inspector/remote/cocoa/RemoteInspectorCocoa.mm:

(Inspector::RemoteInspector::stopInternal):

  • Clear the retry connection flag when stopping in an orderly fashion.

(Inspector::RemoteInspector::setupXPCConnectionIfNeeded):

  • Set the retry connection flag and send a simple message if we already have a relay connection in order to make

sure the connection is either still valid or is torn down properly on failure.
(Inspector::RemoteInspector::xpcConnectionFailed):

  • If the retry flag is set, schedule a retry and clear the retry flag.
Location:
trunk/Source/JavaScriptCore
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r278390 r278413  
     12021-06-03  Patrick Angle  <pangle@apple.com>
     2
     3        Web Inspector: [Cocoa] `RemoteInspector` won't connect to a new relay if it hasn't yet failed to communicate with a previously connected relay
     4        https://bugs.webkit.org/show_bug.cgi?id=226539
     5
     6        Reviewed by Devin Rousso.
     7
     8        `RemoteInspector` communicates with a relay daemon running on the same device in order to send updates like new
     9        or removed inspectable targets and receive changes to settings like automatic debugging. The relay daemon then
     10        communicates with a client that connects for debugging. Only one relay daemon should ever be running at a time,
     11        and its lifecycle is managed separately from JavaScriptCore.
     12
     13        RemoteInspector holds a RefPtr to its connection to this relay, and only clears this pointer upon a failure to
     14        communicate over the XPC connection or a known disconnection. However, it is possible, and in some cases likely
     15        (for example the relay restarting from a brief client disconnection and reconnection), that we can be informed
     16        of a newly launched relay being available while still thinking we are connected to the old relay, as we have not
     17        yet sent a message and triggered a failure in the interim period of time.
     18
     19        To correct this we now send a simple message any time `setupXPCConnectionIfNeeded` is called if we have an
     20        existing RefPtr to a relay connection in order to verify the connection is still functional. We now also retry
     21        to connect to a relay upon failure in order to create a new connection to the current relay.
     22
     23        In order to prevent entering a retry loop where every subsequent retry's failure results in another retry
     24        forever, a flag to retry connecting is set when a call to setupXPCConnectionIfNeeded is made while we already
     25        have a RefPtr to a relay connection. On failure if we are in this special state we will retry once to connect
     26        but subsequent failures will not automatically reattempt a connection.
     27
     28        * inspector/remote/RemoteInspector.h:
     29        * inspector/remote/cocoa/RemoteInspectorCocoa.mm:
     30        (Inspector::RemoteInspector::stopInternal):
     31        - Clear the retry connection flag when stopping in an orderly fashion.
     32        (Inspector::RemoteInspector::setupXPCConnectionIfNeeded):
     33        - Set the retry connection flag and send a simple message if we already have a relay connection in order to make
     34        sure the connection is either still valid or is torn down properly on failure.
     35        (Inspector::RemoteInspector::xpcConnectionFailed):
     36        - If the retry flag is set, schedule a retry and clear the retry flag.
     37
    1382021-06-02  Robin Morisset  <rmorisset@apple.com>
    239
  • trunk/Source/JavaScriptCore/inspector/remote/RemoteInspector.h

    r278253 r278413  
    261261#if PLATFORM(COCOA)
    262262    RefPtr<RemoteInspectorXPCConnection> m_relayConnection;
     263    bool m_shouldReconnectToRelayOnFailure { false };
    263264#endif
    264265#if USE(GLIB)
  • trunk/Source/JavaScriptCore/inspector/remote/cocoa/RemoteInspectorCocoa.mm

    r277920 r278413  
    266266    }
    267267
     268    m_shouldReconnectToRelayOnFailure = false;
     269
    268270    notify_cancel(m_notifyToken);
    269271}
    … …  
    273275    Locker locker { m_mutex };
    274276
    275     if (m_relayConnection)
    276         return;
     277    if (m_relayConnection) {
     278        m_shouldReconnectToRelayOnFailure = true;
     279
     280        // Send a simple message to make sure the connection is still open.
     281        m_relayConnection->sendMessage(@"check", nil);
     282        return;
     283    }
    277284
    278285    auto connection = adoptOSObject(xpc_connection_create_mach_service(WIRXPCMachPortName, m_xpcQueue, 0));
    279     if (!connection)
    280         return;
     286    if (!connection) {
     287        WTFLogAlways("RemoteInspector failed to create XPC connection.");
     288        return;
     289    }
    281290
    282291    m_relayConnection = adoptRef(new RemoteInspectorXPCConnection(connection.get(), m_xpcQueue, this));
    … …  
    364373    // The XPC connection will close itself.
    365374    m_relayConnection = nullptr;
     375
     376    if (!m_shouldReconnectToRelayOnFailure) {
     377        WTFLogAlways("RemoteInspector XPC connection to relay failed.");
     378        return;
     379    }
     380
     381    m_shouldReconnectToRelayOnFailure = false;
     382    WTFLogAlways("RemoteInspector XPC connection to relay failed, reconnecting in 1 second...");
     383
     384    // Schedule setting up a new connection, since we currently are holding a lock needed to create a new connection.
     385    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 1 * NSEC_PER_SEC), dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
     386        RemoteInspector::singleton().setupXPCConnectionIfNeeded();
     387    });
    366388}
    367389
Note: See TracChangeset for help on using the changeset viewer.