Skip to content

Commit e6b26ad

Browse files
committed
Add macOS backend for QRandomAccessAsyncFile
The backend uses Grand Central Dispatch to perform async IO. One complication is that the GCD APIs do not allow to cancel a signle IO read/write operation, instead it's only possilbe to close the related IO channel. Luckily, it's possible to have multiple IO channels referencing the same file descriptor. As a result, we end up duplicating IO channels for each async operation, which makes the code a bit more complicated. The implementation uses QWaitCondition to make sure that the async operation is completed or canceled before removing the relevant QIOOperation or QRandomAcessAsyncFile instance. Another tricky part was the implementation of flush(). The docs for dispatch_io_barrier claim that it applies to a file descriptor, not a specific channel, and thus acts as a barrier across all channels that share the same file descriptor. However, in practice it does not work! As a result, the patch implements an operation queue, and schedules the barrier operations only when all previous operations are completed. Similarly, no new operations are scheduled until the barrier operation is completed. The same logic is applied to the async open() operations that are also considered to be barrier operations. Fixes: QTBUG-139005 Change-Id: Iac448d9460c64dd18dc3b15fc13d5145895a3c3b Reviewed-by: Fabian Kosmale <[email protected]> Reviewed-by: Mårten Nordheim <[email protected]> Reviewed-by: Tor Arne Vestbø <[email protected]>
1 parent 1336a98 commit e6b26ad

File tree

5 files changed

+860
-24
lines changed

5 files changed

+860
-24
lines changed

src/corelib/CMakeLists.txt

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -577,10 +577,15 @@ if(QT_FEATURE_async_io)
577577
io/qrandomaccessasyncfile.cpp io/qrandomaccessasyncfile_p.h io/qrandomaccessasyncfile_p_p.h
578578
)
579579

580-
# TODO: This should become the last (fallback) condition later.
581-
# We migth also want to rewrite it so that it does not depend on
582-
# QT_FEATURE_future.
583-
if(QT_FEATURE_thread AND QT_FEATURE_future)
580+
if(APPLE)
581+
qt_internal_extend_target(Core
582+
SOURCES
583+
io/qrandomaccessasyncfile_darwin.mm
584+
)
585+
elseif(QT_FEATURE_thread AND QT_FEATURE_future)
586+
# TODO: This should become the last (fallback) condition later.
587+
# We migth also want to rewrite it so that it does not depend on
588+
# QT_FEATURE_future.
584589
qt_internal_extend_target(Core
585590
SOURCES
586591
io/qrandomaccessasyncfile_threadpool.cpp

src/corelib/configure.cmake

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1233,7 +1233,7 @@ qt_feature("openssl-hash" PRIVATE
12331233
qt_feature("async-io" PRIVATE
12341234
LABEL "Async File I/O"
12351235
PURPOSE "Provides support for asynchronous file I/O."
1236-
CONDITION QT_FEATURE_thread AND QT_FEATURE_future
1236+
CONDITION (QT_FEATURE_thread AND QT_FEATURE_future) OR APPLE
12371237
)
12381238

12391239
qt_configure_add_summary_section(NAME "Qt Core")

0 commit comments

Comments
 (0)