-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathasync_event_emitting_reentrant_c_worker.hpp
80 lines (70 loc) · 3.79 KB
/
async_event_emitting_reentrant_c_worker.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
/*
* Copyright 2017 Scoop Technologies
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
* documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
* WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#pragma once
#ifndef _NODE_EVENT_ASYNC_EVENT_EMITTING_REENTRANT_C_WORKER
#define _NODE_EVENT_ASYNC_EVENT_EMITTING_REENTRANT_C_WORKER
#include <functional>
#include <memory>
#include "cemitter.h"
#include "async_queued_progress_worker.hpp"
#include "eventemitter_impl.hpp"
namespace NodeEvent {
#ifndef UNUSED
#define UNUSED(x) (void)(x)
#endif
template <size_t SIZE>
class AsyncEventEmittingReentrantCWorker : public AsyncQueuedProgressWorker<EventEmitter::ProgressReport, SIZE> {
public:
typedef typename AsyncQueuedProgressWorker<EventEmitter::ProgressReport, SIZE>::ExecutionProgressSender ExecutionProgressSender;
/// @param[in] callback - the callback to invoke after Execute completes. (unless overridden, is called from
/// HandleOKCallback with no arguments, and called from HandleErrorCallback with the errors
/// reported (if any)
/// @param[in] emitter - The emitter object to use for notifying JS callbacks for given events.
AsyncEventEmittingReentrantCWorker(Nan::Callback* callback, std::shared_ptr<EventEmitter> emitter)
: AsyncQueuedProgressWorker<EventEmitter::ProgressReport, SIZE>(callback), emitter_(emitter) {}
/// emit the EventEmitter::ProgressReport as an event via the given emitter, ignores whether or not the emit is successful
///
/// @param[in] report - an array (of size 1) of a EventEmitter::ProgressReport (which is a pair, where first is the "key" and
/// second is the "value")
/// @param[in] size - size of the array (should always be 1)
virtual void HandleProgressCallback(const EventEmitter::ProgressReport* report, size_t size) override {
UNUSED(size);
Nan::HandleScope scope;
emitter_->emit(report[0].first, report[0].second);
}
/// The work you need to happen in a worker thread
///
/// @param[in] sender - An object you must pass as the first argument of fn
/// @param[in] fn - Function suitable for passing to multi-threaded C code
virtual void ExecuteWithEmitter(const ExecutionProgressSender* sender, eventemitter_fn_r fn) = 0;
private:
virtual void Execute(const ExecutionProgressSender& sender) override {
ExecuteWithEmitter(&sender, this->reentrant_emit);
}
static int reentrant_emit(const void* sender, const char* ev, const char* value) {
if (sender) {
auto reports = new EventEmitter::ProgressReport[1];
reports[0] = {ev, value};
auto emitter = static_cast<const ExecutionProgressSender*>(sender);
return static_cast<int>(emitter->Send(reports, 1));
}
return false;
}
std::shared_ptr<EventEmitter> emitter_;
};
} // namespace NodeEvent
#endif