7#include <QtCore/q26numeric.h>
11Q_LOGGING_CATEGORY(lcQIORing,
"qt.core.ioring", QtCriticalMsg)
13QIORing *QIORing::sharedInstance()
15 thread_local QIORing instance;
16 if (!instance.initializeIORing())
21QIORing::QIORing(quint32 submissionQueueSize, quint32 completionQueueSize)
22 : sqEntries(submissionQueueSize), cqEntries(completionQueueSize)
31 finishRequestWithError(request, QFileDevice::ResourceError);
32 addrItMap.remove(&request);
33 return QueuedRequestStatus::CompletedImmediately;
35 if (!lastUnqueuedIterator) {
36 lastUnqueuedIterator.emplace(addrItMap[&request]);
40 auto &it = addrItMap[&request];
41 const auto where = *lastUnqueuedIterator;
42 pendingRequests.splice(where, pendingRequests, it);
43 it =
std::prev(where);
44 lastUnqueuedIterator.emplace(it);
47 qCDebug(lcQIORing) <<
"Trying to submit request" << request.operation()
48 <<
"user data:" <<
std::addressof(request);
51 const bool requestCompleted = !addrItMap.contains(&request);
52 const QueuedRequestStatus requestQueuedState = requestCompleted
53 ? QueuedRequestStatus::CompletedImmediately
54 : QueuedRequestStatus::Pending;
57 if (unstagedRequests == sqEntries && inFlightRequests <= cqEntries) {
59 return requestQueuedState;
61 if (stagePending || unstagedRequests == 0)
62 return requestQueuedState;
65 QMetaObject::invokeMethod(
66 std::addressof(*notifier), [
this] { submitRequests(); }, Qt::QueuedConnection);
67 return requestQueuedState;
72 if (!handle || !addrItMap.contains(handle))
77 while (!deadline.hasExpired() && addrItMap.contains(handle)) {
78 if (!waitForCompletions(deadline))
82 return !addrItMap.contains(handle);
93void QIORing::setFileErrorResult(QIORing::
GenericRequestType &req, QFileDevice::FileError error)
95 invokeOnOp(req, [error](
auto *concreteRequest) {
96 if constexpr (QtPrivate::HasResultMember<
decltype(*concreteRequest)>)
97 setFileErrorResult(*concreteRequest, error);
101void QIORing::finishRequestWithError(QIORing::
GenericRequestType &req, QFileDevice::FileError error)
103 invokeOnOp(req, [error](
auto *concreteRequest) {
104 if constexpr (QtPrivate::HasResultMember<
decltype(*concreteRequest)>)
105 setFileErrorResult(*concreteRequest, error);
106 invokeCallback(*concreteRequest);
110QIORing::ReadWriteStatus QIORing::handleReadCompletion(size_t value, QSpan<std::byte> *destinations,
111 void *voidExtra, SetResultFn setResultFn)
117 setResultFn(qint64(0));
118 return ReadWriteStatus::Finished;
121 const qsizetype bytesRead = q26::saturate_cast<qsizetype>(value);
122 qCDebug(lcQIORing) <<
"Partial read of" << bytesRead <<
"bytes completed";
123 extra->totalProcessed = setResultFn(bytesRead);
126 extra->spanOffset += bytesRead;
127 qCDebug(lcQIORing) <<
"Read operation progress: span" << extra->spanIndex <<
"offset"
128 << extra->spanOffset <<
"of" << destinations[extra->spanIndex].size()
129 <<
"bytes. Total read:" << extra->totalProcessed <<
"bytes";
133 while (extra->spanOffset >= destinations[extra->spanIndex].size()) {
134 extra->spanOffset -= destinations[extra->spanIndex].size();
136 if (++extra->spanIndex == extra->numSpans)
137 return ReadWriteStatus::Finished;
139 return ReadWriteStatus::MoreToDo;
141 setResultFn(q26::saturate_cast<qsizetype>(value));
142 return ReadWriteStatus::Finished;
145QIORing::ReadWriteStatus QIORing::handleWriteCompletion(size_t value,
146 const QSpan<
const std::byte> *sources,
147 void *voidExtra, SetResultFn setResultFn)
150 const qsizetype bytesWritten = q26::saturate_cast<qsizetype>(value);
151 qCDebug(lcQIORing) <<
"Partial write of" << bytesWritten <<
"bytes completed";
152 extra->totalProcessed = setResultFn(bytesWritten);
155 extra->spanOffset += bytesWritten;
156 qCDebug(lcQIORing) <<
"Write operation progress: span" << extra->spanIndex <<
"offset"
157 << extra->spanOffset <<
"of" << sources[extra->spanIndex].size()
158 <<
"bytes. Total written:" << extra->totalProcessed <<
"bytes";
162 while (extra->spanOffset >= sources[extra->spanIndex].size()) {
163 extra->spanOffset -= sources[extra->spanIndex].size();
165 if (++extra->spanIndex == extra->numSpans)
166 return ReadWriteStatus::Finished;
168 return ReadWriteStatus::MoreToDo;
170 setResultFn(q26::saturate_cast<qsizetype>(value));
171 return ReadWriteStatus::Finished;
174void QIORing::finalizeReadWriteCompletion(
GenericRequestType *request, ReadWriteStatus rwstatus)
177 case ReadWriteStatus::Finished:
178 if (request->getExtra<
void>())
179 --ongoingSplitOperations;
181 case ReadWriteStatus::MoreToDo: {
183 auto &it = addrItMap[request];
184 const auto where = lastUnqueuedIterator.value_or(pendingRequests.end());
185 pendingRequests.splice(where, pendingRequests, it);
186 it =
std::prev(where);
187 lastUnqueuedIterator = it;
195#include "moc_qioring_p.cpp"
RequestHandleTag * RequestHandle
Q_CORE_EXPORT bool waitForRequest(RequestHandle handle, QDeadlineTimer deadline=QDeadlineTimer::Forever)
Combined button and popup list for selecting options.
decltype(std::declval< const T & >().result) DetectResult
constexpr bool HasResultMember