-
Notifications
You must be signed in to change notification settings - Fork 6k
Avoid to freeze the system if hot reloading during debug #3833
Conversation
|
I don't think this will be safe. platform_views_ was only accessed on the UI thread due to the thread safety rules of ftl::WeakPtr In particular, the code in Shell::WaitForPlatformViewIds that checks whether the PlatformView is still alive and then calls into the view's engine must only run on the UI thread. |
|
The They are created and accessed in the same thread, but they are potentially invalidated in other threads.
What is synchronized on destruction is the |
|
May moving from |
|
std::weak_ptr and std::shared_ptr have nicer thread safety properties than ftl::WeakPtr and might be worth trying. You'll need to update all the supported platforms to hold the PlatformView in a shared_ptr instead of a raw pointer or unique_ptr. Also, if the end goal is to get information out of the Engine/RuntimeHolder on a thread other than the UI thread, then you'll need a safe way to do that. Engine is generally not safe to access outside the UI thread. |
|
I will update all the other platforms ASAP. For the thread safety of the Engine access I think that it is safe:
|
jason-simmons
left a comment
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.
LGTM
shell/common/shell.h
Outdated
| std::vector<ftl::WeakPtr<PlatformView>> platform_views_; | ||
| std::vector<std::weak_ptr<PlatformView>> platform_views_; | ||
|
|
||
| std::recursive_mutex mutex_; |
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.
rename this platform_views_mutex_ to indicate what it guards
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.
Ah, now i see that it's also being used to guard the rasterizers list. I'd suggest using two separate locks for platform_views and rasterizers.
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.
Also. does this need to be a recursive_mutex, or can it be a plain std::mutex?
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.
It is needed otherwise the lock inside WaitForPlatformViewIds will acquire it and the nested invocation of GetPlatformViews will freeze.
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.
WaitForPlatformViewIds can access platform_views_ directly while holding the mutex instead of calling GetPlatformViews. This will also avoid the list copy done by GetPlatformViews.
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
|
|
||
| #define PLATFORM_VIEW reinterpret_cast<PlatformViewAndroid*>(platform_view) | ||
| template <typename T> | ||
| class HeapSharedPtr { |
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.
what is the purpose of this wrapper?
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.
Trough the JNI we can move just Java Objects or Atomic values.
The std::shared_ptr cannot be passed directly, but the std::make_shared method will create it on the stack.
We wrap it into an object in the heap that will be manually managed.
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.
Can the make_shared() call and the wrapper be replaced by new std::shared_ptr(new PlatformViewAndroid())?
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
| void PlatformViewAndroid::Detach() { | ||
| ReleaseSurface(); | ||
| delete this; | ||
| //delete this; |
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.
remove this line before submitting
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
| } | ||
|
|
||
| void Shell::GetRasterizers(std::vector<ftl::WeakPtr<Rasterizer>>* rasterizers) { | ||
| FTL_DCHECK(gpu_thread_checker_ && |
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.
The check for the GPU thread was replaced by a mutex, but the pointers are still ftl::WeakPtrs that are bound to the GPU thread.
Is there a need to access the rasterizers list outside the GPU thread? If not, then I'd prefer to revert to using the GPU thread checker
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.
You are right, it is an error, I will restore those thread based checks
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
|
We found a Contributor License Agreement for you (the sender of this pull request), but were unable to find agreements for the commit author(s). If you authored these, maybe you used a different email address in the git commits than was used to sign the CLA (login here to double check)? If these were authored by someone else, then they will need to sign a CLA as well, and confirm that they're okay with these being contributed to Google. |
1 similar comment
|
We found a Contributor License Agreement for you (the sender of this pull request), but were unable to find agreements for the commit author(s). If you authored these, maybe you used a different email address in the git commits than was used to sign the CLA (login here to double check)? If these were authored by someone else, then they will need to sign a CLA as well, and confirm that they're okay with these being contributed to Google. |
|
CLAs look good, thanks! |
1 similar comment
|
CLAs look good, thanks! |
|
I've squashed all the commits to one |
|
This broke my build... |
Looks like the test_runner host build broke. |
In #3833 the `_flutter.listViews` RPC moved from thread based to lock based synchronization. The thread based synchronization side effect was used by flutter benchmarks in https://github.com/flutter/flutter/blob/master/packages/flutter_tools/lib/src/vmservice.dart#L1223 and https://github.com/flutter/flutter/blob/master/packages/flutter_tools/lib/src/run_hot.dart#L156 to ensure the completeness of the restart/reload and so correct timing. A new RPC `_flutter.flushUIThreadTasks` is introduced to allow the flutter benchmarks to reintroduce thread based synchronization. Related flutter/flutter#11241
Trying to hot reload during debug freezes the system, due to the fact that
WaitForPlatformViewIdstries to execute code on the main thread while it is locked, this in turn freezes the Service Isolate making impossible to continue debug or try to solve the situation.