Fabric: MessageQueueEventBeat
Summary: @public MessageQueueEventBeat implements particular Event Beat synchronized with Message Queue and calling a callback on the JS thread (aka Message Queue thread). The actual beat is synchronized with the main run loop. Reviewed By: mdvacca Differential Revision: D8886230 fbshipit-source-id: 97ef7d10f705789b4b0cd3a12389db960159f289
This commit is contained in:
parent
57bbce9bd9
commit
26d0b05c80
|
@ -0,0 +1,35 @@
|
|||
/**
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#include <CoreFoundation/CoreFoundation.h>
|
||||
#include <CoreFoundation/CFRunLoop.h>
|
||||
#include <cxxreact/MessageQueueThread.h>
|
||||
#include <fabric/events/EventBeat.h>
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
/*
|
||||
* Event beat that associated with MessageQueueThread.
|
||||
*/
|
||||
class MessageQueueEventBeat:
|
||||
public EventBeat {
|
||||
|
||||
public:
|
||||
MessageQueueEventBeat(const std::shared_ptr<MessageQueueThread> &messageQueueThread);
|
||||
~MessageQueueEventBeat();
|
||||
|
||||
void induce() const override;
|
||||
|
||||
private:
|
||||
const std::shared_ptr<MessageQueueThread> messageQueueThread_;
|
||||
CFRunLoopObserverRef mainRunLoopObserver_;
|
||||
mutable std::atomic<bool> isBusy_ {false};
|
||||
};
|
||||
|
||||
} // namespace react
|
||||
} // namespace facebook
|
|
@ -0,0 +1,52 @@
|
|||
/**
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#include "MessageQueueEventBeat.h"
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
MessageQueueEventBeat::MessageQueueEventBeat(const std::shared_ptr<MessageQueueThread> &messageQueueThread):
|
||||
messageQueueThread_(messageQueueThread) {
|
||||
|
||||
mainRunLoopObserver_ =
|
||||
CFRunLoopObserverCreateWithHandler(
|
||||
NULL /* allocator */,
|
||||
kCFRunLoopBeforeWaiting /* activities */,
|
||||
true /* repeats */,
|
||||
0 /* order */,
|
||||
^(CFRunLoopObserverRef observer, CFRunLoopActivity activity) {
|
||||
// Note: We only `induce` beat here; actual beat will be performed on
|
||||
// a different thread.
|
||||
this->induce();
|
||||
}
|
||||
);
|
||||
|
||||
assert(mainRunLoopObserver_);
|
||||
|
||||
CFRunLoopAddObserver(CFRunLoopGetMain(), mainRunLoopObserver_, kCFRunLoopCommonModes);
|
||||
}
|
||||
|
||||
MessageQueueEventBeat::~MessageQueueEventBeat() {
|
||||
CFRunLoopRemoveObserver(CFRunLoopGetMain(), mainRunLoopObserver_, kCFRunLoopCommonModes);
|
||||
CFRelease(mainRunLoopObserver_);
|
||||
}
|
||||
|
||||
void MessageQueueEventBeat::induce() const {
|
||||
if (!isRequested_ || isBusy_) {
|
||||
return;
|
||||
}
|
||||
|
||||
isBusy_ = true;
|
||||
messageQueueThread_->runOnQueue([this]() {
|
||||
this->beat();
|
||||
isBusy_ = false;
|
||||
});
|
||||
}
|
||||
|
||||
} // namespace react
|
||||
} // namespace facebook
|
Loading…
Reference in New Issue