Skip to content

Commit 43c55e9

Browse files
javachefacebook-github-bot
authored andcommitted
Allow moving SyncCallback (#43268)
Summary: Pull Request resolved: #43268 We previously restricted all copies and moves of SyncCallback, but that led to unsafe calling paths being added instead to AsyncCallback. Instead, allowing moving of SyncCallback, and document the need for the caller to invoke it safely, so can we remove the unsafe path from AsyncCallback. Changelog: [General][Changed] Allow moving SyncCallback for advanced use-cases Reviewed By: christophpurrer Differential Revision: D54381734 fbshipit-source-id: 5fd797cd4541e507aa68f1e4e76a1be5cae20fbe
1 parent 24e6722 commit 43c55e9

File tree

1 file changed

+16
-12
lines changed
  • packages/react-native/ReactCommon/react/bridging

1 file changed

+16
-12
lines changed

packages/react-native/ReactCommon/react/bridging/Function.h

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -54,15 +54,6 @@ class AsyncCallback {
5454
callWithFunction(priority, std::move(callImpl));
5555
}
5656

57-
/// Invoke the function write-away as if it was a synchronous function
58-
/// without any synchronization or delegating to JS context.
59-
/// @note Caller is responsible for calling this from within JS context.
60-
void unsafeCallSync(Args... args) const noexcept {
61-
if (callback_) {
62-
(*callback_)(std::forward<Args>(args)...);
63-
}
64-
}
65-
6657
private:
6758
friend Bridging<AsyncCallback>;
6859

@@ -110,6 +101,9 @@ class AsyncCallback {
110101
}
111102
};
112103

104+
// You must ensure that when invoking this you're located on the JS thread, or
105+
// have exclusive control of the JS VM context. If you cannot ensure this, use
106+
// AsyncCallback instead.
113107
template <typename R, typename... Args>
114108
class SyncCallback<R(Args...)> {
115109
public:
@@ -122,9 +116,19 @@ class SyncCallback<R(Args...)> {
122116
rt,
123117
std::move(jsInvoker))) {}
124118

125-
// Disallow moving to prevent function from get called on another thread.
126-
SyncCallback(SyncCallback&&) = delete;
127-
SyncCallback& operator=(SyncCallback&&) = delete;
119+
// Disallow copying, as we can no longer safely destroy the callback
120+
// from the destructor if there's multiple copies
121+
SyncCallback(const SyncCallback&) = delete;
122+
SyncCallback& operator=(const SyncCallback&) = delete;
123+
124+
// Allow move
125+
SyncCallback(SyncCallback&& other) noexcept
126+
: wrapper_(std::move(other.wrapper_)) {}
127+
128+
SyncCallback& operator=(SyncCallback&& other) noexcept {
129+
wrapper_ = std::move(other.wrapper_);
130+
return *this;
131+
}
128132

129133
~SyncCallback() {
130134
if (auto wrapper = wrapper_.lock()) {

0 commit comments

Comments
 (0)