mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-03 07:43:54 -06:00
aio: add aio_context_acquire() and aio_context_release()
It can be useful to run an AioContext from a thread which normally does not "own" the AioContext. For example, request draining can be implemented by acquiring the AioContext and looping aio_poll() until all requests have been completed. The following pattern should work: /* Event loop thread */ while (running) { aio_context_acquire(ctx); aio_poll(ctx, true); aio_context_release(ctx); } /* Another thread */ aio_context_acquire(ctx); bdrv_read(bs, 0x1000, buf, 1); aio_context_release(ctx); This patch implements aio_context_acquire() and aio_context_release(). Note that existing aio_poll() callers do not need to worry about acquiring and releasing - it is only needed when multiple threads will call aio_poll() on the same AioContext. Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
This commit is contained in:
parent
2da61b671e
commit
98563fc3ec
3 changed files with 95 additions and 0 deletions
|
@ -19,6 +19,7 @@
|
|||
#include "qemu/queue.h"
|
||||
#include "qemu/event_notifier.h"
|
||||
#include "qemu/thread.h"
|
||||
#include "qemu/rfifolock.h"
|
||||
#include "qemu/timer.h"
|
||||
|
||||
typedef struct BlockDriverAIOCB BlockDriverAIOCB;
|
||||
|
@ -47,6 +48,9 @@ typedef void IOHandler(void *opaque);
|
|||
struct AioContext {
|
||||
GSource source;
|
||||
|
||||
/* Protects all fields from multi-threaded access */
|
||||
RFifoLock lock;
|
||||
|
||||
/* The list of registered AIO handlers */
|
||||
QLIST_HEAD(, AioHandler) aio_handlers;
|
||||
|
||||
|
@ -104,6 +108,20 @@ void aio_context_ref(AioContext *ctx);
|
|||
*/
|
||||
void aio_context_unref(AioContext *ctx);
|
||||
|
||||
/* Take ownership of the AioContext. If the AioContext will be shared between
|
||||
* threads, a thread must have ownership when calling aio_poll().
|
||||
*
|
||||
* Note that multiple threads calling aio_poll() means timers, BHs, and
|
||||
* callbacks may be invoked from a different thread than they were registered
|
||||
* from. Therefore, code must use AioContext acquire/release or use
|
||||
* fine-grained synchronization to protect shared state if other threads will
|
||||
* be accessing it simultaneously.
|
||||
*/
|
||||
void aio_context_acquire(AioContext *ctx);
|
||||
|
||||
/* Relinquish ownership of the AioContext. */
|
||||
void aio_context_release(AioContext *ctx);
|
||||
|
||||
/**
|
||||
* aio_bh_new: Allocate a new bottom half structure.
|
||||
*
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue