//////////////////////////////////////////////////////////////////////////// // // Copyright 2015 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. // //////////////////////////////////////////////////////////////////////////// #ifndef REALM_WEAK_REALM_NOTIFIER_HPP #define REALM_WEAK_REALM_NOTIFIER_HPP #include <memory> #include <thread> namespace realm { class Realm; namespace util { class Scheduler; } namespace _impl { // WeakRealmNotifier stores a weak reference to a Realm instance, along with all of // the information about a Realm that needs to be accessed from other threads. // This is needed to avoid forming strong references to the Realm instances on // other threads, which can produce deadlocks when the last strong reference to // a Realm instance is released from within a function holding the cache lock. class WeakRealmNotifier { public: WeakRealmNotifier(const std::shared_ptr<Realm>& realm, bool cache); ~WeakRealmNotifier(); // Get a strong reference to the cached realm std::shared_ptr<Realm> realm() const { return m_realm.lock(); } // Has the Realm instance been destroyed? bool expired() const { return m_realm.expired(); } // Is this a WeakRealmNotifier for the given Realm instance? bool is_for_realm(Realm* realm) const { return realm == m_realm_key; } bool is_cached_for_scheduler(std::shared_ptr<util::Scheduler> scheduler) const; bool scheduler_is_on_thread() const; // Invoke m_realm.notify() on the Realm's thread via the scheduler. void notify(); // Bind this notifier to the Realm's scheduler. void bind_to_scheduler(); private: std::weak_ptr<Realm> m_realm; void* m_realm_key; bool m_cache = false; std::shared_ptr<util::Scheduler> m_scheduler; }; } // namespace _impl } // namespace realm #endif // REALM_WEAK_REALM_NOTIFIER_HPP