-
-
Notifications
You must be signed in to change notification settings - Fork 218
/
Copy pathsocket.h
135 lines (100 loc) · 4.2 KB
/
socket.h
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
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
#pragma once
#include <functional>
#include <optional>
#include "./closable.h"
#include "./inline.h"
#include "./outgoing_msg.h"
#include "./poller.h"
namespace zmq {
class Module;
class Socket : public Napi::ObjectWrap<Socket>, public Closable {
public:
static void Initialize(Module& module, Napi::Object& exports);
explicit Socket(const Napi::CallbackInfo& info);
Socket(const Socket&) = delete;
Socket(Socket&&) = delete;
Socket& operator=(const Socket&) = delete;
Socket& operator=(Socket&&) = delete;
~Socket() override;
void Close() override;
protected:
enum class State : uint8_t {
Open, /* Socket is open. */
Closed, /* Socket is closed. */
Blocked, /* Async operation in progress that disallows socket access. */
};
inline void Close(const Napi::CallbackInfo& info);
inline Napi::Value Bind(const Napi::CallbackInfo& info);
inline Napi::Value BindSync(const Napi::CallbackInfo& info);
inline Napi::Value Unbind(const Napi::CallbackInfo& info);
inline Napi::Value UnbindSync(const Napi::CallbackInfo& info);
inline void Connect(const Napi::CallbackInfo& info);
inline void Disconnect(const Napi::CallbackInfo& info);
inline Napi::Value Send(const Napi::CallbackInfo& info);
inline Napi::Value Receive(const Napi::CallbackInfo& info);
inline void Join(const Napi::CallbackInfo& info);
inline void Leave(const Napi::CallbackInfo& info);
template <typename T>
inline Napi::Value GetSockOpt(const Napi::CallbackInfo& info);
template <typename T>
inline void SetSockOpt(const Napi::CallbackInfo& info);
inline Napi::Value GetEvents(const Napi::CallbackInfo& info);
inline Napi::Value GetContext(const Napi::CallbackInfo& info);
inline Napi::Value GetClosed(const Napi::CallbackInfo& info);
inline Napi::Value GetReadable(const Napi::CallbackInfo& info);
inline Napi::Value GetWritable(const Napi::CallbackInfo& info);
private:
inline void WarnUnlessImmediateOption(int32_t option) const;
[[nodiscard]] inline bool ValidateOpen() const;
[[nodiscard]] bool HasEvents(uint32_t requested_events) const;
/* Send/receive are usually in a hot path and will benefit slightly
from being inlined. They are used in more than one location and are
not necessarily automatically inlined by all compilers. */
force_inline void Send(const Napi::Promise::Deferred& res, OutgoingMsg::Parts& parts);
force_inline void Receive(const Napi::Promise::Deferred& res);
inline void JoinElement(const Napi::Value& value);
inline void LeaveElement(const Napi::Value& value);
class Poller : public zmq::Poller<Poller> {
std::reference_wrapper<Socket> socket;
std::optional<Napi::Promise::Deferred> read_deferred;
std::optional<Napi::Promise::Deferred> write_deferred;
OutgoingMsg::Parts write_value;
public:
explicit Poller(std::reference_wrapper<Socket> socket) : socket(socket) {}
Napi::Value ReadPromise();
Napi::Value WritePromise(OutgoingMsg::Parts&& parts);
[[nodiscard]] bool Reading() const {
return read_deferred.has_value();
}
[[nodiscard]] bool Writing() const {
return write_deferred.has_value();
}
[[nodiscard]] bool ValidateReadable() const {
return socket.get().HasEvents(ZMQ_POLLIN);
}
[[nodiscard]] bool ValidateWritable() const {
return socket.get().HasEvents(ZMQ_POLLOUT);
}
void ReadableCallback();
void WritableCallback();
};
Napi::AsyncContext async_context;
Napi::ObjectReference context_ref;
Napi::ObjectReference observer_ref;
Socket::Poller poller;
Module& module;
void* socket = nullptr;
int64_t send_timeout = -1;
int64_t receive_timeout = -1;
uint32_t sync_operations = 0;
uint32_t endpoints = 0;
State state = State::Open;
bool request_close = false;
bool thread_safe = false;
int type = 0;
friend class Observer;
friend class Proxy;
};
} // namespace zmq
static_assert(!std::is_copy_constructible_v<zmq::Socket>, "not copyable");
static_assert(!std::is_move_constructible_v<zmq::Socket>, "not movable");