Reputation: 1410
I am using Linux aio (io_submit()
/ io_getevents()
) for file I/O. Since some operations do not have aio equilvalents (open()
, fsync()
, fallocate()
), I use a worker thread that may block without impacting the main thread. My question is, should I add close()
to this list?
All files are opened with O_DIRECT
on XFS, but I am interested in both the general answer to the question, and on the specific answer with regard to my choice of filesystem and open mode.
Note that using a worker thread for close()
is not trivial since close()
is often called in cleanup paths, which aren't good places to launch a worker thread request and wait for it. So I'm hoping that close()
is non-blocking in this scenario.
For this question, "blocking" means waiting on an I/O operation, or on some lock that may only be released when an I/O operation completes, but excluding page fault servicing.
Upvotes: 4
Views: 517
Reputation: 2051
close()
may block on some filesystems. When possible, code should be written as portably as is practical. As such, you should definitely add close()
to the list of calls that are called only from your blocking worker thread.
However, you mention that you often have to call close()
in cleanup paths. If these are cleanup paths that execute at the termination of your application, it may not make as much of a difference even if close()
does block if you call it directly.
Alternatively, what you could do would be to have a queue that is fed to a pool of workers. In glibc AIO
, this is what is done for many calls. When you initialize AIO with aio_init()
, glibc
sets up a queue and a pool of worker threads. Every time an AIO call is made, glibc
simply adds the relevant task and data to the queue. In the background, the worker threads wait on the queue and execute blocking calls and code and then perform any relevant actions.
If you really do have the need for a non-blocking close()
(and other) calls, it may be to your advantage to simply setup a task queue and a thread pool and simply submit specific calls to the queue and have the thread pool execute calls as they come in.
Upvotes: 2