From 6792c0205d63fdf279d71f1d0b862e83d0421ee8 Mon Sep 17 00:00:00 2001 From: Mikolaj Staworzynski Date: Mon, 9 Dec 2024 14:24:48 +0100 Subject: [PATCH] ARRISAPP-1222: [WPE 2.38]: [Sky Sports v2] CS2400 observed 2/20 runs - fixed Gently handle randomly spotted case when setup of boot url is interrupted by window.close/DOMWindow::close() (1) Detecting case of failed boot url setup with WEBKIT_NETWORK_ERROR, WEBKIT_NETWORK_ERROR_CANCELLED and do not propagate that event. (2) In NotifyClosure when that case happens repeat internally setup of boot url and do not propagate that event - slauncher wait for boot url setup. (3) url setup method has two versions now: * API one with waiting for result: uint32_t URL(const string& URLwithParams) override => SetupURLInternal(URLwithParams, true); * non API one without waiting for result => SetupURLInternal(URLwithParams, false); --- WebKitBrowser/WebKitImplementation.cpp | 105 +++++++++++++++++-------- 1 file changed, 72 insertions(+), 33 deletions(-) diff --git a/WebKitBrowser/WebKitImplementation.cpp b/WebKitBrowser/WebKitImplementation.cpp index 34fbb5cde..f31485523 100644 --- a/WebKitBrowser/WebKitImplementation.cpp +++ b/WebKitBrowser/WebKitImplementation.cpp @@ -2204,6 +2204,11 @@ static GSourceFuncs _handlerIntervention = } uint32_t URL(const string& URLwithParams) override + { + return SetupURLInternal(URLwithParams); + } + + uint32_t SetupURLInternal(const string& URLwithParams, bool waitForResult = true) { using namespace std::chrono; std::string newCertContents; @@ -2216,17 +2221,14 @@ static GSourceFuncs _handlerIntervention = if (_context != nullptr) { using SetURLData = std::tuple; auto *data = new SetURLData(this, URL, newCertContents); - - { - std::unique_lock lock{urlData_.mutex}; - urlData_.result = Core::ERROR_TIMEDOUT; - } const auto now = steady_clock::now(); - { + if (waitForResult) { std::unique_lock lock{urlData_.mutex}; + urlData_.result = Core::ERROR_TIMEDOUT; urlData_.loadResult.loadUrl = URL; urlData_.loadResult.waitForFailedOrFinished = true; + urlData_.loadResult.waitForExceptionalPageClosureAfterBootUrl = false; } g_main_context_invoke_full( @@ -2263,33 +2265,36 @@ static GSourceFuncs _handlerIntervention = [](gpointer customdata) { delete static_cast(customdata); }); - - std::unique_lock lock{urlData_.mutex}; - TRACE_L1("Start waiting for the load result of url: %s", URL.c_str()); - urlData_.cond.wait_for( - lock, - milliseconds{URL_LOAD_RESULT_TIMEOUT_MS}, - [this](){return Core::ERROR_TIMEDOUT != urlData_.result;}); - - const auto diff = steady_clock::now() - now; - - TRACE_L1( - "URL: %s, load result %s(%d), %dms", - urlData_.url.c_str(), - Core::ERROR_NONE == urlData_.result ? "OK" : "NOK", - int(urlData_.result), - int(duration_cast(diff).count())); - - ODH_WARNING( - "WPE0040", - WPE_CONTEXT_WITH_URL(urlData_.url.c_str()), - "URL: %s, load result %s(%d), %dms", - urlData_.url.c_str(), - Core::ERROR_NONE == urlData_.result ? "OK" : "NOK", - int(urlData_.result), - int(duration_cast(diff).count())); - - return urlData_.result; + if (waitForResult) { + std::unique_lock lock{urlData_.mutex}; + TRACE_L1("Start waiting for the load result of url: %s", URL.c_str()); + urlData_.cond.wait_for( + lock, + milliseconds{URL_LOAD_RESULT_TIMEOUT_MS}, + [this](){return Core::ERROR_TIMEDOUT != urlData_.result;}); + + const auto diff = steady_clock::now() - now; + + TRACE_L1( + "URL: %s, load result %s(%d), %dms", + urlData_.url.c_str(), + Core::ERROR_NONE == urlData_.result ? "OK" : "NOK", + int(urlData_.result), + int(duration_cast(diff).count())); + + ODH_WARNING( + "WPE0040", + WPE_CONTEXT_WITH_URL(urlData_.url.c_str()), + "URL: %s, load result %s(%d), %dms", + urlData_.url.c_str(), + Core::ERROR_NONE == urlData_.result ? "OK" : "NOK", + int(urlData_.result), + int(duration_cast(diff).count())); + + return urlData_.result; + } else { + return Core::ERROR_NONE; + } } else { @@ -2749,6 +2754,19 @@ static GSourceFuncs _handlerIntervention = _adminLock.Unlock(); } + + bool OnLoadFailedCheckWaitingForBootUrl(const string& URL) { + bool postponeNotification = false; + if (URL == _bootUrl) { + std::unique_lock lock{urlData_.mutex}; + if (urlData_.loadResult.waitForFailedOrFinished && urlData_.loadResult.loadUrl == _bootUrl) { + urlData_.loadResult.waitForExceptionalPageClosureAfterBootUrl = true; + postponeNotification = true; + } + } + return postponeNotification; + } + void OnLoadFailed(const string& URL) { urlValue(URL); @@ -3261,8 +3279,23 @@ static GSourceFuncs _handlerIntervention = return (Core::ERROR_NONE); } + bool RepeatLoadUrlWhenPageClosureAndLoadFailedWithReasonCancelledOnBootUrl() { + std::unique_lock lock{urlData_.mutex}; + bool repeat = urlData_.loadResult.waitForExceptionalPageClosureAfterBootUrl && urlData_.loadResult.waitForFailedOrFinished; + urlData_.loadResult.waitForExceptionalPageClosureAfterBootUrl = false; + return repeat; + } + void NotifyClosure() { + if (RepeatLoadUrlWhenPageClosureAndLoadFailedWithReasonCancelledOnBootUrl()) { + // our setup of boot url was interrupted by window.close in the middle of loading the boot url + // here we need to "fix the reality" by doing extra _bootUrl setup + SYSLOG(Logging::Notification, (_T("boot URL setup + window.close: NotifyClosure: Repeat load boot url started"))); + SetupURLInternal(_bootUrl, false); + SYSLOG(Logging::Notification, (_T("boot URL setup + window.close: NotifyClosure: Repeat load boot url finished"))); + return; + } _adminLock.Lock(); { @@ -3538,6 +3571,10 @@ static GSourceFuncs _handlerIntervention = SYSLOG_GLOBAL(Logging::Notification, (_T("LoadFailed: %s"), message.c_str())); if (g_error_matches(error, WEBKIT_NETWORK_ERROR, WEBKIT_NETWORK_ERROR_CANCELLED)) { browser->_ignoreLoadFinishedOnce = true; + if (browser->OnLoadFailedCheckWaitingForBootUrl(failingURI)) { + SYSLOG_GLOBAL(Logging::Notification, (_T("boot URL setup + window.close detected: will wait for page closure event"))); + return; + } } browser->OnLoadFailed(failingURI); } @@ -3563,6 +3600,7 @@ static GSourceFuncs _handlerIntervention = } static void closeCallback(VARIABLE_IS_NOT_USED WebKitWebView* webView, WebKitImplementation* browser) { + SYSLOG_GLOBAL(Logging::Notification, (_T("closeCallback"))); browser->NotifyClosure(); } static gboolean decidePermissionCallback(VARIABLE_IS_NOT_USED WebKitWebView* webView, WebKitPermissionRequest* permissionRequest) @@ -4378,6 +4416,7 @@ static GSourceFuncs _handlerIntervention = uint32_t result = Core::ERROR_TIMEDOUT; struct { bool waitForFailedOrFinished = false; + bool waitForExceptionalPageClosureAfterBootUrl = false; string loadUrl; } loadResult; } urlData_;