]>
Commit | Line | Data |
---|---|---|
39c0564e VJ |
1 | /* |
2 | * Virtio 9p backend | |
3 | * | |
4 | * Copyright IBM, Corp. 2010 | |
5 | * | |
6 | * Authors: | |
7 | * Harsh Prateek Bora <[email protected]> | |
8 | * Venkateswararao Jujjuri(JV) <[email protected]> | |
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 */ | |
22 | static V9fsThPool v9fs_pool; | |
23 | ||
24 | void co_run_in_worker_bh(void *opaque) | |
25 | { | |
26 | Coroutine *co = opaque; | |
27 | g_thread_pool_push(v9fs_pool.pool, co, NULL); | |
28 | } | |
29 | ||
30 | static 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 | ||
45 | static 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 | ||
59 | int 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 | ||
39c0564e VJ |
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); | |
95 | err_out: | |
96 | pthread_sigmask(SIG_SETMASK, &oldset, NULL); | |
97 | return ret; | |
98 | } |