join 1.0
lightweight network framework library
Loading...
Searching...
No Matches
async_datagram_socket.hpp
Go to the documentation of this file.
1
25#ifndef JOIN_CORE_ASYNC_DATAGRAM_SOCKET_HPP
26#define JOIN_CORE_ASYNC_DATAGRAM_SOCKET_HPP
27
28// libjoin.
31
32// C++.
33#include <system_error>
34#include <utility>
35
36namespace join
37{
41 template <class Protocol, class Proactor, size_t OpCount>
42 class BasicAsyncDatagramSocket : public BasicAsyncRawSocket<Protocol, Proactor, OpCount>
43 {
44 public:
45 using Socket = typename Protocol::Socket;
46 using Endpoint = typename Protocol::Endpoint;
51
57 : BasicAsyncRawSocket<Protocol, Proactor, OpCount> (proactor)
58 {
59 }
60
67 : BasicAsyncRawSocket<Protocol, Proactor, OpCount> (Socket (ttl), proactor)
68 {
69 }
70
77 : BasicAsyncRawSocket<Protocol, Proactor, OpCount> (std::move (sock), proactor)
78 {
79 }
80
86
93
99
106
112 int connect (const Endpoint& endpoint) noexcept
113 {
114 return this->_socket.connect (endpoint);
115 }
116
121 int disconnect () noexcept
122 {
123 return this->_socket.disconnect ();
124 }
125
136 ssize_t asyncReadFrom (char* data, size_t maxSize, Endpoint& endpoint, ReadFromHandler handler,
137 bool flush = true, bool link = false) noexcept
138 {
139 if (JOIN_UNLIKELY (!this->_socket.opened ()))
140 {
142 return -1;
143 }
144
145 AsyncRead* read = this->allocateRead ();
146 if (JOIN_UNLIKELY (read == nullptr))
147 {
149 return -1;
150 }
151
152 read->readFromHandler = std::move (handler);
153 read->iov.iov_base = data;
154 read->iov.iov_len = maxSize;
155 read->msg.msg_name = endpoint.addr ();
156 read->msg.msg_namelen = sizeof (struct sockaddr_storage);
157 read->msg.msg_iov = &read->iov;
158 read->msg.msg_iovlen = 1;
159 read->msg.msg_control = nullptr;
160 read->msg.msg_controllen = 0;
161 read->msg.msg_flags = 0;
162 read->op = IoOperation::makeRecvmsg (this->_socket.handle (), &read->msg, 0, this, link);
163 read->op.state.store (IoOperation::State::Submitted, std::memory_order_release);
164
165 size_t index = this->_arena.getIndex (read);
166
167 if (this->_proactor->submit (read->op, flush, false) == -1)
168 {
169 // LCOV_EXCL_START
170 this->releaseOp (read);
171 return -1;
172 // LCOV_EXCL_STOP
173 }
174
175 return static_cast<ssize_t> (index);
176 }
177
185 ssize_t asyncReadFromMulti (uint16_t group, ReadFromHandler handler, bool flush = true) noexcept
186 {
187 if (JOIN_UNLIKELY (!this->_socket.opened ()))
188 {
190 return -1;
191 }
192
193 AsyncRead* read = this->allocateRead ();
194 if (JOIN_UNLIKELY (read == nullptr))
195 {
197 return -1;
198 }
199
200 read->readFromHandler = std::move (handler);
201 read->msg.msg_name = nullptr;
202 read->msg.msg_namelen = sizeof (struct sockaddr_storage);
203 read->msg.msg_iov = &read->iov;
204 read->msg.msg_iovlen = 1;
205 read->msg.msg_control = nullptr;
206 read->msg.msg_controllen = 0;
207 read->msg.msg_flags = 0;
208 read->op = IoOperation::makeRecvmsgMulti (this->_socket.handle (), group, &read->msg, 0, this);
209 read->op.state.store (IoOperation::State::Submitted, std::memory_order_release);
210
211 size_t index = this->_arena.getIndex (read);
212
213 if (this->_proactor->submit (read->op, flush, false) == -1)
214 {
215 // LCOV_EXCL_START
216 this->releaseOp (read);
217 return -1;
218 // LCOV_EXCL_STOP
219 }
220
221 return static_cast<ssize_t> (index);
222 }
223
234 ssize_t asyncWriteTo (const char* data, size_t size, Endpoint& endpoint, WriteHandler handler,
235 bool flush = true, bool link = false) noexcept
236 {
237 if (JOIN_UNLIKELY (!this->_arena.hasBackend ()))
238 {
240 return -1;
241 }
242
243 if (!this->_socket.opened () && (this->_socket.open (endpoint.protocol ()) == -1))
244 {
245 return -1; // LCOV_EXCL_LINE
246 }
247
248 AsyncWrite* write = this->allocateWrite ();
249 if (JOIN_UNLIKELY (write == nullptr))
250 {
252 return -1;
253 }
254
255 write->writeHandler = std::move (handler);
256 write->iov.iov_base = const_cast<char*> (data);
257 write->iov.iov_len = size;
258 write->msg.msg_name = endpoint.addr ();
259 write->msg.msg_namelen = endpoint.length ();
260 write->msg.msg_iov = &write->iov;
261 write->msg.msg_iovlen = 1;
262 write->msg.msg_control = nullptr;
263 write->msg.msg_controllen = 0;
264 write->msg.msg_flags = 0;
265 write->op = IoOperation::makeSendmsg (this->_socket.handle (), &write->msg, MSG_NOSIGNAL, this, link);
266 write->op.state.store (IoOperation::State::Submitted, std::memory_order_release);
267
268 size_t index = this->_arena.getIndex (write);
269
270 if (this->_proactor->submit (write->op, flush, false) == -1)
271 {
272 // LCOV_EXCL_START
273 this->releaseOp (write);
274 return -1;
275 // LCOV_EXCL_STOP
276 }
277
278 return static_cast<ssize_t> (index);
279 }
280
285 const Endpoint& remoteEndpoint () const noexcept
286 {
287 return this->_socket.remoteEndpoint ();
288 }
289
294 bool connected () const noexcept
295 {
296 return this->_socket.connected ();
297 }
298
303 int mtu () const noexcept
304 {
305 return this->_socket.mtu ();
306 }
307
312 int ttl () const noexcept
313 {
314 return this->_socket.ttl ();
315 }
316 };
317}
318
319#endif
bool hasBackend() const noexcept
check if the arena still owns a memory region.
Definition allocator.hpp:487
uint32_t getIndex(void *p) const noexcept
get the index of a chunk in the pool.
Definition allocator.hpp:498
asynchronous datagram socket class.
Definition protocol.hpp:88
typename Protocol::Endpoint Endpoint
Definition async_datagram_socket.hpp:46
BasicAsyncDatagramSocket & operator=(const BasicAsyncDatagramSocket &other)=delete
copy assignment operator.
int mtu() const noexcept
get socket mtu.
Definition async_datagram_socket.hpp:303
typename AsyncRead::ReadFrom ReadFromHandler
Definition async_datagram_socket.hpp:49
BasicAsyncDatagramSocket(int ttl, Proactor &proactor=ProactorThread::proactor())
create the socket instance specifying the time to live.
Definition async_datagram_socket.hpp:66
typename AsyncWrite::Write WriteHandler
Definition async_datagram_socket.hpp:50
BasicAsyncDatagramSocket(Socket &&sock, Proactor &proactor=ProactorThread::proactor())
create the socket instance adopting an already opened socket.
Definition async_datagram_socket.hpp:76
bool connected() const noexcept
check if the socket is connected.
Definition async_datagram_socket.hpp:294
int ttl() const noexcept
returns the Time-To-Live value.
Definition async_datagram_socket.hpp:312
ssize_t asyncReadFromMulti(uint16_t group, ReadFromHandler handler, bool flush=true) noexcept
start an asynchronous multishot read, reporting the endpoint the data are coming from.
Definition async_datagram_socket.hpp:185
BasicAsyncDatagramSocket(BasicAsyncDatagramSocket &&other) noexcept=default
move constructor.
ssize_t asyncReadFrom(char *data, size_t maxSize, Endpoint &endpoint, ReadFromHandler handler, bool flush=true, bool link=false) noexcept
start an asynchronous read, reporting the endpoint the data are coming from.
Definition async_datagram_socket.hpp:136
const Endpoint & remoteEndpoint() const noexcept
determine the remote endpoint associated with this socket.
Definition async_datagram_socket.hpp:285
typename Protocol::Socket Socket
Definition async_datagram_socket.hpp:45
ssize_t asyncWriteTo(const char *data, size_t size, Endpoint &endpoint, WriteHandler handler, bool flush=true, bool link=false) noexcept
start an asynchronous write to the given endpoint.
Definition async_datagram_socket.hpp:234
BasicAsyncDatagramSocket(Proactor &proactor=ProactorThread::proactor())
create the socket instance.
Definition async_datagram_socket.hpp:56
int disconnect() noexcept
remove the default remote endpoint.
Definition async_datagram_socket.hpp:121
BasicAsyncDatagramSocket(const BasicAsyncDatagramSocket &other)=delete
copy constructor.
int connect(const Endpoint &endpoint) noexcept
assign the default remote endpoint for this socket.
Definition async_datagram_socket.hpp:112
asynchronous raw socket class.
Definition protocol.hpp:85
AsyncRead * allocateRead() noexcept
Definition async_raw_socket.hpp:570
AsyncWrite * allocateWrite() noexcept
Definition async_raw_socket.hpp:579
Socket _socket
Definition async_socket.hpp:629
void releaseOp(Op *operation) noexcept
Definition async_socket.hpp:525
OpArena _arena
Definition async_socket.hpp:632
BasicProactor * _proactor
Definition async_socket.hpp:626
static BasicProactor & proactor()
get the Proactor instance owned by the singleton ProactorThread.
Definition proactor.hpp:982
basic proactor class.
Definition proactor.hpp:156
int submit(IoOperation &op, bool flush=false, bool sync=false) noexcept
submit an asynchronous operation to the proactor.
Definition proactor.hpp:655
Definition acceptor.hpp:32
std::error_code make_error_code(join::Errc code) noexcept
Create an std::error_code object.
Definition error.cpp:195
Definition error.hpp:144
asynchronous read operation.
Definition async_operation.hpp:89
IoOperation op
operation submitted to the proactor.
Definition async_operation.hpp:99
iovec iov
read scatter gather entry.
Definition async_operation.hpp:111
ReadFrom readFromHandler
handler invoked on completion, reporting the endpoint the data are coming from.
Definition async_operation.hpp:105
msghdr msg
read message header.
Definition async_operation.hpp:108
Function< void(const std::error_code &, const char *, size_t, const Endpoint &, bool), 16 > ReadFrom
handler invoked on completion, reporting the endpoint the data are coming from.
Definition async_operation.hpp:96
asynchronous write operation.
Definition async_operation.hpp:119
Function< void(const std::error_code &, size_t), 16 > Write
handler invoked on completion.
Definition async_operation.hpp:124
Write writeHandler
handler invoked on completion.
Definition async_operation.hpp:133
msghdr msg
write message header.
Definition async_operation.hpp:136
iovec iov
write scatter gather entry.
Definition async_operation.hpp:139
IoOperation op
operation submitted to the proactor.
Definition async_operation.hpp:127
static IoOperation makeSendmsg(int fd, const msghdr *msg, int flags, CompletionHandler *handler, bool linked=false) noexcept
build a send-message operation.
Definition io_operation.cpp:263
static IoOperation makeRecvmsgMulti(int fd, uint16_t group, msghdr *msg, int flags, CompletionHandler *handler) noexcept
build a multishot receive-message operation.
Definition io_operation.cpp:243
static IoOperation makeRecvmsg(int fd, msghdr *msg, int flags, CompletionHandler *handler, bool linked=false) noexcept
build a receive-message operation.
Definition io_operation.cpp:227
std::atomic< State > state
operation state.
Definition io_operation.hpp:392
#define JOIN_UNLIKELY(x)
Definition utils.hpp:46