Extract the non-Apple specific parts of CachedRealm to a base class

This commit is contained in:
Thomas Goyne 2015-12-03 14:16:48 -08:00 committed by Thomas Goyne
parent 178c562f2c
commit 112c778d8e
4 changed files with 79 additions and 32 deletions

View File

@ -21,6 +21,7 @@ set(HEADERS
results.hpp
schema.hpp
shared_realm.hpp
impl/cached_realm_base.hpp
impl/transact_log_handler.hpp
parser/parser.hpp
parser/query_builder.hpp)

View File

@ -24,9 +24,7 @@ using namespace realm;
using namespace realm::_impl;
CachedRealm::CachedRealm(const std::shared_ptr<Realm>& realm, bool cache)
: m_realm(realm)
, m_realm_key(realm.get())
, m_cache(cache)
: CachedRealmBase(realm, cache)
{
struct RefCountedWeakPointer {
std::weak_ptr<Realm> realm;
@ -58,15 +56,17 @@ CachedRealm::CachedRealm(const std::shared_ptr<Realm>& realm, bool cache)
}
CachedRealm::CachedRealm(CachedRealm&& rgt)
: CachedRealmBase(std::move(rgt))
, m_runloop(rgt.m_runloop)
, m_signal(rgt.m_signal)
{
*this = std::move(rgt);
rgt.m_runloop = nullptr;
rgt.m_signal = nullptr;
}
CachedRealm& CachedRealm::operator=(CachedRealm&& rgt)
{
m_realm = std::move(rgt.m_realm);
m_thread_id = rgt.m_thread_id;
m_cache = rgt.m_cache;
CachedRealmBase::operator=(std::move(rgt));
m_runloop = rgt.m_runloop;
m_signal = rgt.m_signal;
rgt.m_runloop = nullptr;

View File

@ -19,21 +19,16 @@
#ifndef REALM_CACHED_REALM_HPP
#define REALM_CACHED_REALM_HPP
#include "../cached_realm_base.hpp"
#include <CoreFoundation/CFRunLoop.h>
#include <memory>
#include <thread>
namespace realm {
class Realm;
namespace _impl {
// CachedRealm 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 CachedRealm {
class CachedRealm : public CachedRealmBase {
public:
CachedRealm(const std::shared_ptr<Realm>& realm, bool cache);
~CachedRealm();
@ -44,27 +39,10 @@ public:
CachedRealm(const CachedRealm&) = delete;
CachedRealm& operator=(const CachedRealm&) = delete;
// Get a strong reference to the cached realm
std::shared_ptr<Realm> realm() const { return m_realm.lock(); }
// Does this CachedRealm store a Realm instance that should be used on the current thread?
bool is_cached_for_current_thread() const { return m_cache && m_thread_id == std::this_thread::get_id(); }
// Has the Realm instance been destroyed?
bool expired() const { return m_realm.expired(); }
// Asyncronously call notify() on the Realm on the appropriate thread
void notify();
// Is this a CachedRealm for the given Realm instance?
bool is_for_realm(Realm* realm) const { return realm == m_realm_key; }
private:
std::weak_ptr<Realm> m_realm;
std::thread::id m_thread_id = std::this_thread::get_id();
void* m_realm_key;
bool m_cache = false;
CFRunLoopRef m_runloop;
CFRunLoopSourceRef m_signal;
};

View File

@ -0,0 +1,68 @@
////////////////////////////////////////////////////////////////////////////
//
// 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_CACHED_REALM_BASE_HPP
#define REALM_CACHED_REALM_BASE_HPP
#include <memory>
#include <thread>
namespace realm {
class Realm;
namespace _impl {
// CachedRealm 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 CachedRealmBase {
public:
CachedRealmBase(const std::shared_ptr<Realm>& realm, bool cache);
// Get a strong reference to the cached realm
std::shared_ptr<Realm> realm() const { return m_realm.lock(); }
// Does this CachedRealmBase store a Realm instance that should be used on the current thread?
bool is_cached_for_current_thread() const { return m_cache && m_thread_id == std::this_thread::get_id(); }
// Has the Realm instance been destroyed?
bool expired() const { return m_realm.expired(); }
// Is this a CachedRealmBase for the given Realm instance?
bool is_for_realm(Realm* realm) const { return realm == m_realm_key; }
private:
std::weak_ptr<Realm> m_realm;
std::thread::id m_thread_id = std::this_thread::get_id();
void* m_realm_key;
bool m_cache = false;
};
inline CachedRealmBase::CachedRealmBase(const std::shared_ptr<Realm>& realm, bool cache)
: m_realm(realm)
, m_realm_key(realm.get())
, m_cache(cache)
{
}
} // namespace _impl
} // namespace realm
#endif // REALM_CACHED_REALM_BASE_HPP