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 ProactorType, size_t OpCount>
42 class BasicAsyncDatagramSocket : public BasicAsyncRawSocket<Protocol, ProactorType, OpCount>
43 {
44 public:
45 using Socket = typename Protocol::Socket;
46 using Endpoint = typename Protocol::Endpoint;
51
56 explicit BasicAsyncDatagramSocket (ProactorType& proactor = ProactorThread::proactor ())
57 : BasicAsyncRawSocket<Protocol, ProactorType, OpCount> (proactor)
58 {
59 }
60
66 explicit BasicAsyncDatagramSocket (int ttl, ProactorType& proactor = ProactorThread::proactor ())
67 : BasicAsyncRawSocket<Protocol, ProactorType, OpCount> (Socket (ttl), proactor)
68 {
69 }
70
76 explicit BasicAsyncDatagramSocket (Socket&& sock, ProactorType& proactor = ProactorThread::proactor ())
77 : BasicAsyncRawSocket<Protocol, ProactorType, 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
138 ssize_t asyncReadFrom (ReadFromHandler handler, char* data, size_t maxSize, Endpoint& endpoint,
139 char* control = nullptr, size_t controlSize = 0, bool flush = true,
140 bool link = false) noexcept
141 {
142 if (JOIN_UNLIKELY (!this->_socket.opened ()))
143 {
145 return -1;
146 }
147
148 AsyncRead* read = this->allocateRead ();
149 if (JOIN_UNLIKELY (read == nullptr))
150 {
152 return -1;
153 }
154
155 read->readFromHandler = std::move (handler);
156 read->iov.iov_base = data;
157 read->iov.iov_len = maxSize;
158 read->msg.msg_name = endpoint.addr ();
159 read->msg.msg_namelen = sizeof (struct sockaddr_storage);
160 read->msg.msg_iov = &read->iov;
161 read->msg.msg_iovlen = 1;
162 read->msg.msg_control = control;
163 read->msg.msg_controllen = controlSize;
164 read->msg.msg_flags = 0;
165 read->op = IoOperation::makeRecvmsg (this->_socket.handle (), &read->msg, 0, this, link);
166 read->op.state.store (IoOperation::State::Submitted, std::memory_order_release);
167
168 size_t index = this->_allocator.getIndex (read);
169
170 if (this->_proactor->submit (read->op, flush, false) == -1)
171 {
172 // LCOV_EXCL_START
173 this->releaseOperation (read);
174 return -1;
175 // LCOV_EXCL_STOP
176 }
177
178 return static_cast<ssize_t> (index);
179 }
180
189 ssize_t asyncReadFromMulti (ReadFromHandler handler, uint16_t group, size_t controlSize = 0,
190 bool flush = true) noexcept
191 {
192 if (JOIN_UNLIKELY (!this->_socket.opened ()))
193 {
195 return -1;
196 }
197
198 AsyncRead* read = this->allocateRead ();
199 if (JOIN_UNLIKELY (read == nullptr))
200 {
202 return -1;
203 }
204
205 read->readFromHandler = std::move (handler);
206 read->msg.msg_name = nullptr;
207 read->msg.msg_namelen = sizeof (struct sockaddr_storage);
208 read->msg.msg_iov = &read->iov;
209 read->msg.msg_iovlen = 1;
210 read->msg.msg_control = nullptr;
211 read->msg.msg_controllen = controlSize;
212 read->msg.msg_flags = 0;
213 read->op = IoOperation::makeRecvmsgMulti (this->_socket.handle (), group, &read->msg, 0, this);
214 read->op.state.store (IoOperation::State::Submitted, std::memory_order_release);
215
216 size_t index = this->_allocator.getIndex (read);
217
218 if (this->_proactor->submit (read->op, flush, false) == -1)
219 {
220 // LCOV_EXCL_START
221 this->releaseOperation (read);
222 return -1;
223 // LCOV_EXCL_STOP
224 }
225
226 return static_cast<ssize_t> (index);
227 }
228
241 ssize_t asyncWriteTo (WriteHandler handler, const char* data, size_t size, Endpoint& endpoint,
242 const char* control = nullptr, size_t controlSize = 0, bool flush = true,
243 bool link = false) noexcept
244 {
245 if (JOIN_UNLIKELY (!this->_allocator.hasBackend ()))
246 {
248 return -1;
249 }
250
251 if (!this->_socket.opened () && (this->_socket.open (endpoint.protocol ()) == -1))
252 {
253 return -1; // LCOV_EXCL_LINE
254 }
255
256 AsyncWrite* write = this->allocateWrite ();
257 if (JOIN_UNLIKELY (write == nullptr))
258 {
260 return -1;
261 }
262
263 write->writeHandler = std::move (handler);
264 write->iov.iov_base = const_cast<char*> (data);
265 write->iov.iov_len = size;
266 write->msg.msg_name = endpoint.addr ();
267 write->msg.msg_namelen = endpoint.length ();
268 write->msg.msg_iov = &write->iov;
269 write->msg.msg_iovlen = 1;
270 write->msg.msg_control = const_cast<char*> (control);
271 write->msg.msg_controllen = controlSize;
272 write->msg.msg_flags = 0;
273 write->op = IoOperation::makeSendmsg (this->_socket.handle (), &write->msg, MSG_NOSIGNAL, this, link);
274 write->op.state.store (IoOperation::State::Submitted, std::memory_order_release);
275
276 size_t index = this->_allocator.getIndex (write);
277
278 if (this->_proactor->submit (write->op, flush, false) == -1)
279 {
280 // LCOV_EXCL_START
281 this->releaseOperation (write);
282 return -1;
283 // LCOV_EXCL_STOP
284 }
285
286 return static_cast<ssize_t> (index);
287 }
288
293 const Endpoint& remoteEndpoint () const noexcept
294 {
295 return this->_socket.remoteEndpoint ();
296 }
297
302 bool connected () const noexcept
303 {
304 return this->_socket.connected ();
305 }
306
311 int mtu () const noexcept
312 {
313 return this->_socket.mtu ();
314 }
315
320 int ttl () const noexcept
321 {
322 return this->_socket.ttl ();
323 }
324 };
325}
326
327#endif
asynchronous datagram socket class.
Definition protocol.hpp:91
typename AsyncWrite::Write WriteHandler
Definition async_datagram_socket.hpp:50
const Endpoint & remoteEndpoint() const noexcept
determine the remote endpoint associated with this socket.
Definition async_datagram_socket.hpp:293
BasicAsyncDatagramSocket(BasicAsyncDatagramSocket &&other) noexcept=default
move constructor.
BasicAsyncDatagramSocket & operator=(const BasicAsyncDatagramSocket &other)=delete
copy assignment operator.
int ttl() const noexcept
returns the Time-To-Live value.
Definition async_datagram_socket.hpp:320
BasicAsyncDatagramSocket(const BasicAsyncDatagramSocket &other)=delete
copy constructor.
bool connected() const noexcept
check if the socket is connected.
Definition async_datagram_socket.hpp:302
int disconnect() noexcept
remove the default remote endpoint.
Definition async_datagram_socket.hpp:121
BasicAsyncDatagramSocket(ProactorType &proactor=ProactorThread::proactor())
create the socket instance.
Definition async_datagram_socket.hpp:56
int mtu() const noexcept
get socket mtu.
Definition async_datagram_socket.hpp:311
typename Protocol::Endpoint Endpoint
Definition async_datagram_socket.hpp:46
int connect(const Endpoint &endpoint) noexcept
assign the default remote endpoint for this socket.
Definition async_datagram_socket.hpp:112
ssize_t asyncReadFrom(ReadFromHandler handler, char *data, size_t maxSize, Endpoint &endpoint, char *control=nullptr, size_t controlSize=0, bool flush=true, bool link=false) noexcept
start an asynchronous read, reporting the endpoint the data are coming from.
Definition async_datagram_socket.hpp:138
ssize_t asyncWriteTo(WriteHandler handler, const char *data, size_t size, Endpoint &endpoint, const char *control=nullptr, size_t controlSize=0, bool flush=true, bool link=false) noexcept
start an asynchronous write to the given endpoint.
Definition async_datagram_socket.hpp:241
typename AsyncRead::ReadFrom ReadFromHandler
Definition async_datagram_socket.hpp:49
BasicAsyncDatagramSocket(Socket &&sock, ProactorType &proactor=ProactorThread::proactor())
create the socket instance adopting an already opened socket.
Definition async_datagram_socket.hpp:76
BasicAsyncDatagramSocket(int ttl, ProactorType &proactor=ProactorThread::proactor())
create the socket instance specifying the time to live.
Definition async_datagram_socket.hpp:66
ssize_t asyncReadFromMulti(ReadFromHandler handler, uint16_t group, size_t controlSize=0, bool flush=true) noexcept
start an asynchronous multishot read, reporting the endpoint the data are coming from.
Definition async_datagram_socket.hpp:189
typename Protocol::Socket Socket
Definition async_datagram_socket.hpp:45
asynchronous raw socket class.
Definition protocol.hpp:88
AsyncWrite * allocateWrite() noexcept
Definition async_raw_socket.hpp:588
AsyncRead * allocateRead() noexcept
Definition async_raw_socket.hpp:579
Socket _socket
Definition async_socket.hpp:657
void releaseOperation(Op *operation) noexcept
Definition async_socket.hpp:539
BasicProactor * _proactor
Definition async_socket.hpp:654
OpAllocator _allocator
Definition async_socket.hpp:660
static BasicProactor & proactor()
get the Proactor instance owned by the singleton ProactorThread.
Definition proactor.hpp:1053
int submit(IoOperation &op, bool flush=false, bool sync=false) noexcept
submit an asynchronous operation to the proactor.
Definition proactor.hpp:741
uint32_t getIndex(void *p) const noexcept
get the index of a chunk in the pool.
Definition slab_allocator.hpp:455
bool hasBackend() const noexcept
check if the slab allocator still owns a memory region.
Definition slab_allocator.hpp:444
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
ReadFrom readFromHandler
handler invoked on completion, reporting the endpoint the data are coming from.
Definition async_operation.hpp:107
IoOperation op
operation submitted to the proactor.
Definition async_operation.hpp:101
msghdr msg
read message header.
Definition async_operation.hpp:110
Function< void(const std::error_code &, const char *, size_t, const Endpoint &, const char *, size_t, bool), 16 > ReadFrom
handler invoked on completion, reporting the endpoint the data are coming from and the control messag...
Definition async_operation.hpp:96
iovec iov
read scatter gather entry.
Definition async_operation.hpp:113
asynchronous write operation.
Definition async_operation.hpp:121
msghdr msg
write message header.
Definition async_operation.hpp:138
Function< void(const std::error_code &, size_t), 16 > Write
handler invoked on completion.
Definition async_operation.hpp:126
Write writeHandler
handler invoked on completion.
Definition async_operation.hpp:135
iovec iov
write scatter gather entry.
Definition async_operation.hpp:141
IoOperation op
operation submitted to the proactor.
Definition async_operation.hpp:129
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:271
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:251
static IoOperation makeRecvmsg(int fd, msghdr *msg, int flags, CompletionHandler *handler, bool linked=false) noexcept
build a receive-message operation.
Definition io_operation.cpp:235
std::atomic< State > state
operation state.
Definition io_operation.hpp:404
#define JOIN_UNLIKELY(x)
Definition utils.hpp:51