qemu/hw/9pfs/virtio-9p-coth.c
<<
>>
Prefs
   1/*
   2 * Virtio 9p backend
   3 *
   4 * Copyright IBM, Corp. 2010
   5 *
   6 * Authors:
   7 *  Harsh Prateek Bora <harsh@linux.vnet.ibm.com>
   8 *  Venkateswararao Jujjuri(JV) <jvrao@linux.vnet.ibm.com>
   9 *
  10 * This work is licensed under the terms of the GNU GPL, version 2.  See
  11 * the COPYING file in the top-level directory.
  12 *
  13 */
  14
  15#include "qemu-char.h"
  16#include "fsdev/qemu-fsdev.h"
  17#include "qemu-thread.h"
  18#include "qemu-coroutine.h"
  19#include "virtio-9p-coth.h"
  20
  21/* v9fs glib thread pool */
  22static V9fsThPool v9fs_pool;
  23
  24void co_run_in_worker_bh(void *opaque)
  25{
  26    Coroutine *co = opaque;
  27    g_thread_pool_push(v9fs_pool.pool, co, NULL);
  28}
  29
  30static void v9fs_qemu_process_req_done(void *arg)
  31{
  32    char byte;
  33    ssize_t len;
  34    Coroutine *co;
  35
  36    do {
  37        len = read(v9fs_pool.rfd, &byte, sizeof(byte));
  38    } while (len == -1 &&  errno == EINTR);
  39
  40    while ((co = g_async_queue_try_pop(v9fs_pool.completed)) != NULL) {
  41        qemu_coroutine_enter(co, NULL);
  42    }
  43}
  44
  45static void v9fs_thread_routine(gpointer data, gpointer user_data)
  46{
  47    ssize_t len;
  48    char byte = 0;
  49    Coroutine *co = data;
  50
  51    qemu_coroutine_enter(co, NULL);
  52
  53    g_async_queue_push(v9fs_pool.completed, co);
  54    do {
  55        len = write(v9fs_pool.wfd, &byte, sizeof(byte));
  56    } while (len == -1 && errno == EINTR);
  57}
  58
  59int v9fs_init_worker_threads(void)
  60{
  61    int ret = 0;
  62    int notifier_fds[2];
  63    V9fsThPool *p = &v9fs_pool;
  64    sigset_t set, oldset;
  65
  66    sigfillset(&set);
  67    /* Leave signal handling to the iothread.  */
  68    pthread_sigmask(SIG_SETMASK, &set, &oldset);
  69
  70    if (qemu_pipe(notifier_fds) == -1) {
  71        ret = -1;
  72        goto err_out;
  73    }
  74    p->pool = g_thread_pool_new(v9fs_thread_routine, p, -1, FALSE, NULL);
  75    if (!p->pool) {
  76        ret = -1;
  77        goto err_out;
  78    }
  79    p->completed = g_async_queue_new();
  80    if (!p->completed) {
  81        /*
  82         * We are going to terminate.
  83         * So don't worry about cleanup
  84         */
  85        ret = -1;
  86        goto err_out;
  87    }
  88    p->rfd = notifier_fds[0];
  89    p->wfd = notifier_fds[1];
  90
  91    fcntl(p->rfd, F_SETFL, O_NONBLOCK);
  92    fcntl(p->wfd, F_SETFL, O_NONBLOCK);
  93
  94    qemu_set_fd_handler(p->rfd, v9fs_qemu_process_req_done, NULL, NULL);
  95err_out:
  96    pthread_sigmask(SIG_SETMASK, &oldset, NULL);
  97    return ret;
  98}
  99