diff options
-rw-r--r-- | arch/um/os-Linux/sigio.c | 55 |
1 files changed, 27 insertions, 28 deletions
diff --git a/arch/um/os-Linux/sigio.c b/arch/um/os-Linux/sigio.c index 7604c404c4c2..9ba942947146 100644 --- a/arch/um/os-Linux/sigio.c +++ b/arch/um/os-Linux/sigio.c | |||
@@ -29,8 +29,10 @@ static int write_sigio_pid = -1; | |||
29 | * the descriptors closed after it is killed. So, it can't see them change. | 29 | * the descriptors closed after it is killed. So, it can't see them change. |
30 | * On the UML side, they are changed under the sigio_lock. | 30 | * On the UML side, they are changed under the sigio_lock. |
31 | */ | 31 | */ |
32 | static int write_sigio_fds[2] = { -1, -1 }; | 32 | #define SIGIO_FDS_INIT {-1, -1} |
33 | static int sigio_private[2] = { -1, -1 }; | 33 | |
34 | static int write_sigio_fds[2] = SIGIO_FDS_INIT; | ||
35 | static int sigio_private[2] = SIGIO_FDS_INIT; | ||
34 | 36 | ||
35 | struct pollfds { | 37 | struct pollfds { |
36 | struct pollfd *poll; | 38 | struct pollfd *poll; |
@@ -270,49 +272,46 @@ void write_sigio_workaround(void) | |||
270 | /* Did we race? Don't try to optimize this, please, it's not so likely | 272 | /* Did we race? Don't try to optimize this, please, it's not so likely |
271 | * to happen, and no more than once at the boot. */ | 273 | * to happen, and no more than once at the boot. */ |
272 | if(write_sigio_pid != -1) | 274 | if(write_sigio_pid != -1) |
273 | goto out_unlock; | 275 | goto out_free; |
274 | |||
275 | write_sigio_pid = run_helper_thread(write_sigio_thread, NULL, | ||
276 | CLONE_FILES | CLONE_VM, &stack, 0); | ||
277 | 276 | ||
278 | if (write_sigio_pid < 0) | 277 | current_poll = ((struct pollfds) { .poll = p, |
279 | goto out_clear; | 278 | .used = 1, |
279 | .size = 1 }); | ||
280 | 280 | ||
281 | if (write_sigio_irq(l_write_sigio_fds[0])) | 281 | if (write_sigio_irq(l_write_sigio_fds[0])) |
282 | goto out_kill; | 282 | goto out_clear_poll; |
283 | 283 | ||
284 | /* Success, finally. */ | ||
285 | memcpy(write_sigio_fds, l_write_sigio_fds, sizeof(l_write_sigio_fds)); | 284 | memcpy(write_sigio_fds, l_write_sigio_fds, sizeof(l_write_sigio_fds)); |
286 | memcpy(sigio_private, l_sigio_private, sizeof(l_sigio_private)); | 285 | memcpy(sigio_private, l_sigio_private, sizeof(l_sigio_private)); |
287 | 286 | ||
288 | current_poll = ((struct pollfds) { .poll = p, | 287 | write_sigio_pid = run_helper_thread(write_sigio_thread, NULL, |
289 | .used = 1, | 288 | CLONE_FILES | CLONE_VM, &stack, 0); |
290 | .size = 1 }); | ||
291 | 289 | ||
292 | sigio_unlock(); | 290 | if (write_sigio_pid < 0) |
293 | return; | 291 | goto out_clear; |
294 | 292 | ||
295 | out_kill: | ||
296 | l_write_sigio_pid = write_sigio_pid; | ||
297 | write_sigio_pid = -1; | ||
298 | sigio_unlock(); | 293 | sigio_unlock(); |
299 | /* Going to call waitpid, avoid holding the lock. */ | 294 | return; |
300 | os_kill_process(l_write_sigio_pid, 1); | ||
301 | goto out_free; | ||
302 | 295 | ||
303 | out_clear: | 296 | out_clear: |
304 | write_sigio_pid = -1; | 297 | write_sigio_pid = -1; |
305 | out_unlock: | 298 | write_sigio_fds[0] = -1; |
306 | sigio_unlock(); | 299 | write_sigio_fds[1] = -1; |
307 | out_free: | 300 | sigio_private[0] = -1; |
301 | sigio_private[1] = -1; | ||
302 | out_clear_poll: | ||
303 | current_poll = ((struct pollfds) { .poll = NULL, | ||
304 | .size = 0, | ||
305 | .used = 0 }); | ||
306 | out_free: | ||
308 | kfree(p); | 307 | kfree(p); |
309 | out_close2: | 308 | sigio_unlock(); |
309 | out_close2: | ||
310 | close(l_sigio_private[0]); | 310 | close(l_sigio_private[0]); |
311 | close(l_sigio_private[1]); | 311 | close(l_sigio_private[1]); |
312 | out_close1: | 312 | out_close1: |
313 | close(l_write_sigio_fds[0]); | 313 | close(l_write_sigio_fds[0]); |
314 | close(l_write_sigio_fds[1]); | 314 | close(l_write_sigio_fds[1]); |
315 | return; | ||
316 | } | 315 | } |
317 | 316 | ||
318 | void sigio_cleanup(void) | 317 | void sigio_cleanup(void) |