From ef77d1d5e4c12b9a657da10cb4decb0b7d96349c Mon Sep 17 00:00:00 2001 From: Youngsoo Choi Date: Mon, 16 Jan 2017 12:51:12 +0900 Subject: [PATCH] Do not create extended main loop for termination by |Terminate| There are two types of termination sequences. The first one is terminated by |Terminate| and another one is terminated by |OnTerminate| triggered by application framework. In case of termination by |OnTerminate|, app f/w emits elm_shutdown that quits main loop so extended main loop is needed to finish termination sequence. Btw, in case of termination by |Terminate|, app f/w does not interrupt current main loop so it is stll alive and extended main loop is not needed. This CL introduces not to create extended main loop for the termination by |Terminate|. Bug: http://suprem.sec.samsung.net/jira/browse/TWF-2804 Change-Id: I15147c9d07ec768bdb7f8acf92e18886ec2c100d Signed-off-by: Youngsoo Choi --- runtime/browser/runtime.cc | 19 +------- runtime/browser/runtime.h | 8 ---- runtime/browser/web_application.cc | 96 ++++++++++++++++++++------------------ runtime/browser/web_application.h | 9 ++++ 4 files changed, 62 insertions(+), 70 deletions(-) diff --git a/runtime/browser/runtime.cc b/runtime/browser/runtime.cc index 5861b08..2254bfc 100644 --- a/runtime/browser/runtime.cc +++ b/runtime/browser/runtime.cc @@ -58,25 +58,10 @@ std::unique_ptr Runtime::MakeRuntime( } } -// static -Eina_Bool Runtime::ClosePageInExtendedMainLoop(void* user_data) -{ - LOGGER(DEBUG); - struct Timer* main_loop = static_cast(user_data); - main_loop->application->ClosePage(); - return ECORE_CALLBACK_CANCEL; -} - void Runtime::ProcessClosingPage(WebApplication* application) { LOGGER(DEBUG); - if (application) { - struct Timer main_loop; - main_loop.application = application; - main_loop.timer = ecore_timer_add(MAIN_LOOP_INTERVAL, ClosePageInExtendedMainLoop, &main_loop); - LOGGER(DEBUG) << "Defer termination of main loop"; - ecore_main_loop_begin(); - ecore_timer_del(main_loop.timer); - } + if (application) + application->ProcessClosingPage(); } } // namespace runtime diff --git a/runtime/browser/runtime.h b/runtime/browser/runtime.h index 63ddc97..a003dac 100755 --- a/runtime/browser/runtime.h +++ b/runtime/browser/runtime.h @@ -38,14 +38,6 @@ class Runtime { protected: void ProcessClosingPage(WebApplication* application); - - private: - static Eina_Bool ClosePageInExtendedMainLoop(void* user_data); - struct Timer - { - WebApplication* application; - Ecore_Timer* timer; - }; }; } // namespace runtime diff --git a/runtime/browser/web_application.cc b/runtime/browser/web_application.cc index e11d9e0..97d9bb3 100755 --- a/runtime/browser/web_application.cc +++ b/runtime/browser/web_application.cc @@ -52,7 +52,8 @@ #error INJECTED_BUNDLE_PATH is not set. #endif -#define TIMER_INTERVAL 0.1 +#define SESSION_COUNTER_INTERVAL 0.1 +#define MAIN_LOOP_INTERVAL 1 using namespace extensions; @@ -647,20 +648,35 @@ void WebApplication::Suspend() { void WebApplication::Terminate() { is_terminate_called_ = true; - if (terminator_) { - LOGGER(DEBUG) << "terminator_"; - terminator_(); - } else { - LOGGER(ERROR) << "There's no registered terminator."; - elm_exit(); - } - auto extension_server = extensions::XWalkExtensionServer::GetInstance(); - LOGGER(DEBUG) << "Shutdown extension server"; - extension_server->Shutdown(); + ClosePage(); +} + +// static +Eina_Bool WebApplication::ClosePageInExtendedMainLoop(void* user_data) +{ + LOGGER(DEBUG); + struct Timer* main_loop = static_cast(user_data); + main_loop->application->ClosePage(); + return ECORE_CALLBACK_CANCEL; +} + +void WebApplication::ProcessClosingPage() { + LOGGER(DEBUG); + + main_loop.application = this; + main_loop.timer = ecore_timer_add(MAIN_LOOP_INTERVAL, + ClosePageInExtendedMainLoop, &main_loop); + if (!main_loop.timer) + LOGGER(ERROR) << "It's failed to create main_loop timer"; + LOGGER(DEBUG) << "Defer termination of main loop"; + ecore_main_loop_begin(); + ecore_timer_del(main_loop.timer); + ecore_timer_del(session_counter.timer); } void WebApplication::ClosePage() { LOGGER(DEBUG); + int valid_evas_object_count = 0; auto it = view_stack_.begin(); if (it != view_stack_.end()) { @@ -675,18 +691,20 @@ void WebApplication::ClosePage() { } } } - if (valid_evas_object_count == 0) { - if (is_terminate_called_) { - ecore_main_loop_quit(); - } else { - if (terminator_) { - LOGGER(DEBUG) << "terminator_"; - terminator_(); - } else { - LOGGER(ERROR) << "There's no registered terminator."; - elm_exit(); - } - } + if (valid_evas_object_count == 0) + Exit(); +} + +void WebApplication::Exit() { + if (!is_terminate_called_) + ecore_main_loop_quit(); + + if (terminator_) { + LOGGER(DEBUG) << "terminator_"; + terminator_(); + } else { + LOGGER(ERROR) << "There's no registered terminator."; + elm_exit(); } } @@ -723,13 +741,9 @@ void WebApplication::RemoveWebViewFromStack(WebView* view) { } if (view_stack_.size() == 0) { - // If |Terminate()| hasn't been called, - // main loop shouldn't be terminated here. - if (!is_terminate_called_) { - auto extension_server = XWalkExtensionServer::GetInstance(); - LOGGER(DEBUG) << "Shutdown extension server"; - extension_server->Shutdown(); - } + auto extension_server = XWalkExtensionServer::GetInstance(); + LOGGER(DEBUG) << "Shutdown extension server"; + extension_server->Shutdown(); } else if (current != view_stack_.front()) { view_stack_.front()->SetVisibility(true); window_->SetContent(view_stack_.front()->evas_object()); @@ -746,7 +760,7 @@ void WebApplication::RemoveWebViewFromStack(WebView* view) { Eina_Bool WebApplication::CheckPluginSession(void* user_data) { - WebApplication* that = static_cast(user_data); + struct Timer* session_counter = static_cast(user_data); if(XWalkExtensionRendererController::plugin_session_count > 0) { LOGGER(ERROR) << "plugin_session_count : " << XWalkExtensionRendererController::plugin_session_count; @@ -755,30 +769,22 @@ Eina_Bool WebApplication::CheckPluginSession(void* user_data) LOGGER(DEBUG) << "plugin_session_count : " << XWalkExtensionRendererController::plugin_session_count; LOGGER(DEBUG) << "Execute deferred termination of main loop"; - if (that->is_terminate_called_) { - ecore_main_loop_quit(); - } else { - if (that->terminator_) { - LOGGER(DEBUG) << "terminator_"; - that->terminator_(); - } else { - LOGGER(ERROR) << "There's no registered terminator."; - elm_exit(); - } - } + session_counter->application->Exit(); return ECORE_CALLBACK_CANCEL; } void WebApplication::OnClosedWebView(WebView* view) { - Ecore_Timer* timeout_id = NULL; // Reply to javascript dialog for preventing freeze issue. view->ReplyToJavascriptDialog(); RemoveWebViewFromStack(view); LOGGER(DEBUG) << "plugin_session_count : " << XWalkExtensionRendererController::plugin_session_count; - if (!ecore_timer_add(TIMER_INTERVAL, CheckPluginSession, this)) - LOGGER(ERROR) << "It's failed to create timer"; + session_counter.application = this; + session_counter.timer = ecore_timer_add(SESSION_COUNTER_INTERVAL, + CheckPluginSession, &session_counter); + if (!session_counter.timer) + LOGGER(ERROR) << "It's failed to create session_counter timer"; } void WebApplication::OnReceivedWrtMessage(WebView* view, diff --git a/runtime/browser/web_application.h b/runtime/browser/web_application.h index 3fdbdfe..446fb49 100755 --- a/runtime/browser/web_application.h +++ b/runtime/browser/web_application.h @@ -53,6 +53,9 @@ class WebApplication : public WebView::EventListener { void Terminate(); void ClosePage(); + void Exit(); + void ProcessClosingPage(); + std::string data_path() const { return app_data_path_; } void set_terminator(std::function terminator) { terminator_ = terminator; @@ -107,6 +110,12 @@ class WebApplication : public WebView::EventListener { virtual void OnRotatePrepared(WebView* view); #endif // MANUAL_ROTATE_FEATURE_SUPPORT static Eina_Bool CheckPluginSession(void* user_data); + static Eina_Bool ClosePageInExtendedMainLoop(void* user_data); + struct Timer + { + WebApplication* application; + Ecore_Timer* timer; + } main_loop, session_counter; private: bool Initialize(); -- 2.7.4