X-Git-Url: https://git.mdrn.pl/wl-app.git/blobdiff_plain/53b27422d140022594fc241cca91c3183be57bca..48b2fe9f7c2dc3d9aeaaa6dbfb27c7da4f3235ff:/iOS/Pods/Realm/include/util/apple/event_loop_signal.hpp diff --git a/iOS/Pods/Realm/include/util/apple/event_loop_signal.hpp b/iOS/Pods/Realm/include/util/apple/event_loop_signal.hpp new file mode 100644 index 0000000..37a3d36 --- /dev/null +++ b/iOS/Pods/Realm/include/util/apple/event_loop_signal.hpp @@ -0,0 +1,82 @@ +//////////////////////////////////////////////////////////////////////////// +// +// Copyright 2016 Realm Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//////////////////////////////////////////////////////////////////////////// + +#include +#include + +namespace realm { +namespace util { +template +class EventLoopSignal { +public: + EventLoopSignal(Callback&& callback) + { + struct RefCountedRunloopCallback { + Callback callback; + std::atomic ref_count; + }; + + CFRunLoopSourceContext ctx{}; + ctx.info = new RefCountedRunloopCallback{std::move(callback), {0}}; + ctx.perform = [](void* info) { + static_cast(info)->callback(); + }; + ctx.retain = [](const void* info) { + static_cast(const_cast(info))->ref_count.fetch_add(1, std::memory_order_relaxed); + return info; + }; + ctx.release = [](const void* info) { + auto ptr = static_cast(const_cast(info)); + if (ptr->ref_count.fetch_add(-1, std::memory_order_acq_rel) == 1) { + delete ptr; + } + }; + + m_runloop = CFRunLoopGetCurrent(); + CFRetain(m_runloop); + m_signal = CFRunLoopSourceCreate(kCFAllocatorDefault, 0, &ctx); + CFRunLoopAddSource(m_runloop, m_signal, kCFRunLoopDefaultMode); + } + + ~EventLoopSignal() + { + CFRunLoopSourceInvalidate(m_signal); + CFRelease(m_signal); + CFRelease(m_runloop); + } + + EventLoopSignal(EventLoopSignal&&) = delete; + EventLoopSignal& operator=(EventLoopSignal&&) = delete; + EventLoopSignal(EventLoopSignal const&) = delete; + EventLoopSignal& operator=(EventLoopSignal const&) = delete; + + void notify() + { + CFRunLoopSourceSignal(m_signal); + // Signalling the source makes it run the next time the runloop gets + // to it, but doesn't make the runloop start if it's currently idle + // waiting for events + CFRunLoopWakeUp(m_runloop); + } + +private: + CFRunLoopRef m_runloop; + CFRunLoopSourceRef m_signal; +}; +} // namespace util +} // namespace realm