aboutsummaryrefslogtreecommitdiffstats
path: root/arch/um/os-Linux/sigio.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/um/os-Linux/sigio.c')
-rw-r--r--arch/um/os-Linux/sigio.c55
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 */
32static int write_sigio_fds[2] = { -1, -1 }; 32#define SIGIO_FDS_INIT {-1, -1}
33static int sigio_private[2] = { -1, -1 }; 33
34static int write_sigio_fds[2] = SIGIO_FDS_INIT;
35static int sigio_private[2] = SIGIO_FDS_INIT;
34 36
35struct pollfds { 37struct 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: 296out_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;
302out_clear_poll:
303 current_poll = ((struct pollfds) { .poll = NULL,
304 .size = 0,
305 .used = 0 });
306out_free:
308 kfree(p); 307 kfree(p);
309 out_close2: 308 sigio_unlock();
309out_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: 312out_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
318void sigio_cleanup(void) 317void sigio_cleanup(void)