-
Notifications
You must be signed in to change notification settings - Fork 6k
Remove get engine #9747
Remove get engine #9747
Changes from 9 commits
593c9b3
d3b1538
d6e773d
650a309
907adc3
d208da1
15d8eb6
df66441
f543223
97194c1
e510c32
9036750
d8d508c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -3,7 +3,6 @@ | |
| // found in the LICENSE file. | ||
|
|
||
| #define RAPIDJSON_HAS_STDSTRING 1 | ||
|
|
||
| #include "flutter/shell/common/shell.h" | ||
|
|
||
| #include <memory> | ||
|
|
@@ -372,6 +371,71 @@ void Shell::NotifyLowMemoryWarning() const { | |
| // to purge them. | ||
| } | ||
|
|
||
| void Shell::RunEngine(RunConfiguration run_configuration) { | ||
| RunEngine(std::move(run_configuration), nullptr); | ||
| } | ||
|
|
||
| void Shell::RunEngine(RunConfiguration run_configuration, | ||
| std::function<void(Engine::RunStatus)> result_callback) { | ||
| FML_DCHECK(is_setup_); | ||
| FML_DCHECK(task_runners_.GetPlatformTaskRunner()->RunsTasksOnCurrentThread()); | ||
|
|
||
| if (!weak_engine_) { | ||
| result_callback(Engine::RunStatus::Failure); | ||
| } | ||
| fml::TaskRunner::RunNowOrPostTask( | ||
| task_runners_.GetUITaskRunner(), | ||
| fml::MakeCopyable([run_configuration = std::move(run_configuration), | ||
| weak_engine = weak_engine_, | ||
| result_callback = | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done |
||
| std::move(result_callback)]() mutable { | ||
| if (!weak_engine) { | ||
| if (result_callback) { | ||
| FML_LOG(ERROR) | ||
| << "Could not launch engine with configuration - no engine."; | ||
| result_callback(Engine::RunStatus::Failure); | ||
| } | ||
| return; | ||
| } | ||
| auto result = weak_engine->Run(std::move(run_configuration)); | ||
| if (result == flutter::Engine::RunStatus::Failure) { | ||
| FML_LOG(ERROR) << "Could not launch engine with configuration."; | ||
| } | ||
| if (result_callback) { | ||
| result_callback(result); | ||
| } | ||
| })); | ||
| } | ||
|
|
||
| std::optional<int> Shell::GetUIIsolateLastError() const { | ||
| FML_DCHECK(is_setup_); | ||
| FML_DCHECK(task_runners_.GetPlatformTaskRunner()->RunsTasksOnCurrentThread()); | ||
|
|
||
| if (!weak_engine_) { | ||
| return std::nullopt; | ||
| } | ||
| switch (weak_engine_->GetUIIsolateLastError()) { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Using a weak pointer on the non-originating thread is not thread safe. See the comment in Now in this particular case, the engine provides a guarantee that shell subcomponents will be destroyed before its destructor finishes execution on the platform task runner. So, it happens to work out. But I would still be more comfortable if code didn't break safe threading rules because of the lifecycle assumptions. It is not immediately clear from reading just this bit of code about why this is safe even though it breaks rules of safe weak pointer use. You can use the same pattern used right above in the
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Going with the unique_ptr and a comment, as discussed offline |
||
| case tonic::kCompilationErrorType: | ||
| return kCompilationErrorExitCode; | ||
| case tonic::kApiErrorType: | ||
| return kApiErrorExitCode; | ||
| case tonic::kUnknownErrorType: | ||
| return kErrorExitCode; | ||
| default: | ||
| return 0; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I was under the impression the engine method returned 0 if ther ewas no error. Is that not the case? The tester_main was defaulting this case to 0 as well AFAICT
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It seems to be |
||
| } | ||
| } | ||
|
|
||
| bool Shell::EngineHasLivePorts() const { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ditto on the comment in |
||
| FML_DCHECK(is_setup_); | ||
| FML_DCHECK(task_runners_.GetPlatformTaskRunner()->RunsTasksOnCurrentThread()); | ||
|
|
||
| if (!weak_engine_) { | ||
| return false; | ||
| } | ||
| return weak_engine_->UIIsolateHasLivePorts(); | ||
| } | ||
|
|
||
| bool Shell::IsSetup() const { | ||
| return is_setup_; | ||
| } | ||
|
|
@@ -425,10 +489,14 @@ fml::WeakPtr<Rasterizer> Shell::GetRasterizer() { | |
| return weak_rasterizer_; | ||
| } | ||
|
|
||
| // TODO(dnfield): Remove this when either Topaz is up to date or flutter_runner | ||
| // is built out of this repo. | ||
| #ifdef OS_FUCHSIA | ||
| fml::WeakPtr<Engine> Shell::GetEngine() { | ||
| FML_DCHECK(is_setup_); | ||
| return weak_engine_; | ||
| } | ||
| #endif // OS_FUCHSIA | ||
|
|
||
| fml::WeakPtr<PlatformView> Shell::GetPlatformView() { | ||
| FML_DCHECK(is_setup_); | ||
|
|
@@ -907,7 +975,7 @@ void Shell::ReportTimings() { | |
|
|
||
| auto timings = std::move(unreported_timings_); | ||
| unreported_timings_ = {}; | ||
| task_runners_.GetUITaskRunner()->PostTask([timings, engine = GetEngine()] { | ||
| task_runners_.GetUITaskRunner()->PostTask([timings, engine = weak_engine_] { | ||
| if (engine) { | ||
| engine->ReportTimings(std::move(timings)); | ||
| } | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -78,6 +78,13 @@ class Shell final : public PlatformView::Delegate, | |
| public Rasterizer::Delegate, | ||
| public ServiceProtocol::Handler { | ||
| public: | ||
| /// The Dart error code for an API error. | ||
| const int kApiErrorExitCode = 253; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we make these enums instead now? |
||
| /// The Dart error code for a compilation error. | ||
| const int kCompilationErrorExitCode = 254; | ||
| /// The Dart error code for an unkonwn error. | ||
| const int kErrorExitCode = 255; | ||
|
|
||
| template <class T> | ||
| using CreateCallback = std::function<std::unique_ptr<T>(Shell&)>; | ||
|
|
||
|
|
@@ -165,6 +172,19 @@ class Shell final : public PlatformView::Delegate, | |
| /// | ||
| ~Shell(); | ||
|
|
||
| //---------------------------------------------------------------------------- | ||
| /// @brief Starts an isolate for the given RunConfiguration. | ||
| /// | ||
| void RunEngine(RunConfiguration run_configuration); | ||
|
|
||
| //---------------------------------------------------------------------------- | ||
| /// @brief Starts an isolate for the given RunConfiguration. The | ||
| /// result_callback will be called with the status of the | ||
| /// operation. | ||
| /// | ||
| void RunEngine(RunConfiguration run_configuration, | ||
| std::function<void(Engine::RunStatus)> result_callback); | ||
|
|
||
| //------------------------------------------------------------------------------ | ||
| /// @return The settings used to launch this shell. | ||
| /// | ||
|
|
@@ -191,12 +211,18 @@ class Shell final : public PlatformView::Delegate, | |
| /// | ||
| fml::WeakPtr<Rasterizer> GetRasterizer(); | ||
|
|
||
| // TODO(dnfield): Remove this when either Topaz is up to date or flutter_runner | ||
| // is built out of this repo. | ||
| #ifdef OS_FUCHSIA | ||
| //------------------------------------------------------------------------------ | ||
| /// @brief Engines may only be accessed on the UI thread. | ||
| /// @brief Engines may only be accessed on the UI thread. This method is | ||
| /// deprecated, and implementers should instead use other API | ||
| /// available on the Shell or the PlatformView. | ||
| /// | ||
| /// @return A weak pointer to the engine. | ||
| /// | ||
| fml::WeakPtr<Engine> GetEngine(); | ||
| #endif // OS_FUCHSIA | ||
|
|
||
| //---------------------------------------------------------------------------- | ||
| /// @brief Platform views may only be accessed on the platform task | ||
|
|
@@ -253,6 +279,25 @@ class Shell final : public PlatformView::Delegate, | |
| /// | ||
| fml::Status WaitForFirstFrame(fml::TimeDelta timeout); | ||
|
|
||
| //---------------------------------------------------------------------------- | ||
| /// @brief Used by embedders to get the last error from the Dart UI | ||
| /// Isolate, if one exists. | ||
| /// | ||
| /// @return Returns the last error code from the UI Isolate. | ||
| /// | ||
| std::optional<int> GetUIIsolateLastError() const; | ||
|
|
||
| //---------------------------------------------------------------------------- | ||
| /// @brief Used by embedders to check if the Engine is running and has | ||
| /// any live ports remaining. For example, the Flutter tester uses | ||
| /// this method to check whether it should continue to wait for | ||
| /// a running test or not. | ||
| /// | ||
| /// @return Returns if the shell has an engine and the engine has any live | ||
| /// Dart ports. | ||
| /// | ||
| bool EngineHasLivePorts() const; | ||
|
|
||
| private: | ||
| using ServiceProtocolHandler = | ||
| std::function<bool(const ServiceProtocol::Handler::ServiceProtocolMap&, | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it would be better to have the result callback be executed on the calling task runner (the platform task runner in this case). Since doing the re-threading at the each possible call-site is tedious, you can wrap the same in and closure that does the re-threading and then pass that around as normal. See the image decoder for a use of this pattern.
On a related note, since forgetting to invoke the closure in the error case is possible, maybe we should have an RAII wrapper for the same. I have a prototype for this in a different patch that is not in yet.
That way, you can wrap the callback in a closure that does the re-threading and put it in that RAII wrapper. You could then invoke the same only in the success case and ensure that all erroneous cases invoke the callback and on the right thread.
Something like the following should work for now:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done