mediasoup 3.20.6 → 3.20.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/node/lib/Worker.d.ts +1 -1
- package/node/lib/Worker.d.ts.map +1 -1
- package/node/lib/Worker.js +1 -11
- package/node/lib/WorkerTypes.d.ts +0 -9
- package/node/lib/WorkerTypes.d.ts.map +1 -1
- package/node/lib/fbs/plain-transport/connect-response.d.ts.map +1 -1
- package/node/lib/fbs/plain-transport/connect-response.js +0 -1
- package/node/lib/fbs/worker/dump-response.d.ts +1 -5
- package/node/lib/fbs/worker/dump-response.d.ts.map +1 -1
- package/node/lib/fbs/worker/dump-response.js +3 -16
- package/node/lib/index.d.ts +1 -1
- package/node/lib/index.d.ts.map +1 -1
- package/node/lib/index.js +1 -2
- package/node/lib/test/test-PlainTransport.js +30 -0
- package/node/lib/test/test-Worker.js +0 -1
- package/npm-scripts.mjs +13 -8
- package/package.json +6 -6
- package/worker/fbs/meson.build +0 -1
- package/worker/fbs/plainTransport.fbs +1 -1
- package/worker/fbs/worker.fbs +0 -2
- package/worker/include/RTC/ICE/StunPacket.hpp +8 -9
- package/worker/include/RTC/RTP/Packet.hpp +1 -1
- package/worker/include/RTC/RTP/ProbationGenerator.hpp +1 -1
- package/worker/include/RTC/SCTP/packet/Chunk.hpp +1 -1
- package/worker/include/RTC/SCTP/packet/ErrorCause.hpp +1 -1
- package/worker/include/RTC/SCTP/packet/Packet.hpp +1 -2
- package/worker/include/RTC/SCTP/packet/Parameter.hpp +1 -1
- package/worker/include/RTC/SCTP/packet/TLV.hpp +1 -1
- package/worker/include/RTC/SCTP/packet/chunks/DataChunk.hpp +1 -1
- package/worker/include/RTC/SCTP/packet/chunks/ForwardTsnChunk.hpp +1 -1
- package/worker/include/RTC/SCTP/packet/chunks/IDataChunk.hpp +1 -1
- package/worker/include/RTC/SCTP/packet/chunks/IForwardTsnChunk.hpp +1 -1
- package/worker/include/RTC/SCTP/packet/chunks/InitAckChunk.hpp +1 -1
- package/worker/include/RTC/SCTP/packet/chunks/InitChunk.hpp +1 -1
- package/worker/include/RTC/SCTP/packet/chunks/SackChunk.hpp +1 -1
- package/worker/include/RTC/SCTP/packet/chunks/ShutdownChunk.hpp +1 -1
- package/worker/include/RTC/SCTP/packet/errorCauses/InvalidStreamIdentifierErrorCause.hpp +1 -1
- package/worker/include/RTC/SCTP/packet/errorCauses/MissingMandatoryParameterErrorCause.hpp +1 -1
- package/worker/include/RTC/SCTP/packet/errorCauses/NoUserDataErrorCause.hpp +1 -1
- package/worker/include/RTC/SCTP/packet/errorCauses/StaleCookieErrorCause.hpp +1 -1
- package/worker/include/RTC/SCTP/packet/parameters/AddIncomingStreamsRequestParameter.hpp +1 -1
- package/worker/include/RTC/SCTP/packet/parameters/AddOutgoingStreamsRequestParameter.hpp +1 -1
- package/worker/include/RTC/SCTP/packet/parameters/CookiePreservativeParameter.hpp +1 -1
- package/worker/include/RTC/SCTP/packet/parameters/IPv4AddressParameter.hpp +1 -1
- package/worker/include/RTC/SCTP/packet/parameters/IPv6AddressParameter.hpp +1 -1
- package/worker/include/RTC/SCTP/packet/parameters/IncomingSsnResetRequestParameter.hpp +1 -1
- package/worker/include/RTC/SCTP/packet/parameters/OutgoingSsnResetRequestParameter.hpp +1 -1
- package/worker/include/RTC/SCTP/packet/parameters/ReconfigurationResponseParameter.hpp +2 -2
- package/worker/include/RTC/SCTP/packet/parameters/SsnTsnResetRequestParameter.hpp +1 -1
- package/worker/include/RTC/SCTP/packet/parameters/ZeroChecksumAcceptableParameter.hpp +1 -1
- package/worker/include/Settings.hpp +0 -1
- package/worker/include/handles/TcpConnectionHandle.hpp +0 -4
- package/worker/include/handles/UdpSocketHandle.hpp +0 -4
- package/worker/meson.build +0 -34
- package/worker/meson_options.txt +0 -1
- package/worker/src/RTC/PipeTransport.cpp +5 -5
- package/worker/src/RTC/PlainTransport.cpp +5 -5
- package/worker/src/RTC/RTP/Packet.cpp +0 -2
- package/worker/src/RTC/RTP/RtpStreamSend.cpp +0 -20
- package/worker/src/RTC/Router.cpp +0 -37
- package/worker/src/RTC/SCTP/association/Association.cpp +12 -7
- package/worker/src/RTC/SimulcastProducerStreamManager.cpp +2 -2
- package/worker/src/RTC/SrtpSession.cpp +0 -24
- package/worker/src/RTC/Transport.cpp +3 -22
- package/worker/src/RTC/WebRtcTransport.cpp +5 -5
- package/worker/src/Settings.cpp +0 -14
- package/worker/src/Utils/Crypto.cpp +3 -3
- package/worker/src/Utils/String.cpp +1 -1
- package/worker/src/Worker.cpp +5 -38
- package/worker/src/handles/TcpConnectionHandle.cpp +1 -42
- package/worker/src/handles/UdpSocketHandle.cpp +1 -42
- package/worker/src/lib.cpp +1 -10
- package/worker/fbs/liburing.fbs +0 -7
- package/worker/include/DepLibUring.hpp +0 -143
- package/worker/src/DepLibUring.cpp +0 -638
- package/worker/subprojects/liburing.wrap +0 -14
|
@@ -1,638 +0,0 @@
|
|
|
1
|
-
#define MS_CLASS "DepLibUring"
|
|
2
|
-
// #define MS_LOG_DEV_LEVEL 3
|
|
3
|
-
|
|
4
|
-
#include "DepLibUring.hpp"
|
|
5
|
-
#include "DepLibUV.hpp"
|
|
6
|
-
#include "Logger.hpp"
|
|
7
|
-
#include "MediaSoupErrors.hpp"
|
|
8
|
-
#include "Settings.hpp"
|
|
9
|
-
#include "Utils.hpp"
|
|
10
|
-
#include <stdexcept>
|
|
11
|
-
#include <sys/eventfd.h>
|
|
12
|
-
#include <sys/resource.h>
|
|
13
|
-
#include <sys/utsname.h>
|
|
14
|
-
|
|
15
|
-
/* Class variables. */
|
|
16
|
-
|
|
17
|
-
thread_local bool DepLibUring::enabled{ false };
|
|
18
|
-
// liburing instance per thread.
|
|
19
|
-
thread_local DepLibUring::LibUring* DepLibUring::liburing{ nullptr };
|
|
20
|
-
// Completion queue entry array used to retrieve processes tasks.
|
|
21
|
-
thread_local struct io_uring_cqe* Cqes[DepLibUring::QueueDepth];
|
|
22
|
-
|
|
23
|
-
/* Static methods for UV callbacks. */
|
|
24
|
-
|
|
25
|
-
inline static void onCloseFd(uv_handle_t* handle)
|
|
26
|
-
{
|
|
27
|
-
delete reinterpret_cast<uv_poll_t*>(handle);
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
inline static void onFdEvent(uv_poll_t* handle, int /*status*/, int /*events*/)
|
|
31
|
-
{
|
|
32
|
-
auto* liburing = static_cast<DepLibUring::LibUring*>(handle->data);
|
|
33
|
-
auto count = io_uring_peek_batch_cqe(liburing->GetRing(), Cqes, DepLibUring::QueueDepth);
|
|
34
|
-
|
|
35
|
-
// libuv uses level triggering, so we need to read from the socket to reset
|
|
36
|
-
// the counter in order to avoid libuv calling this callback indefinitely.
|
|
37
|
-
eventfd_t v;
|
|
38
|
-
const int err = eventfd_read(liburing->GetEventFd(), std::addressof(v));
|
|
39
|
-
|
|
40
|
-
if (err < 0)
|
|
41
|
-
{
|
|
42
|
-
// Get positive errno.
|
|
43
|
-
const int error = -err;
|
|
44
|
-
|
|
45
|
-
MS_ABORT("eventfd_read() failed: %s", std::strerror(error));
|
|
46
|
-
};
|
|
47
|
-
|
|
48
|
-
for (unsigned int i{ 0 }; i < count; ++i)
|
|
49
|
-
{
|
|
50
|
-
struct io_uring_cqe* cqe = Cqes[i];
|
|
51
|
-
auto* userData = static_cast<DepLibUring::UserData*>(io_uring_cqe_get_data(cqe));
|
|
52
|
-
|
|
53
|
-
if (liburing->IsZeroCopyEnabled())
|
|
54
|
-
{
|
|
55
|
-
// CQE notification for a zero-copy submission.
|
|
56
|
-
if (cqe->flags & IORING_CQE_F_NOTIF)
|
|
57
|
-
{
|
|
58
|
-
// The send buffer is now in the network card, run the send callback.
|
|
59
|
-
if (userData->cb)
|
|
60
|
-
{
|
|
61
|
-
(*userData->cb)(true);
|
|
62
|
-
delete userData->cb;
|
|
63
|
-
userData->cb = nullptr;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
liburing->ReleaseUserDataEntry(userData->idx);
|
|
67
|
-
io_uring_cqe_seen(liburing->GetRing(), cqe);
|
|
68
|
-
|
|
69
|
-
continue;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
// CQE for a zero-copy submission, a CQE notification will follow.
|
|
73
|
-
if (cqe->flags & IORING_CQE_F_MORE)
|
|
74
|
-
{
|
|
75
|
-
if (cqe->res < 0)
|
|
76
|
-
{
|
|
77
|
-
if (userData->cb)
|
|
78
|
-
{
|
|
79
|
-
(*userData->cb)(false);
|
|
80
|
-
delete userData->cb;
|
|
81
|
-
userData->cb = nullptr;
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
// NOTE: Do not release the user data as it will be done upon reception
|
|
86
|
-
// of CQE notification.
|
|
87
|
-
io_uring_cqe_seen(liburing->GetRing(), cqe);
|
|
88
|
-
|
|
89
|
-
continue;
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
// Successfull SQE.
|
|
94
|
-
if (cqe->res >= 0)
|
|
95
|
-
{
|
|
96
|
-
if (userData->cb)
|
|
97
|
-
{
|
|
98
|
-
(*userData->cb)(true);
|
|
99
|
-
delete userData->cb;
|
|
100
|
-
userData->cb = nullptr;
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
// Failed SQE.
|
|
104
|
-
else
|
|
105
|
-
{
|
|
106
|
-
if (userData->cb)
|
|
107
|
-
{
|
|
108
|
-
(*userData->cb)(false);
|
|
109
|
-
delete userData->cb;
|
|
110
|
-
userData->cb = nullptr;
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
liburing->ReleaseUserDataEntry(userData->idx);
|
|
115
|
-
io_uring_cqe_seen(liburing->GetRing(), cqe);
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
/* Static class methods */
|
|
120
|
-
|
|
121
|
-
void DepLibUring::ClassInit()
|
|
122
|
-
{
|
|
123
|
-
const auto mayor = io_uring_major_version();
|
|
124
|
-
const auto minor = io_uring_minor_version();
|
|
125
|
-
|
|
126
|
-
MS_DEBUG_TAG(info, "io_uring version: \"%i.%i\"", mayor, minor);
|
|
127
|
-
|
|
128
|
-
if (Settings::configuration.disableLiburing)
|
|
129
|
-
{
|
|
130
|
-
MS_DEBUG_TAG(info, "io_uring disabled by user settings");
|
|
131
|
-
|
|
132
|
-
return;
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
// This must be called first.
|
|
136
|
-
if (DepLibUring::CheckRuntimeSupport())
|
|
137
|
-
{
|
|
138
|
-
try
|
|
139
|
-
{
|
|
140
|
-
DepLibUring::liburing = new LibUring();
|
|
141
|
-
|
|
142
|
-
MS_DEBUG_TAG(info, "io_uring enabled");
|
|
143
|
-
|
|
144
|
-
DepLibUring::enabled = true;
|
|
145
|
-
}
|
|
146
|
-
catch (const MediaSoupError& error)
|
|
147
|
-
{
|
|
148
|
-
MS_DEBUG_TAG(info, "io_uring initialization failed, io_uring not enabled");
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
else
|
|
152
|
-
{
|
|
153
|
-
MS_DEBUG_TAG(info, "io_uring not enabled");
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
void DepLibUring::ClassDestroy()
|
|
158
|
-
{
|
|
159
|
-
MS_TRACE();
|
|
160
|
-
|
|
161
|
-
delete DepLibUring::liburing;
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
bool DepLibUring::CheckRuntimeSupport()
|
|
165
|
-
{
|
|
166
|
-
struct utsname buffer{};
|
|
167
|
-
|
|
168
|
-
const auto err = uname(std::addressof(buffer));
|
|
169
|
-
|
|
170
|
-
if (err != 0)
|
|
171
|
-
{
|
|
172
|
-
MS_THROW_ERROR("uname() failed: %s", std::strerror(err));
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
MS_DEBUG_TAG(info, "kernel version: %s", buffer.version);
|
|
176
|
-
|
|
177
|
-
auto* kernelMayorCstr = buffer.release;
|
|
178
|
-
auto kernelMayorLong = strtol(kernelMayorCstr, &kernelMayorCstr, 10);
|
|
179
|
-
|
|
180
|
-
// liburing `sento` capabilities are supported for kernel versions greather
|
|
181
|
-
// than or equal to 6.
|
|
182
|
-
if (kernelMayorLong < 6)
|
|
183
|
-
{
|
|
184
|
-
MS_DEBUG_TAG(info, "kernel doesn't support io_uring");
|
|
185
|
-
|
|
186
|
-
return false;
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
return true;
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
bool DepLibUring::IsEnabled()
|
|
193
|
-
{
|
|
194
|
-
return DepLibUring::enabled;
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
flatbuffers::Offset<FBS::LibUring::Dump> DepLibUring::FillBuffer(flatbuffers::FlatBufferBuilder& builder)
|
|
198
|
-
{
|
|
199
|
-
MS_TRACE();
|
|
200
|
-
|
|
201
|
-
MS_ASSERT(DepLibUring::enabled, "io_uring not enabled");
|
|
202
|
-
|
|
203
|
-
return DepLibUring::liburing->FillBuffer(builder);
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
void DepLibUring::StartPollingCQEs()
|
|
207
|
-
{
|
|
208
|
-
MS_TRACE();
|
|
209
|
-
|
|
210
|
-
MS_ASSERT(DepLibUring::enabled, "io_uring not enabled");
|
|
211
|
-
|
|
212
|
-
DepLibUring::liburing->StartPollingCQEs();
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
void DepLibUring::StopPollingCQEs()
|
|
216
|
-
{
|
|
217
|
-
MS_TRACE();
|
|
218
|
-
|
|
219
|
-
MS_ASSERT(DepLibUring::enabled, "io_uring not enabled");
|
|
220
|
-
|
|
221
|
-
DepLibUring::liburing->StopPollingCQEs();
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
uint8_t* DepLibUring::GetSendBuffer()
|
|
225
|
-
{
|
|
226
|
-
MS_TRACE();
|
|
227
|
-
|
|
228
|
-
MS_ASSERT(DepLibUring::enabled, "io_uring not enabled");
|
|
229
|
-
|
|
230
|
-
return DepLibUring::liburing->GetSendBuffer();
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
bool DepLibUring::PrepareSend(
|
|
234
|
-
int sockfd, const uint8_t* data, size_t len, const struct sockaddr* addr, onSendCallback* cb)
|
|
235
|
-
{
|
|
236
|
-
MS_TRACE();
|
|
237
|
-
|
|
238
|
-
MS_ASSERT(DepLibUring::enabled, "io_uring not enabled");
|
|
239
|
-
|
|
240
|
-
return DepLibUring::liburing->PrepareSend(sockfd, data, len, addr, cb);
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
bool DepLibUring::PrepareWrite(
|
|
244
|
-
int sockfd, const uint8_t* data1, size_t len1, const uint8_t* data2, size_t len2, onSendCallback* cb)
|
|
245
|
-
{
|
|
246
|
-
MS_TRACE();
|
|
247
|
-
|
|
248
|
-
MS_ASSERT(DepLibUring::enabled, "io_uring not enabled");
|
|
249
|
-
|
|
250
|
-
return DepLibUring::liburing->PrepareWrite(sockfd, data1, len1, data2, len2, cb);
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
void DepLibUring::Submit()
|
|
254
|
-
{
|
|
255
|
-
MS_TRACE();
|
|
256
|
-
|
|
257
|
-
MS_ASSERT(DepLibUring::enabled, "io_uring not enabled");
|
|
258
|
-
|
|
259
|
-
DepLibUring::liburing->Submit();
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
void DepLibUring::SetActive()
|
|
263
|
-
{
|
|
264
|
-
MS_TRACE();
|
|
265
|
-
|
|
266
|
-
MS_ASSERT(DepLibUring::enabled, "io_uring not enabled");
|
|
267
|
-
|
|
268
|
-
DepLibUring::liburing->SetActive();
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
bool DepLibUring::IsActive()
|
|
272
|
-
{
|
|
273
|
-
MS_TRACE();
|
|
274
|
-
|
|
275
|
-
MS_ASSERT(DepLibUring::enabled, "io_uring not enabled");
|
|
276
|
-
|
|
277
|
-
return DepLibUring::liburing->IsActive();
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
/* Instance methods. */
|
|
281
|
-
|
|
282
|
-
DepLibUring::LibUring::LibUring()
|
|
283
|
-
{
|
|
284
|
-
MS_TRACE();
|
|
285
|
-
|
|
286
|
-
/**
|
|
287
|
-
* IORING_SETUP_SINGLE_ISSUER: A hint to the kernel that only a single task
|
|
288
|
-
* (or thread) will submit requests, which is used for internal optimisations.
|
|
289
|
-
*/
|
|
290
|
-
|
|
291
|
-
const unsigned int flags = IORING_SETUP_SINGLE_ISSUER;
|
|
292
|
-
|
|
293
|
-
// Initialize io_uring.
|
|
294
|
-
auto err = io_uring_queue_init(DepLibUring::QueueDepth, std::addressof(this->ring), flags);
|
|
295
|
-
|
|
296
|
-
if (err < 0)
|
|
297
|
-
{
|
|
298
|
-
// Get positive errno.
|
|
299
|
-
const int error = -err;
|
|
300
|
-
|
|
301
|
-
MS_THROW_ERROR("io_uring_queue_init() failed: %s", std::strerror(error));
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
// Create an eventfd instance.
|
|
305
|
-
this->efd = eventfd(0, 0);
|
|
306
|
-
|
|
307
|
-
if (this->efd < 0)
|
|
308
|
-
{
|
|
309
|
-
MS_THROW_ERROR("eventfd() failed: %s", std::strerror(-this->efd));
|
|
310
|
-
}
|
|
311
|
-
|
|
312
|
-
err = io_uring_register_eventfd(std::addressof(this->ring), this->efd);
|
|
313
|
-
|
|
314
|
-
if (err < 0)
|
|
315
|
-
{
|
|
316
|
-
// Get positive errno.
|
|
317
|
-
const int error = -err;
|
|
318
|
-
|
|
319
|
-
MS_THROW_ERROR("io_uring_register_eventfd() failed: %s", std::strerror(error));
|
|
320
|
-
}
|
|
321
|
-
|
|
322
|
-
// Initialize available UserData entries.
|
|
323
|
-
for (size_t i{ 0 }; i < DepLibUring::QueueDepth; ++i)
|
|
324
|
-
{
|
|
325
|
-
this->userDatas[i].store = this->sendBuffers[i];
|
|
326
|
-
this->availableUserDataEntries.push(i);
|
|
327
|
-
}
|
|
328
|
-
|
|
329
|
-
// Initialize iovecs.
|
|
330
|
-
for (size_t i{ 0 }; i < DepLibUring::QueueDepth; ++i)
|
|
331
|
-
{
|
|
332
|
-
this->iovecs[i].iov_base = this->sendBuffers[i];
|
|
333
|
-
this->iovecs[i].iov_len = DepLibUring::SendBufferSize;
|
|
334
|
-
}
|
|
335
|
-
|
|
336
|
-
err = io_uring_register_buffers(std::addressof(this->ring), this->iovecs, DepLibUring::QueueDepth);
|
|
337
|
-
|
|
338
|
-
if (err < 0)
|
|
339
|
-
{
|
|
340
|
-
// Get positive errno.
|
|
341
|
-
const int error = -err;
|
|
342
|
-
|
|
343
|
-
if (error == ENOMEM)
|
|
344
|
-
{
|
|
345
|
-
this->zeroCopyEnabled = false;
|
|
346
|
-
|
|
347
|
-
struct rlimit l = {};
|
|
348
|
-
|
|
349
|
-
if (getrlimit(RLIMIT_MEMLOCK, std::addressof(l)) == -1)
|
|
350
|
-
{
|
|
351
|
-
MS_WARN_TAG(info, "getrlimit() failed: %s", std::strerror(errno));
|
|
352
|
-
MS_WARN_TAG(
|
|
353
|
-
info,
|
|
354
|
-
"io_uring_register_buffers() failed due to low RLIMIT_MEMLOCK, disabling zero copy: %s",
|
|
355
|
-
std::strerror(error));
|
|
356
|
-
}
|
|
357
|
-
else
|
|
358
|
-
{
|
|
359
|
-
MS_WARN_TAG(
|
|
360
|
-
info,
|
|
361
|
-
"io_uring_register_buffers() failed due to low RLIMIT_MEMLOCK (soft:%llu, hard:%llu), disabling zero copy: %s",
|
|
362
|
-
static_cast<unsigned long long>(l.rlim_cur),
|
|
363
|
-
static_cast<unsigned long long>(l.rlim_max),
|
|
364
|
-
std::strerror(error));
|
|
365
|
-
}
|
|
366
|
-
}
|
|
367
|
-
else
|
|
368
|
-
{
|
|
369
|
-
MS_THROW_ERROR("io_uring_register_buffers() failed: %s", std::strerror(error));
|
|
370
|
-
}
|
|
371
|
-
}
|
|
372
|
-
}
|
|
373
|
-
|
|
374
|
-
DepLibUring::LibUring::~LibUring()
|
|
375
|
-
{
|
|
376
|
-
MS_TRACE();
|
|
377
|
-
|
|
378
|
-
// Close the event file descriptor.
|
|
379
|
-
const auto err = close(this->efd);
|
|
380
|
-
|
|
381
|
-
if (err != 0)
|
|
382
|
-
{
|
|
383
|
-
// Get positive errno.
|
|
384
|
-
const int error = -err;
|
|
385
|
-
|
|
386
|
-
try
|
|
387
|
-
{
|
|
388
|
-
MS_ABORT("close() failed: %s", std::strerror(error));
|
|
389
|
-
}
|
|
390
|
-
catch (const std::exception& error) // NOLINT(bugprone-empty-catch)
|
|
391
|
-
{
|
|
392
|
-
// NOTE: This is to avoid a warning:
|
|
393
|
-
// warning: ‘throw’ will always call ‘terminate’ [-Wterminate]
|
|
394
|
-
}
|
|
395
|
-
}
|
|
396
|
-
|
|
397
|
-
// Close the ring.
|
|
398
|
-
io_uring_queue_exit(std::addressof(this->ring));
|
|
399
|
-
}
|
|
400
|
-
|
|
401
|
-
flatbuffers::Offset<FBS::LibUring::Dump> DepLibUring::LibUring::FillBuffer(
|
|
402
|
-
flatbuffers::FlatBufferBuilder& builder) const
|
|
403
|
-
{
|
|
404
|
-
MS_TRACE();
|
|
405
|
-
|
|
406
|
-
return FBS::LibUring::CreateDump(
|
|
407
|
-
builder, this->sqeProcessCount, this->sqeMissCount, this->userDataMissCount);
|
|
408
|
-
}
|
|
409
|
-
|
|
410
|
-
void DepLibUring::LibUring::StartPollingCQEs()
|
|
411
|
-
{
|
|
412
|
-
MS_TRACE();
|
|
413
|
-
|
|
414
|
-
// Watch the event file descriptor for completions.
|
|
415
|
-
this->uvHandle = new uv_poll_t;
|
|
416
|
-
|
|
417
|
-
auto err = uv_poll_init(DepLibUV::GetLoop(), this->uvHandle, this->efd);
|
|
418
|
-
|
|
419
|
-
if (err != 0)
|
|
420
|
-
{
|
|
421
|
-
delete this->uvHandle;
|
|
422
|
-
|
|
423
|
-
MS_THROW_ERROR("uv_poll_init() failed: %s", uv_strerror(err));
|
|
424
|
-
}
|
|
425
|
-
|
|
426
|
-
this->uvHandle->data = this;
|
|
427
|
-
|
|
428
|
-
err = uv_poll_start(this->uvHandle, UV_READABLE, static_cast<uv_poll_cb>(onFdEvent));
|
|
429
|
-
|
|
430
|
-
if (err != 0)
|
|
431
|
-
{
|
|
432
|
-
MS_THROW_ERROR("uv_poll_start() failed: %s", uv_strerror(err));
|
|
433
|
-
}
|
|
434
|
-
}
|
|
435
|
-
|
|
436
|
-
void DepLibUring::LibUring::StopPollingCQEs()
|
|
437
|
-
{
|
|
438
|
-
MS_TRACE();
|
|
439
|
-
|
|
440
|
-
this->uvHandle->data = nullptr;
|
|
441
|
-
|
|
442
|
-
// Stop polling the event file descriptor.
|
|
443
|
-
const auto err = uv_poll_stop(this->uvHandle);
|
|
444
|
-
|
|
445
|
-
if (err != 0)
|
|
446
|
-
{
|
|
447
|
-
MS_ABORT("uv_poll_stop() failed: %s", uv_strerror(err));
|
|
448
|
-
}
|
|
449
|
-
|
|
450
|
-
// NOTE: Handles that wrap file descriptors are clossed immediately.
|
|
451
|
-
uv_close(reinterpret_cast<uv_handle_t*>(this->uvHandle), static_cast<uv_close_cb>(onCloseFd));
|
|
452
|
-
}
|
|
453
|
-
|
|
454
|
-
uint8_t* DepLibUring::LibUring::GetSendBuffer()
|
|
455
|
-
{
|
|
456
|
-
MS_TRACE();
|
|
457
|
-
|
|
458
|
-
if (this->availableUserDataEntries.empty())
|
|
459
|
-
{
|
|
460
|
-
MS_DEBUG_DEV("no user data entry available");
|
|
461
|
-
|
|
462
|
-
return nullptr;
|
|
463
|
-
}
|
|
464
|
-
|
|
465
|
-
auto idx = this->availableUserDataEntries.front();
|
|
466
|
-
|
|
467
|
-
return this->userDatas[idx].store;
|
|
468
|
-
}
|
|
469
|
-
|
|
470
|
-
bool DepLibUring::LibUring::PrepareSend(
|
|
471
|
-
int sockfd, const uint8_t* data, size_t len, const struct sockaddr* addr, onSendCallback* cb)
|
|
472
|
-
{
|
|
473
|
-
MS_TRACE();
|
|
474
|
-
|
|
475
|
-
auto* userData = this->GetUserData();
|
|
476
|
-
|
|
477
|
-
if (!userData)
|
|
478
|
-
{
|
|
479
|
-
MS_DEBUG_DEV("no user data entry available");
|
|
480
|
-
|
|
481
|
-
this->userDataMissCount++;
|
|
482
|
-
|
|
483
|
-
return false;
|
|
484
|
-
}
|
|
485
|
-
|
|
486
|
-
auto* sqe = io_uring_get_sqe(std::addressof(this->ring));
|
|
487
|
-
|
|
488
|
-
if (!sqe)
|
|
489
|
-
{
|
|
490
|
-
MS_DEBUG_DEV("no sqe available");
|
|
491
|
-
|
|
492
|
-
this->sqeMissCount++;
|
|
493
|
-
|
|
494
|
-
return false;
|
|
495
|
-
}
|
|
496
|
-
|
|
497
|
-
// The send data buffer belongs to us, no need to memcpy.
|
|
498
|
-
if (this->IsDataInSendBuffers(data))
|
|
499
|
-
{
|
|
500
|
-
MS_ASSERT(data == userData->store, "send buffer does not match userData store");
|
|
501
|
-
}
|
|
502
|
-
else
|
|
503
|
-
{
|
|
504
|
-
std::memcpy(userData->store, data, len);
|
|
505
|
-
}
|
|
506
|
-
|
|
507
|
-
userData->cb = cb;
|
|
508
|
-
|
|
509
|
-
io_uring_sqe_set_data(sqe, userData);
|
|
510
|
-
|
|
511
|
-
const socklen_t addrlen = Utils::IP::GetAddressLen(addr);
|
|
512
|
-
|
|
513
|
-
if (this->zeroCopyEnabled)
|
|
514
|
-
{
|
|
515
|
-
auto iovec = this->iovecs[userData->idx];
|
|
516
|
-
iovec.iov_len = len;
|
|
517
|
-
|
|
518
|
-
io_uring_prep_send_zc(sqe, sockfd, iovec.iov_base, iovec.iov_len, 0, 0);
|
|
519
|
-
io_uring_prep_send_set_addr(sqe, addr, addrlen);
|
|
520
|
-
|
|
521
|
-
// Tell io_uring that we are providing the already registered send buffer
|
|
522
|
-
// for zero copy.
|
|
523
|
-
sqe->ioprio |= IORING_RECVSEND_FIXED_BUF;
|
|
524
|
-
sqe->buf_index = userData->idx;
|
|
525
|
-
}
|
|
526
|
-
else
|
|
527
|
-
{
|
|
528
|
-
io_uring_prep_sendto(sqe, sockfd, userData->store, len, 0, addr, addrlen);
|
|
529
|
-
}
|
|
530
|
-
|
|
531
|
-
this->sqeProcessCount++;
|
|
532
|
-
|
|
533
|
-
return true;
|
|
534
|
-
}
|
|
535
|
-
|
|
536
|
-
bool DepLibUring::LibUring::PrepareWrite(
|
|
537
|
-
int sockfd, const uint8_t* data1, size_t len1, const uint8_t* data2, size_t len2, onSendCallback* cb)
|
|
538
|
-
{
|
|
539
|
-
MS_TRACE();
|
|
540
|
-
|
|
541
|
-
auto* userData = this->GetUserData();
|
|
542
|
-
|
|
543
|
-
if (!userData)
|
|
544
|
-
{
|
|
545
|
-
MS_DEBUG_DEV("no user data entry available");
|
|
546
|
-
|
|
547
|
-
this->userDataMissCount++;
|
|
548
|
-
|
|
549
|
-
return false;
|
|
550
|
-
}
|
|
551
|
-
|
|
552
|
-
auto* sqe = io_uring_get_sqe(std::addressof(this->ring));
|
|
553
|
-
|
|
554
|
-
if (!sqe)
|
|
555
|
-
{
|
|
556
|
-
MS_DEBUG_DEV("no sqe available");
|
|
557
|
-
|
|
558
|
-
this->sqeMissCount++;
|
|
559
|
-
|
|
560
|
-
return false;
|
|
561
|
-
}
|
|
562
|
-
|
|
563
|
-
// The send data buffer belongs to us, no need to memcpy.
|
|
564
|
-
// NOTE: data1 contains the TCP framing buffer and data2 the actual payload.
|
|
565
|
-
if (this->IsDataInSendBuffers(data2))
|
|
566
|
-
{
|
|
567
|
-
MS_ASSERT(data2 == userData->store, "send buffer does not match userData store");
|
|
568
|
-
|
|
569
|
-
// Always memcpy the frame len as it resides in the stack memory.
|
|
570
|
-
std::memcpy(userData->frameLen, data1, len1);
|
|
571
|
-
|
|
572
|
-
userData->iov[0].iov_base = userData->frameLen;
|
|
573
|
-
userData->iov[0].iov_len = len1;
|
|
574
|
-
userData->iov[1].iov_base = userData->store;
|
|
575
|
-
userData->iov[1].iov_len = len2;
|
|
576
|
-
}
|
|
577
|
-
else
|
|
578
|
-
{
|
|
579
|
-
std::memcpy(userData->store, data1, len1);
|
|
580
|
-
std::memcpy(userData->store + len1, data2, len2);
|
|
581
|
-
|
|
582
|
-
userData->iov[0].iov_base = userData->store;
|
|
583
|
-
userData->iov[0].iov_len = len1;
|
|
584
|
-
userData->iov[1].iov_base = userData->store + len1;
|
|
585
|
-
userData->iov[1].iov_len = len2;
|
|
586
|
-
}
|
|
587
|
-
|
|
588
|
-
userData->cb = cb;
|
|
589
|
-
|
|
590
|
-
io_uring_sqe_set_data(sqe, userData);
|
|
591
|
-
|
|
592
|
-
io_uring_prep_writev(sqe, sockfd, userData->iov, 2, 0);
|
|
593
|
-
|
|
594
|
-
this->sqeProcessCount++;
|
|
595
|
-
|
|
596
|
-
return true;
|
|
597
|
-
}
|
|
598
|
-
|
|
599
|
-
void DepLibUring::LibUring::Submit()
|
|
600
|
-
{
|
|
601
|
-
MS_TRACE();
|
|
602
|
-
|
|
603
|
-
// Unset active flag.
|
|
604
|
-
SetInactive();
|
|
605
|
-
|
|
606
|
-
const auto err = io_uring_submit(std::addressof(this->ring));
|
|
607
|
-
|
|
608
|
-
if (err >= 0)
|
|
609
|
-
{
|
|
610
|
-
MS_DEBUG_DEV("%i submission queue entries submitted", err);
|
|
611
|
-
}
|
|
612
|
-
else
|
|
613
|
-
{
|
|
614
|
-
// Get positive errno.
|
|
615
|
-
const int error = -err;
|
|
616
|
-
|
|
617
|
-
MS_ERROR("io_uring_submit() failed: %s", std::strerror(error));
|
|
618
|
-
}
|
|
619
|
-
}
|
|
620
|
-
|
|
621
|
-
DepLibUring::UserData* DepLibUring::LibUring::GetUserData()
|
|
622
|
-
{
|
|
623
|
-
MS_TRACE();
|
|
624
|
-
|
|
625
|
-
if (this->availableUserDataEntries.empty())
|
|
626
|
-
{
|
|
627
|
-
return nullptr;
|
|
628
|
-
}
|
|
629
|
-
|
|
630
|
-
auto idx = this->availableUserDataEntries.front();
|
|
631
|
-
|
|
632
|
-
this->availableUserDataEntries.pop();
|
|
633
|
-
|
|
634
|
-
auto* userData = std::addressof(this->userDatas[idx]);
|
|
635
|
-
userData->idx = idx;
|
|
636
|
-
|
|
637
|
-
return userData;
|
|
638
|
-
}
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
[wrap-file]
|
|
2
|
-
directory = liburing-liburing-2.14
|
|
3
|
-
source_url = https://github.com/axboe/liburing/archive/refs/tags/liburing-2.14.tar.gz
|
|
4
|
-
source_filename = liburing-2.14.tar.gz
|
|
5
|
-
source_hash = 5f80964108981c6ad979c735f0b4877d5f49914c2a062f8e88282f26bf61de0c
|
|
6
|
-
source_fallback_url = https://wrapdb.mesonbuild.com/v2/liburing_2.14-1/get_source/liburing-2.14.tar.gz
|
|
7
|
-
patch_filename = liburing_2.14-1_patch.zip
|
|
8
|
-
patch_url = https://wrapdb.mesonbuild.com/v2/liburing_2.14-1/get_patch
|
|
9
|
-
patch_fallback_url = https://github.com/mesonbuild/wrapdb/releases/download/liburing_2.14-1/liburing_2.14-1_patch.zip
|
|
10
|
-
patch_hash = 4d0ba8f507c25c4fb9a31507a5c06d2a6c253822828084a0101e2bea27dba62a
|
|
11
|
-
wrapdb_version = 2.14-1
|
|
12
|
-
|
|
13
|
-
[provide]
|
|
14
|
-
dependency_names = liburing
|