• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

realm / realm-core / github_pull_request_312964

19 Feb 2025 07:31PM UTC coverage: 90.814% (-0.3%) from 91.119%
github_pull_request_312964

Pull #8071

Evergreen

web-flow
Bump serialize-javascript and mocha

Bumps [serialize-javascript](https://github.com/yahoo/serialize-javascript) to 6.0.2 and updates ancestor dependency [mocha](https://github.com/mochajs/mocha). These dependencies need to be updated together.


Updates `serialize-javascript` from 6.0.0 to 6.0.2
- [Release notes](https://github.com/yahoo/serialize-javascript/releases)
- [Commits](https://github.com/yahoo/serialize-javascript/compare/v6.0.0...v6.0.2)

Updates `mocha` from 10.2.0 to 10.8.2
- [Release notes](https://github.com/mochajs/mocha/releases)
- [Changelog](https://github.com/mochajs/mocha/blob/main/CHANGELOG.md)
- [Commits](https://github.com/mochajs/mocha/compare/v10.2.0...v10.8.2)

---
updated-dependencies:
- dependency-name: serialize-javascript
  dependency-type: indirect
- dependency-name: mocha
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
Pull Request #8071: Bump serialize-javascript and mocha

96552 of 179126 branches covered (53.9%)

212672 of 234185 relevant lines covered (90.81%)

3115802.0 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

56.0
/test/object-store/util/event_loop.cpp
1
/*************************************************************************
2
 *
3
 * Copyright 2016 Realm Inc.
4
 *
5
 * Licensed under the Apache License, Version 2.0 (the "License");
6
 * you may not use this file except in compliance with the License.
7
 * You may obtain a copy of the License at
8
 *
9
 * http://www.apache.org/licenses/LICENSE-2.0
10
 *
11
 * Unless required by applicable law or agreed to in writing, software
12
 * distributed under the License is distributed on an "AS IS" BASIS,
13
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
 * See the License for the specific language governing permissions and
15
 * limitations under the License.
16
 *
17
 **************************************************************************/
18

19
#include "util/event_loop.hpp"
20

21
#include <realm/object-store/util/event_loop_dispatcher.hpp>
22
#include <realm/util/scope_exit.hpp>
23
#include <realm/util/features.h>
24

25
#include <mutex>
26
#include <stdexcept>
27
#include <vector>
28

29
#if TEST_SCHEDULER_UV
30
#include <uv.h>
31
#elif REALM_PLATFORM_APPLE
32
#include <realm/util/cf_ptr.hpp>
33
#include <CoreFoundation/CoreFoundation.h>
34
#elif REALM_ANDROID
35
// TODO: implement event loop for android: see Scheduler::make_alooper()
36
#elif defined(__EMSCRIPTEN__)
37
// TODO: implement event loop for Emscripten
38
#else
39
#error "No EventLoop implementation selected, tests will fail"
40
#endif
41

42
using namespace realm::util;
43

44
namespace {
45
template <typename Desired, typename Actual>
46
void static_assert_EventLoopDispatcher_guide(const EventLoopDispatcher<Actual>&)
47
{
×
48
    static_assert(std::is_same_v<Actual, Desired>);
×
49
}
×
50

51
[[maybe_unused]] void check_EventLoopDispatcher_guides()
52
{
×
53
    // This doesn't actually run, the only "test" is that it compiles.
×
54
    static_assert_EventLoopDispatcher_guide<void()>(EventLoopDispatcher([] {}));
×
55
    static_assert_EventLoopDispatcher_guide<void()>(EventLoopDispatcher(+[] {}));
×
56
    static_assert_EventLoopDispatcher_guide<void()>(EventLoopDispatcher([]() mutable {}));
×
57
    static_assert_EventLoopDispatcher_guide<void()>(EventLoopDispatcher(+[]() mutable {}));
×
58
    static_assert_EventLoopDispatcher_guide<void()>(EventLoopDispatcher([]() noexcept {}));
×
59
    static_assert_EventLoopDispatcher_guide<void()>(EventLoopDispatcher(+[]() noexcept {}));
×
60
    static_assert_EventLoopDispatcher_guide<void()>(EventLoopDispatcher([]() mutable noexcept {}));
×
61
    static_assert_EventLoopDispatcher_guide<void()>(EventLoopDispatcher(+[]() mutable noexcept {}));
×
62

×
63
    static_assert_EventLoopDispatcher_guide<void(int)>(EventLoopDispatcher([](int) {}));
×
64
    static_assert_EventLoopDispatcher_guide<void(int)>(EventLoopDispatcher(+[](int) {}));
×
65
    static_assert_EventLoopDispatcher_guide<void(int, const double&)>(EventLoopDispatcher([](int, const double&) {}));
×
66
    static_assert_EventLoopDispatcher_guide<void(int, const double&)>(
×
67
        EventLoopDispatcher(+[](int, const double&) {}));
×
68

×
69
    struct Funcy {
×
70
        void operator()(int) const& noexcept {}
×
71
    };
×
72
    static_assert_EventLoopDispatcher_guide<void(int)>(EventLoopDispatcher(Funcy()));
×
73
}
×
74
} // namespace
75

76
struct EventLoop::Impl {
77
    // Returns the main event loop.
78
    static std::unique_ptr<Impl> main();
79

80
    // Run the event loop until the given return predicate returns true
81
    void run_until(util::FunctionRef<bool()> predicate);
82

83
    // Schedule execution of the given function on the event loop.
84
    void perform(util::UniqueFunction<void()>);
85

86
    // Run the event loop until all currently pending work has been run.
87
    void run_pending();
88

89
    ~Impl();
90

91
private:
92
#if TEST_SCHEDULER_UV
93
    Impl(uv_loop_t* loop);
94

95
    std::vector<util::UniqueFunction<void()>> m_pending_work;
96
    std::mutex m_mutex;
97
    uv_loop_t* m_loop;
98
    uv_async_t m_perform_work;
99
#elif REALM_PLATFORM_APPLE
100
    Impl(util::CFPtr<CFRunLoopRef> loop)
101
        : m_loop(std::move(loop))
102
    {
103
    }
104

105
    util::CFPtr<CFRunLoopRef> m_loop;
106
#endif
107
};
108

109
EventLoop& EventLoop::main()
110
{
332✔
111
    static EventLoop main(Impl::main());
332✔
112
    return main;
332✔
113
}
332✔
114

115
EventLoop::EventLoop(std::unique_ptr<Impl> impl)
116
    : m_impl(std::move(impl))
2✔
117
{
2✔
118
}
2✔
119

120
EventLoop::~EventLoop() = default;
2✔
121

122
void EventLoop::run_until(util::FunctionRef<bool()> predicate)
123
{
330✔
124
    return m_impl->run_until(predicate);
330✔
125
}
330✔
126

127
void EventLoop::perform(util::UniqueFunction<void()> function)
128
{
×
129
    return m_impl->perform(std::move(function));
×
130
}
×
131

132
void EventLoop::run_pending()
133
{
2✔
134
    return m_impl->run_pending();
2✔
135
}
2✔
136

137
#if TEST_SCHEDULER_UV
138

139
bool EventLoop::has_implementation()
140
{
2,049✔
141
    return true;
2,049✔
142
}
2,049✔
143

144
std::unique_ptr<EventLoop::Impl> EventLoop::Impl::main()
145
{
2✔
146
    return std::unique_ptr<Impl>(new Impl(uv_default_loop()));
2✔
147
}
2✔
148

149
EventLoop::Impl::Impl(uv_loop_t* loop)
150
    : m_loop(loop)
2✔
151
{
2✔
152
    m_perform_work.data = this;
2✔
153
    uv_async_init(uv_default_loop(), &m_perform_work, [](uv_async_t* handle) {
2✔
154
        std::vector<util::UniqueFunction<void()>> pending_work;
×
155
        {
×
156
            Impl& self = *static_cast<Impl*>(handle->data);
×
157
            std::lock_guard<std::mutex> lock(self.m_mutex);
×
158
            std::swap(pending_work, self.m_pending_work);
×
159
        }
×
160

161
        for (auto& f : pending_work)
×
162
            f();
×
163
    });
×
164
}
2✔
165

166
EventLoop::Impl::~Impl()
167
{
2✔
168
    uv_close((uv_handle_t*)&m_perform_work, [](uv_handle_t*) {});
2✔
169
    uv_loop_close(m_loop);
2✔
170
}
2✔
171

172
struct IdleHandler {
173
    uv_idle_t* idle = new uv_idle_t;
174

175
    IdleHandler(uv_loop_t* loop)
176
    {
210✔
177
        uv_idle_init(loop, idle);
210✔
178
    }
210✔
179
    ~IdleHandler()
180
    {
210✔
181
        uv_close(reinterpret_cast<uv_handle_t*>(idle), [](uv_handle_t* handle) {
210✔
182
            delete reinterpret_cast<uv_idle_t*>(handle);
208✔
183
        });
208✔
184
    }
210✔
185
};
186

187
void EventLoop::Impl::run_until(util::FunctionRef<bool()> predicate)
188
{
330✔
189
    if (predicate())
330✔
190
        return;
120✔
191

192
    IdleHandler observer(m_loop);
210✔
193
    observer.idle->data = &predicate;
210✔
194

195
    uv_idle_start(observer.idle, [](uv_idle_t* handle) {
183,380,350✔
196
        auto& predicate = *static_cast<util::FunctionRef<bool()>*>(handle->data);
183,380,350✔
197
        if (predicate()) {
183,380,350✔
198
            uv_stop(handle->loop);
207✔
199
        }
207✔
200
    });
183,380,350✔
201

202
    auto cleanup = make_scope_exit([&]() noexcept {
210✔
203
        uv_idle_stop(observer.idle);
210✔
204
    });
210✔
205
    uv_run(m_loop, UV_RUN_DEFAULT);
210✔
206
}
210✔
207

208
void EventLoop::Impl::perform(util::UniqueFunction<void()> f)
209
{
×
210
    {
×
211
        std::lock_guard<std::mutex> lock(m_mutex);
×
212
        m_pending_work.push_back(std::move(f));
×
213
    }
×
214
    uv_async_send(&m_perform_work);
×
215
}
×
216

217
void EventLoop::Impl::run_pending()
218
{
2✔
219
    uv_run(m_loop, UV_RUN_NOWAIT);
2✔
220
}
2✔
221

222
#elif REALM_PLATFORM_APPLE
223

224
bool EventLoop::has_implementation()
225
{
226
    return true;
227
}
228

229
std::unique_ptr<EventLoop::Impl> EventLoop::Impl::main()
230
{
231
    return std::unique_ptr<Impl>(new Impl(retainCF(CFRunLoopGetMain())));
232
}
233

234
EventLoop::Impl::~Impl() = default;
235

236
void EventLoop::Impl::run_until(util::FunctionRef<bool()> predicate)
237
{
238
    REALM_ASSERT(m_loop.get() == CFRunLoopGetCurrent());
239

240
    auto callback = [](CFRunLoopObserverRef, CFRunLoopActivity, void* info) {
241
        if ((*static_cast<util::FunctionRef<bool()>*>(info))()) {
242
            CFRunLoopStop(CFRunLoopGetCurrent());
243
        }
244
    };
245
    CFRunLoopObserverContext ctx{};
246
    ctx.info = &predicate;
247
    auto observer =
248
        adoptCF(CFRunLoopObserverCreate(kCFAllocatorDefault, kCFRunLoopAllActivities, true, 0, callback, &ctx));
249
    auto timer = adoptCF(CFRunLoopTimerCreateWithHandler(
250
        kCFAllocatorDefault, CFAbsoluteTimeGetCurrent(), 0.0005, 0, 0,
251
        ^(CFRunLoopTimerRef){
252
            // Do nothing. The timer firing is sufficient to cause our runloop observer to run.
253
        }));
254
    CFRunLoopAddObserver(CFRunLoopGetCurrent(), observer.get(), kCFRunLoopCommonModes);
255
    CFRunLoopAddTimer(CFRunLoopGetCurrent(), timer.get(), kCFRunLoopCommonModes);
256
    auto cleanup = make_scope_exit([&]() noexcept {
257
        CFRunLoopRemoveTimer(CFRunLoopGetCurrent(), timer.get(), kCFRunLoopCommonModes);
258
        CFRunLoopRemoveObserver(CFRunLoopGetCurrent(), observer.get(), kCFRunLoopCommonModes);
259
    });
260
    CFRunLoopRun();
261
}
262

263
void EventLoop::Impl::perform(util::UniqueFunction<void()> func)
264
{
265
    __block auto f = std::move(func);
266
    CFRunLoopPerformBlock(m_loop.get(), kCFRunLoopDefaultMode, ^{
267
        f();
268
    });
269
    CFRunLoopWakeUp(m_loop.get());
270
}
271

272
void EventLoop::Impl::run_pending()
273
{
274
    while (CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0, true) == kCFRunLoopRunHandledSource)
275
        ;
276
}
277

278
#else
279

280
bool EventLoop::has_implementation()
281
{
282
    return false;
283
}
284
std::unique_ptr<EventLoop::Impl> EventLoop::Impl::main()
285
{
286
    return nullptr;
287
}
288
EventLoop::Impl::~Impl() = default;
289
void EventLoop::Impl::run_until(util::FunctionRef<bool()>)
290
{
291
    printf("WARNING: there is no event loop implementation and nothing is happening.\n");
292
}
293
void EventLoop::Impl::perform(util::UniqueFunction<void()>)
294
{
295
    printf("WARNING: there is no event loop implementation and nothing is happening.\n");
296
}
297
void EventLoop::Impl::run_pending()
298
{
299
    printf("WARNING: there is no event loop implementation and nothing is happening.\n");
300
}
301

302
#endif
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc