root / hw / 9pfs / virtio-9p-coth.c @ 737e150e
History | View | Annotate | Download (2.2 kB)
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 "fsdev/qemu-fsdev.h" |
16 |
#include "qemu-thread.h" |
17 |
#include "block/coroutine.h" |
18 |
#include "virtio-9p-coth.h" |
19 |
|
20 |
/* v9fs glib thread pool */
|
21 |
static V9fsThPool v9fs_pool;
|
22 |
|
23 |
void co_run_in_worker_bh(void *opaque) |
24 |
{ |
25 |
Coroutine *co = opaque; |
26 |
g_thread_pool_push(v9fs_pool.pool, co, NULL);
|
27 |
} |
28 |
|
29 |
static void v9fs_qemu_process_req_done(void *arg) |
30 |
{ |
31 |
char byte;
|
32 |
ssize_t len; |
33 |
Coroutine *co; |
34 |
|
35 |
do {
|
36 |
len = read(v9fs_pool.rfd, &byte, sizeof(byte));
|
37 |
} while (len == -1 && errno == EINTR); |
38 |
|
39 |
while ((co = g_async_queue_try_pop(v9fs_pool.completed)) != NULL) { |
40 |
qemu_coroutine_enter(co, NULL);
|
41 |
} |
42 |
} |
43 |
|
44 |
static void v9fs_thread_routine(gpointer data, gpointer user_data) |
45 |
{ |
46 |
ssize_t len; |
47 |
char byte = 0; |
48 |
Coroutine *co = data; |
49 |
|
50 |
qemu_coroutine_enter(co, NULL);
|
51 |
|
52 |
g_async_queue_push(v9fs_pool.completed, co); |
53 |
do {
|
54 |
len = write(v9fs_pool.wfd, &byte, sizeof(byte));
|
55 |
} while (len == -1 && errno == EINTR); |
56 |
} |
57 |
|
58 |
int v9fs_init_worker_threads(void) |
59 |
{ |
60 |
int ret = 0; |
61 |
int notifier_fds[2]; |
62 |
V9fsThPool *p = &v9fs_pool; |
63 |
sigset_t set, oldset; |
64 |
|
65 |
sigfillset(&set); |
66 |
/* Leave signal handling to the iothread. */
|
67 |
pthread_sigmask(SIG_SETMASK, &set, &oldset); |
68 |
|
69 |
if (qemu_pipe(notifier_fds) == -1) { |
70 |
ret = -1;
|
71 |
goto err_out;
|
72 |
} |
73 |
p->pool = g_thread_pool_new(v9fs_thread_routine, p, -1, FALSE, NULL); |
74 |
if (!p->pool) {
|
75 |
ret = -1;
|
76 |
goto err_out;
|
77 |
} |
78 |
p->completed = g_async_queue_new(); |
79 |
if (!p->completed) {
|
80 |
/*
|
81 |
* We are going to terminate.
|
82 |
* So don't worry about cleanup
|
83 |
*/
|
84 |
ret = -1;
|
85 |
goto err_out;
|
86 |
} |
87 |
p->rfd = notifier_fds[0];
|
88 |
p->wfd = notifier_fds[1];
|
89 |
|
90 |
fcntl(p->rfd, F_SETFL, O_NONBLOCK); |
91 |
fcntl(p->wfd, F_SETFL, O_NONBLOCK); |
92 |
|
93 |
qemu_set_fd_handler(p->rfd, v9fs_qemu_process_req_done, NULL, NULL); |
94 |
err_out:
|
95 |
pthread_sigmask(SIG_SETMASK, &oldset, NULL);
|
96 |
return ret;
|
97 |
} |