Add a working WeakRealmNotifier for Node

Uses libuv APIs to async schedule onto the default Node run loop.
This commit is contained in:
Scott Kyle 2016-05-17 01:17:21 -07:00
parent 3b6ee92224
commit 938c7fb2f4
3 changed files with 124 additions and 1 deletions

View File

@ -0,0 +1,74 @@
////////////////////////////////////////////////////////////////////////////
//
// 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 "impl/weak_realm_notifier.hpp"
#include "shared_realm.hpp"
using namespace realm;
using namespace realm::_impl;
WeakRealmNotifier::WeakRealmNotifier(const std::shared_ptr<Realm>& realm, bool cache)
: WeakRealmNotifierBase(realm, cache)
, m_handle(new uv_async_t)
{
m_handle->data = new std::weak_ptr<Realm>(realm);
// This assumes that only one thread matters: the main thread (default loop).
uv_async_init(uv_default_loop(), m_handle, [](uv_async_t* handle) {
auto realm_weak_ptr = static_cast<std::weak_ptr<Realm>*>(handle->data);
auto realm = realm_weak_ptr->lock();
if (realm) {
realm->notify();
}
});
}
WeakRealmNotifier::WeakRealmNotifier(WeakRealmNotifier&& rgt)
: WeakRealmNotifierBase(std::move(rgt))
{
rgt.m_handle = nullptr;
}
WeakRealmNotifier& WeakRealmNotifier::operator=(WeakRealmNotifier&& rgt)
{
WeakRealmNotifierBase::operator=(std::move(rgt));
m_handle = rgt.m_handle;
rgt.m_handle = nullptr;
return *this;
}
WeakRealmNotifier::~WeakRealmNotifier()
{
if (m_handle) {
uv_close((uv_handle_t*)m_handle, [](uv_handle_t* handle) {
auto realm_weak_ptr = static_cast<std::weak_ptr<Realm>*>(handle->data);
delete realm_weak_ptr;
delete handle;
});
}
}
void WeakRealmNotifier::notify()
{
if (m_handle) {
uv_async_send(m_handle);
}
}

View File

@ -0,0 +1,47 @@
////////////////////////////////////////////////////////////////////////////
//
// 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 <uv.h>
#include "impl/weak_realm_notifier_base.hpp"
namespace realm {
class Realm;
namespace _impl {
class WeakRealmNotifier : public WeakRealmNotifierBase {
public:
WeakRealmNotifier(const std::shared_ptr<Realm>& realm, bool cache);
~WeakRealmNotifier();
WeakRealmNotifier(WeakRealmNotifier&&);
WeakRealmNotifier& operator=(WeakRealmNotifier&&);
WeakRealmNotifier(const WeakRealmNotifier&) = delete;
WeakRealmNotifier& operator=(const WeakRealmNotifier&) = delete;
// Asynchronously call notify() on the Realm on the main thread.
void notify();
private:
uv_async_t* m_handle;
};
} // namespace _impl
} // namespace realm

View File

@ -21,7 +21,9 @@
#include <realm/util/features.h>
#if REALM_PLATFORM_APPLE
#if REALM_PLATFORM_NODE
#include "impl/node/weak_realm_notifier.hpp"
#elif REALM_PLATFORM_APPLE
#include "impl/apple/weak_realm_notifier.hpp"
#else
#include "impl/generic/weak_realm_notifier.hpp"