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:
parent
68cf36a7ea
commit
52d6cfeca2
64
io/task.c
64
io/task.c
@ -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);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user