io: store reference to thread information in the QIOTask struct

Currently the struct QIOTaskThreadData is only needed by the worker
thread, but a subsequent patch will need to access it from another
context.

Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
Message-Id: <20190211182442.8542-2-berrange@redhat.com>
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
This commit is contained in:
Daniel P. Berrangé 2019-02-11 18:24:27 +00:00 committed by Marc-André Lureau
parent 68cf36a7ea
commit 52d6cfeca2
1 changed files with 34 additions and 30 deletions

View File

@ -24,6 +24,14 @@
#include "qemu/thread.h"
#include "trace.h"
struct QIOTaskThreadData {
QIOTaskWorker worker;
gpointer opaque;
GDestroyNotify destroy;
GMainContext *context;
};
struct QIOTask {
Object *source;
QIOTaskFunc func;
@ -32,6 +40,7 @@ struct QIOTask {
Error *err;
gpointer result;
GDestroyNotify destroyResult;
struct QIOTaskThreadData *thread;
};
@ -57,6 +66,18 @@ QIOTask *qio_task_new(Object *source,
static void qio_task_free(QIOTask *task)
{
if (task->thread) {
if (task->thread->destroy) {
task->thread->destroy(task->thread->opaque);
}
if (task->thread->context) {
g_main_context_unref(task->thread->context);
}
g_free(task->thread);
}
if (task->destroy) {
task->destroy(task->opaque);
}
@ -72,31 +93,12 @@ static void qio_task_free(QIOTask *task)
}
struct QIOTaskThreadData {
QIOTask *task;
QIOTaskWorker worker;
gpointer opaque;
GDestroyNotify destroy;
GMainContext *context;
};
static gboolean qio_task_thread_result(gpointer opaque)
{
struct QIOTaskThreadData *data = opaque;
QIOTask *task = opaque;
trace_qio_task_thread_result(data->task);
qio_task_complete(data->task);
if (data->destroy) {
data->destroy(data->opaque);
}
if (data->context) {
g_main_context_unref(data->context);
}
g_free(data);
trace_qio_task_thread_result(task);
qio_task_complete(task);
return FALSE;
}
@ -104,22 +106,23 @@ static gboolean qio_task_thread_result(gpointer opaque)
static gpointer qio_task_thread_worker(gpointer opaque)
{
struct QIOTaskThreadData *data = opaque;
QIOTask *task = opaque;
GSource *idle;
trace_qio_task_thread_run(data->task);
data->worker(data->task, data->opaque);
trace_qio_task_thread_run(task);
task->thread->worker(task, task->thread->opaque);
/* We're running in the background thread, and must only
* ever report the task results in the main event loop
* thread. So we schedule an idle callback to report
* the worker results
*/
trace_qio_task_thread_exit(data->task);
trace_qio_task_thread_exit(task);
idle = g_idle_source_new();
g_source_set_callback(idle, qio_task_thread_result, data, NULL);
g_source_attach(idle, data->context);
g_source_set_callback(idle, qio_task_thread_result, task, NULL);
g_source_attach(idle, task->thread->context);
return NULL;
}
@ -138,17 +141,18 @@ void qio_task_run_in_thread(QIOTask *task,
g_main_context_ref(context);
}
data->task = task;
data->worker = worker;
data->opaque = opaque;
data->destroy = destroy;
data->context = context;
task->thread = data;
trace_qio_task_thread_start(task, worker, opaque);
qemu_thread_create(&thread,
"io-task-worker",
qio_task_thread_worker,
data,
task,
QEMU_THREAD_DETACHED);
}