root / ui / vnc-jobs-async.c @ 136be99e
History | View | Annotate | Download (9.1 kB)
1 | bd023f95 | Corentin Chary | /*
|
---|---|---|---|
2 | bd023f95 | Corentin Chary | * QEMU VNC display driver
|
3 | bd023f95 | Corentin Chary | *
|
4 | bd023f95 | Corentin Chary | * Copyright (C) 2006 Anthony Liguori <anthony@codemonkey.ws>
|
5 | bd023f95 | Corentin Chary | * Copyright (C) 2006 Fabrice Bellard
|
6 | bd023f95 | Corentin Chary | * Copyright (C) 2009 Red Hat, Inc
|
7 | bd023f95 | Corentin Chary | * Copyright (C) 2010 Corentin Chary <corentin.chary@gmail.com>
|
8 | bd023f95 | Corentin Chary | *
|
9 | bd023f95 | Corentin Chary | * Permission is hereby granted, free of charge, to any person obtaining a copy
|
10 | bd023f95 | Corentin Chary | * of this software and associated documentation files (the "Software"), to deal
|
11 | bd023f95 | Corentin Chary | * in the Software without restriction, including without limitation the rights
|
12 | bd023f95 | Corentin Chary | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
13 | bd023f95 | Corentin Chary | * copies of the Software, and to permit persons to whom the Software is
|
14 | bd023f95 | Corentin Chary | * furnished to do so, subject to the following conditions:
|
15 | bd023f95 | Corentin Chary | *
|
16 | bd023f95 | Corentin Chary | * The above copyright notice and this permission notice shall be included in
|
17 | bd023f95 | Corentin Chary | * all copies or substantial portions of the Software.
|
18 | bd023f95 | Corentin Chary | *
|
19 | bd023f95 | Corentin Chary | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
20 | bd023f95 | Corentin Chary | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
21 | bd023f95 | Corentin Chary | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
22 | bd023f95 | Corentin Chary | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
23 | bd023f95 | Corentin Chary | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
24 | bd023f95 | Corentin Chary | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
25 | bd023f95 | Corentin Chary | * THE SOFTWARE.
|
26 | bd023f95 | Corentin Chary | */
|
27 | bd023f95 | Corentin Chary | |
28 | bd023f95 | Corentin Chary | |
29 | bd023f95 | Corentin Chary | #include "vnc.h" |
30 | bd023f95 | Corentin Chary | #include "vnc-jobs.h" |
31 | 175b2a6e | Corentin Chary | #include "qemu_socket.h" |
32 | bd023f95 | Corentin Chary | |
33 | bd023f95 | Corentin Chary | /*
|
34 | bd023f95 | Corentin Chary | * Locking:
|
35 | bd023f95 | Corentin Chary | *
|
36 | bd023f95 | Corentin Chary | * There is three levels of locking:
|
37 | bd023f95 | Corentin Chary | * - jobs queue lock: for each operation on the queue (push, pop, isEmpty?)
|
38 | bd023f95 | Corentin Chary | * - VncDisplay global lock: mainly used for framebuffer updates to avoid
|
39 | bd023f95 | Corentin Chary | * screen corruption if the framebuffer is updated
|
40 | bd023f95 | Corentin Chary | * while the worker is doing something.
|
41 | bd023f95 | Corentin Chary | * - VncState::output lock: used to make sure the output buffer is not corrupted
|
42 | bd023f95 | Corentin Chary | * if two threads try to write on it at the same time
|
43 | bd023f95 | Corentin Chary | *
|
44 | bd023f95 | Corentin Chary | * While the VNC worker thread is working, the VncDisplay global lock is hold
|
45 | bd023f95 | Corentin Chary | * to avoid screen corruptions (this does not block vnc_refresh() because it
|
46 | bd023f95 | Corentin Chary | * uses trylock()) but the output lock is not hold because the thread work on
|
47 | bd023f95 | Corentin Chary | * its own output buffer.
|
48 | bd023f95 | Corentin Chary | * When the encoding job is done, the worker thread will hold the output lock
|
49 | bd023f95 | Corentin Chary | * and copy its output buffer in vs->output.
|
50 | bd023f95 | Corentin Chary | */
|
51 | bd023f95 | Corentin Chary | |
52 | bd023f95 | Corentin Chary | struct VncJobQueue {
|
53 | bd023f95 | Corentin Chary | QemuCond cond; |
54 | bd023f95 | Corentin Chary | QemuMutex mutex; |
55 | bd023f95 | Corentin Chary | QemuThread thread; |
56 | bd023f95 | Corentin Chary | Buffer buffer; |
57 | bd023f95 | Corentin Chary | bool exit;
|
58 | bd023f95 | Corentin Chary | QTAILQ_HEAD(, VncJob) jobs; |
59 | bd023f95 | Corentin Chary | }; |
60 | bd023f95 | Corentin Chary | |
61 | bd023f95 | Corentin Chary | typedef struct VncJobQueue VncJobQueue; |
62 | bd023f95 | Corentin Chary | |
63 | bd023f95 | Corentin Chary | /*
|
64 | bd023f95 | Corentin Chary | * We use a single global queue, but most of the functions are
|
65 | bd023f95 | Corentin Chary | * already reetrant, so we can easilly add more than one encoding thread
|
66 | bd023f95 | Corentin Chary | */
|
67 | bd023f95 | Corentin Chary | static VncJobQueue *queue;
|
68 | bd023f95 | Corentin Chary | |
69 | bd023f95 | Corentin Chary | static void vnc_lock_queue(VncJobQueue *queue) |
70 | bd023f95 | Corentin Chary | { |
71 | bd023f95 | Corentin Chary | qemu_mutex_lock(&queue->mutex); |
72 | bd023f95 | Corentin Chary | } |
73 | bd023f95 | Corentin Chary | |
74 | bd023f95 | Corentin Chary | static void vnc_unlock_queue(VncJobQueue *queue) |
75 | bd023f95 | Corentin Chary | { |
76 | bd023f95 | Corentin Chary | qemu_mutex_unlock(&queue->mutex); |
77 | bd023f95 | Corentin Chary | } |
78 | bd023f95 | Corentin Chary | |
79 | bd023f95 | Corentin Chary | VncJob *vnc_job_new(VncState *vs) |
80 | bd023f95 | Corentin Chary | { |
81 | 7267c094 | Anthony Liguori | VncJob *job = g_malloc0(sizeof(VncJob));
|
82 | bd023f95 | Corentin Chary | |
83 | bd023f95 | Corentin Chary | job->vs = vs; |
84 | bd023f95 | Corentin Chary | vnc_lock_queue(queue); |
85 | bd023f95 | Corentin Chary | QLIST_INIT(&job->rectangles); |
86 | bd023f95 | Corentin Chary | vnc_unlock_queue(queue); |
87 | bd023f95 | Corentin Chary | return job;
|
88 | bd023f95 | Corentin Chary | } |
89 | bd023f95 | Corentin Chary | |
90 | bd023f95 | Corentin Chary | int vnc_job_add_rect(VncJob *job, int x, int y, int w, int h) |
91 | bd023f95 | Corentin Chary | { |
92 | 7267c094 | Anthony Liguori | VncRectEntry *entry = g_malloc0(sizeof(VncRectEntry));
|
93 | bd023f95 | Corentin Chary | |
94 | bd023f95 | Corentin Chary | entry->rect.x = x; |
95 | bd023f95 | Corentin Chary | entry->rect.y = y; |
96 | bd023f95 | Corentin Chary | entry->rect.w = w; |
97 | bd023f95 | Corentin Chary | entry->rect.h = h; |
98 | bd023f95 | Corentin Chary | |
99 | bd023f95 | Corentin Chary | vnc_lock_queue(queue); |
100 | bd023f95 | Corentin Chary | QLIST_INSERT_HEAD(&job->rectangles, entry, next); |
101 | bd023f95 | Corentin Chary | vnc_unlock_queue(queue); |
102 | bd023f95 | Corentin Chary | return 1; |
103 | bd023f95 | Corentin Chary | } |
104 | bd023f95 | Corentin Chary | |
105 | bd023f95 | Corentin Chary | void vnc_job_push(VncJob *job)
|
106 | bd023f95 | Corentin Chary | { |
107 | bd023f95 | Corentin Chary | vnc_lock_queue(queue); |
108 | bd023f95 | Corentin Chary | if (queue->exit || QLIST_EMPTY(&job->rectangles)) {
|
109 | 7267c094 | Anthony Liguori | g_free(job); |
110 | bd023f95 | Corentin Chary | } else {
|
111 | bd023f95 | Corentin Chary | QTAILQ_INSERT_TAIL(&queue->jobs, job, next); |
112 | bd023f95 | Corentin Chary | qemu_cond_broadcast(&queue->cond); |
113 | bd023f95 | Corentin Chary | } |
114 | bd023f95 | Corentin Chary | vnc_unlock_queue(queue); |
115 | bd023f95 | Corentin Chary | } |
116 | bd023f95 | Corentin Chary | |
117 | bd023f95 | Corentin Chary | static bool vnc_has_job_locked(VncState *vs) |
118 | bd023f95 | Corentin Chary | { |
119 | bd023f95 | Corentin Chary | VncJob *job; |
120 | bd023f95 | Corentin Chary | |
121 | bd023f95 | Corentin Chary | QTAILQ_FOREACH(job, &queue->jobs, next) { |
122 | bd023f95 | Corentin Chary | if (job->vs == vs || !vs) {
|
123 | bd023f95 | Corentin Chary | return true; |
124 | bd023f95 | Corentin Chary | } |
125 | bd023f95 | Corentin Chary | } |
126 | bd023f95 | Corentin Chary | return false; |
127 | bd023f95 | Corentin Chary | } |
128 | bd023f95 | Corentin Chary | |
129 | bd023f95 | Corentin Chary | bool vnc_has_job(VncState *vs)
|
130 | bd023f95 | Corentin Chary | { |
131 | bd023f95 | Corentin Chary | bool ret;
|
132 | bd023f95 | Corentin Chary | |
133 | bd023f95 | Corentin Chary | vnc_lock_queue(queue); |
134 | bd023f95 | Corentin Chary | ret = vnc_has_job_locked(vs); |
135 | bd023f95 | Corentin Chary | vnc_unlock_queue(queue); |
136 | bd023f95 | Corentin Chary | return ret;
|
137 | bd023f95 | Corentin Chary | } |
138 | bd023f95 | Corentin Chary | |
139 | bd023f95 | Corentin Chary | void vnc_jobs_clear(VncState *vs)
|
140 | bd023f95 | Corentin Chary | { |
141 | bd023f95 | Corentin Chary | VncJob *job, *tmp; |
142 | bd023f95 | Corentin Chary | |
143 | bd023f95 | Corentin Chary | vnc_lock_queue(queue); |
144 | bd023f95 | Corentin Chary | QTAILQ_FOREACH_SAFE(job, &queue->jobs, next, tmp) { |
145 | bd023f95 | Corentin Chary | if (job->vs == vs || !vs) {
|
146 | bd023f95 | Corentin Chary | QTAILQ_REMOVE(&queue->jobs, job, next); |
147 | bd023f95 | Corentin Chary | } |
148 | bd023f95 | Corentin Chary | } |
149 | bd023f95 | Corentin Chary | vnc_unlock_queue(queue); |
150 | bd023f95 | Corentin Chary | } |
151 | bd023f95 | Corentin Chary | |
152 | bd023f95 | Corentin Chary | void vnc_jobs_join(VncState *vs)
|
153 | bd023f95 | Corentin Chary | { |
154 | bd023f95 | Corentin Chary | vnc_lock_queue(queue); |
155 | bd023f95 | Corentin Chary | while (vnc_has_job_locked(vs)) {
|
156 | bd023f95 | Corentin Chary | qemu_cond_wait(&queue->cond, &queue->mutex); |
157 | bd023f95 | Corentin Chary | } |
158 | bd023f95 | Corentin Chary | vnc_unlock_queue(queue); |
159 | 175b2a6e | Corentin Chary | vnc_jobs_consume_buffer(vs); |
160 | 175b2a6e | Corentin Chary | } |
161 | 175b2a6e | Corentin Chary | |
162 | 175b2a6e | Corentin Chary | void vnc_jobs_consume_buffer(VncState *vs)
|
163 | 175b2a6e | Corentin Chary | { |
164 | 175b2a6e | Corentin Chary | bool flush;
|
165 | 175b2a6e | Corentin Chary | |
166 | 175b2a6e | Corentin Chary | vnc_lock_output(vs); |
167 | 175b2a6e | Corentin Chary | if (vs->jobs_buffer.offset) {
|
168 | 175b2a6e | Corentin Chary | vnc_write(vs, vs->jobs_buffer.buffer, vs->jobs_buffer.offset); |
169 | 175b2a6e | Corentin Chary | buffer_reset(&vs->jobs_buffer); |
170 | 175b2a6e | Corentin Chary | } |
171 | 175b2a6e | Corentin Chary | flush = vs->csock != -1 && vs->abort != true; |
172 | 175b2a6e | Corentin Chary | vnc_unlock_output(vs); |
173 | 175b2a6e | Corentin Chary | |
174 | 175b2a6e | Corentin Chary | if (flush) {
|
175 | 175b2a6e | Corentin Chary | vnc_flush(vs); |
176 | 175b2a6e | Corentin Chary | } |
177 | bd023f95 | Corentin Chary | } |
178 | bd023f95 | Corentin Chary | |
179 | bd023f95 | Corentin Chary | /*
|
180 | bd023f95 | Corentin Chary | * Copy data for local use
|
181 | bd023f95 | Corentin Chary | */
|
182 | bd023f95 | Corentin Chary | static void vnc_async_encoding_start(VncState *orig, VncState *local) |
183 | bd023f95 | Corentin Chary | { |
184 | bd023f95 | Corentin Chary | local->vnc_encoding = orig->vnc_encoding; |
185 | bd023f95 | Corentin Chary | local->features = orig->features; |
186 | bd023f95 | Corentin Chary | local->ds = orig->ds; |
187 | bd023f95 | Corentin Chary | local->vd = orig->vd; |
188 | 7d964c9d | Corentin Chary | local->lossy_rect = orig->lossy_rect; |
189 | bd023f95 | Corentin Chary | local->write_pixels = orig->write_pixels; |
190 | bd023f95 | Corentin Chary | local->clientds = orig->clientds; |
191 | bd023f95 | Corentin Chary | local->tight = orig->tight; |
192 | bd023f95 | Corentin Chary | local->zlib = orig->zlib; |
193 | bd023f95 | Corentin Chary | local->hextile = orig->hextile; |
194 | 148954fa | Corentin Chary | local->zrle = orig->zrle; |
195 | bd023f95 | Corentin Chary | local->output = queue->buffer; |
196 | bd023f95 | Corentin Chary | local->csock = -1; /* Don't do any network work on this thread */ |
197 | bd023f95 | Corentin Chary | |
198 | bd023f95 | Corentin Chary | buffer_reset(&local->output); |
199 | bd023f95 | Corentin Chary | } |
200 | bd023f95 | Corentin Chary | |
201 | bd023f95 | Corentin Chary | static void vnc_async_encoding_end(VncState *orig, VncState *local) |
202 | bd023f95 | Corentin Chary | { |
203 | bd023f95 | Corentin Chary | orig->tight = local->tight; |
204 | bd023f95 | Corentin Chary | orig->zlib = local->zlib; |
205 | bd023f95 | Corentin Chary | orig->hextile = local->hextile; |
206 | 148954fa | Corentin Chary | orig->zrle = local->zrle; |
207 | 7d964c9d | Corentin Chary | orig->lossy_rect = local->lossy_rect; |
208 | c53af37f | Corentin Chary | |
209 | c53af37f | Corentin Chary | queue->buffer = local->output; |
210 | bd023f95 | Corentin Chary | } |
211 | bd023f95 | Corentin Chary | |
212 | bd023f95 | Corentin Chary | static int vnc_worker_thread_loop(VncJobQueue *queue) |
213 | bd023f95 | Corentin Chary | { |
214 | bd023f95 | Corentin Chary | VncJob *job; |
215 | bd023f95 | Corentin Chary | VncRectEntry *entry, *tmp; |
216 | bd023f95 | Corentin Chary | VncState vs; |
217 | bd023f95 | Corentin Chary | int n_rectangles;
|
218 | bd023f95 | Corentin Chary | int saved_offset;
|
219 | bd023f95 | Corentin Chary | |
220 | bd023f95 | Corentin Chary | vnc_lock_queue(queue); |
221 | bd023f95 | Corentin Chary | while (QTAILQ_EMPTY(&queue->jobs) && !queue->exit) {
|
222 | bd023f95 | Corentin Chary | qemu_cond_wait(&queue->cond, &queue->mutex); |
223 | bd023f95 | Corentin Chary | } |
224 | bd023f95 | Corentin Chary | /* Here job can only be NULL if queue->exit is true */
|
225 | bd023f95 | Corentin Chary | job = QTAILQ_FIRST(&queue->jobs); |
226 | bd023f95 | Corentin Chary | vnc_unlock_queue(queue); |
227 | bd023f95 | Corentin Chary | |
228 | bd023f95 | Corentin Chary | if (queue->exit) {
|
229 | bd023f95 | Corentin Chary | return -1; |
230 | bd023f95 | Corentin Chary | } |
231 | bd023f95 | Corentin Chary | |
232 | bd023f95 | Corentin Chary | vnc_lock_output(job->vs); |
233 | bd023f95 | Corentin Chary | if (job->vs->csock == -1 || job->vs->abort == true) { |
234 | 175b2a6e | Corentin Chary | vnc_unlock_output(job->vs); |
235 | bd023f95 | Corentin Chary | goto disconnected;
|
236 | bd023f95 | Corentin Chary | } |
237 | bd023f95 | Corentin Chary | vnc_unlock_output(job->vs); |
238 | bd023f95 | Corentin Chary | |
239 | bd023f95 | Corentin Chary | /* Make a local copy of vs and switch output buffers */
|
240 | bd023f95 | Corentin Chary | vnc_async_encoding_start(job->vs, &vs); |
241 | bd023f95 | Corentin Chary | |
242 | bd023f95 | Corentin Chary | /* Start sending rectangles */
|
243 | bd023f95 | Corentin Chary | n_rectangles = 0;
|
244 | bd023f95 | Corentin Chary | vnc_write_u8(&vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE); |
245 | bd023f95 | Corentin Chary | vnc_write_u8(&vs, 0);
|
246 | bd023f95 | Corentin Chary | saved_offset = vs.output.offset; |
247 | bd023f95 | Corentin Chary | vnc_write_u16(&vs, 0);
|
248 | bd023f95 | Corentin Chary | |
249 | bd023f95 | Corentin Chary | vnc_lock_display(job->vs->vd); |
250 | bd023f95 | Corentin Chary | QLIST_FOREACH_SAFE(entry, &job->rectangles, next, tmp) { |
251 | bd023f95 | Corentin Chary | int n;
|
252 | bd023f95 | Corentin Chary | |
253 | bd023f95 | Corentin Chary | if (job->vs->csock == -1) { |
254 | bd023f95 | Corentin Chary | vnc_unlock_display(job->vs->vd); |
255 | bd023f95 | Corentin Chary | goto disconnected;
|
256 | bd023f95 | Corentin Chary | } |
257 | bd023f95 | Corentin Chary | |
258 | bd023f95 | Corentin Chary | n = vnc_send_framebuffer_update(&vs, entry->rect.x, entry->rect.y, |
259 | bd023f95 | Corentin Chary | entry->rect.w, entry->rect.h); |
260 | bd023f95 | Corentin Chary | |
261 | bd023f95 | Corentin Chary | if (n >= 0) { |
262 | bd023f95 | Corentin Chary | n_rectangles += n; |
263 | bd023f95 | Corentin Chary | } |
264 | 7267c094 | Anthony Liguori | g_free(entry); |
265 | bd023f95 | Corentin Chary | } |
266 | bd023f95 | Corentin Chary | vnc_unlock_display(job->vs->vd); |
267 | bd023f95 | Corentin Chary | |
268 | bd023f95 | Corentin Chary | /* Put n_rectangles at the beginning of the message */
|
269 | bd023f95 | Corentin Chary | vs.output.buffer[saved_offset] = (n_rectangles >> 8) & 0xFF; |
270 | bd023f95 | Corentin Chary | vs.output.buffer[saved_offset + 1] = n_rectangles & 0xFF; |
271 | bd023f95 | Corentin Chary | |
272 | bd023f95 | Corentin Chary | vnc_lock_output(job->vs); |
273 | 175b2a6e | Corentin Chary | if (job->vs->csock != -1) { |
274 | 175b2a6e | Corentin Chary | buffer_reserve(&job->vs->jobs_buffer, vs.output.offset); |
275 | 175b2a6e | Corentin Chary | buffer_append(&job->vs->jobs_buffer, vs.output.buffer, |
276 | 175b2a6e | Corentin Chary | vs.output.offset); |
277 | 175b2a6e | Corentin Chary | /* Copy persistent encoding data */
|
278 | 175b2a6e | Corentin Chary | vnc_async_encoding_end(job->vs, &vs); |
279 | 175b2a6e | Corentin Chary | |
280 | 175b2a6e | Corentin Chary | qemu_bh_schedule(job->vs->bh); |
281 | bd023f95 | Corentin Chary | } |
282 | bd023f95 | Corentin Chary | vnc_unlock_output(job->vs); |
283 | bd023f95 | Corentin Chary | |
284 | 175b2a6e | Corentin Chary | disconnected:
|
285 | bd023f95 | Corentin Chary | vnc_lock_queue(queue); |
286 | bd023f95 | Corentin Chary | QTAILQ_REMOVE(&queue->jobs, job, next); |
287 | bd023f95 | Corentin Chary | vnc_unlock_queue(queue); |
288 | bd023f95 | Corentin Chary | qemu_cond_broadcast(&queue->cond); |
289 | 7267c094 | Anthony Liguori | g_free(job); |
290 | bd023f95 | Corentin Chary | return 0; |
291 | bd023f95 | Corentin Chary | } |
292 | bd023f95 | Corentin Chary | |
293 | bd023f95 | Corentin Chary | static VncJobQueue *vnc_queue_init(void) |
294 | bd023f95 | Corentin Chary | { |
295 | 7267c094 | Anthony Liguori | VncJobQueue *queue = g_malloc0(sizeof(VncJobQueue));
|
296 | bd023f95 | Corentin Chary | |
297 | bd023f95 | Corentin Chary | qemu_cond_init(&queue->cond); |
298 | bd023f95 | Corentin Chary | qemu_mutex_init(&queue->mutex); |
299 | bd023f95 | Corentin Chary | QTAILQ_INIT(&queue->jobs); |
300 | bd023f95 | Corentin Chary | return queue;
|
301 | bd023f95 | Corentin Chary | } |
302 | bd023f95 | Corentin Chary | |
303 | bd023f95 | Corentin Chary | static void vnc_queue_clear(VncJobQueue *q) |
304 | bd023f95 | Corentin Chary | { |
305 | bd023f95 | Corentin Chary | qemu_cond_destroy(&queue->cond); |
306 | bd023f95 | Corentin Chary | qemu_mutex_destroy(&queue->mutex); |
307 | bd023f95 | Corentin Chary | buffer_free(&queue->buffer); |
308 | 7267c094 | Anthony Liguori | g_free(q); |
309 | bd023f95 | Corentin Chary | queue = NULL; /* Unset global queue */ |
310 | bd023f95 | Corentin Chary | } |
311 | bd023f95 | Corentin Chary | |
312 | bd023f95 | Corentin Chary | static void *vnc_worker_thread(void *arg) |
313 | bd023f95 | Corentin Chary | { |
314 | bd023f95 | Corentin Chary | VncJobQueue *queue = arg; |
315 | bd023f95 | Corentin Chary | |
316 | b7680cb6 | Jan Kiszka | qemu_thread_get_self(&queue->thread); |
317 | bd023f95 | Corentin Chary | |
318 | bd023f95 | Corentin Chary | while (!vnc_worker_thread_loop(queue)) ;
|
319 | bd023f95 | Corentin Chary | vnc_queue_clear(queue); |
320 | bd023f95 | Corentin Chary | return NULL; |
321 | bd023f95 | Corentin Chary | } |
322 | bd023f95 | Corentin Chary | |
323 | bd023f95 | Corentin Chary | void vnc_start_worker_thread(void) |
324 | bd023f95 | Corentin Chary | { |
325 | bd023f95 | Corentin Chary | VncJobQueue *q; |
326 | bd023f95 | Corentin Chary | |
327 | bd023f95 | Corentin Chary | if (vnc_worker_thread_running())
|
328 | bd023f95 | Corentin Chary | return ;
|
329 | bd023f95 | Corentin Chary | |
330 | bd023f95 | Corentin Chary | q = vnc_queue_init(); |
331 | cf218714 | Jan Kiszka | qemu_thread_create(&q->thread, vnc_worker_thread, q, QEMU_THREAD_DETACHED); |
332 | bd023f95 | Corentin Chary | queue = q; /* Set global queue */
|
333 | bd023f95 | Corentin Chary | } |
334 | bd023f95 | Corentin Chary | |
335 | bd023f95 | Corentin Chary | bool vnc_worker_thread_running(void) |
336 | bd023f95 | Corentin Chary | { |
337 | bd023f95 | Corentin Chary | return queue; /* Check global queue */ |
338 | bd023f95 | Corentin Chary | } |
339 | bd023f95 | Corentin Chary | |
340 | bd023f95 | Corentin Chary | void vnc_stop_worker_thread(void) |
341 | bd023f95 | Corentin Chary | { |
342 | bd023f95 | Corentin Chary | if (!vnc_worker_thread_running())
|
343 | bd023f95 | Corentin Chary | return ;
|
344 | bd023f95 | Corentin Chary | |
345 | bd023f95 | Corentin Chary | /* Remove all jobs and wake up the thread */
|
346 | bd023f95 | Corentin Chary | vnc_lock_queue(queue); |
347 | bd023f95 | Corentin Chary | queue->exit = true;
|
348 | bd023f95 | Corentin Chary | vnc_unlock_queue(queue); |
349 | bd023f95 | Corentin Chary | vnc_jobs_clear(NULL);
|
350 | bd023f95 | Corentin Chary | qemu_cond_broadcast(&queue->cond); |
351 | bd023f95 | Corentin Chary | } |