Revision a8486bc9 cpus.c
b/cpus.c | ||
---|---|---|
33 | 33 |
#include "exec-all.h" |
34 | 34 |
|
35 | 35 |
#include "cpus.h" |
36 |
#include "compatfd.h" |
|
36 | 37 |
|
37 | 38 |
#ifdef SIGRTMIN |
38 | 39 |
#define SIG_IPI (SIGRTMIN+4) |
... | ... | |
329 | 330 |
|
330 | 331 |
static void tcg_init_ipi(void); |
331 | 332 |
static void kvm_init_ipi(CPUState *env); |
332 |
static void unblock_io_signals(void); |
|
333 |
static sigset_t block_io_signals(void); |
|
334 |
|
|
335 |
/* If we have signalfd, we mask out the signals we want to handle and then |
|
336 |
* use signalfd to listen for them. We rely on whatever the current signal |
|
337 |
* handler is to dispatch the signals when we receive them. |
|
338 |
*/ |
|
339 |
static void sigfd_handler(void *opaque) |
|
340 |
{ |
|
341 |
int fd = (unsigned long) opaque; |
|
342 |
struct qemu_signalfd_siginfo info; |
|
343 |
struct sigaction action; |
|
344 |
ssize_t len; |
|
345 |
|
|
346 |
while (1) { |
|
347 |
do { |
|
348 |
len = read(fd, &info, sizeof(info)); |
|
349 |
} while (len == -1 && errno == EINTR); |
|
350 |
|
|
351 |
if (len == -1 && errno == EAGAIN) { |
|
352 |
break; |
|
353 |
} |
|
354 |
|
|
355 |
if (len != sizeof(info)) { |
|
356 |
printf("read from sigfd returned %zd: %m\n", len); |
|
357 |
return; |
|
358 |
} |
|
359 |
|
|
360 |
sigaction(info.ssi_signo, NULL, &action); |
|
361 |
if ((action.sa_flags & SA_SIGINFO) && action.sa_sigaction) { |
|
362 |
action.sa_sigaction(info.ssi_signo, |
|
363 |
(siginfo_t *)&info, NULL); |
|
364 |
} else if (action.sa_handler) { |
|
365 |
action.sa_handler(info.ssi_signo); |
|
366 |
} |
|
367 |
} |
|
368 |
} |
|
369 |
|
|
370 |
static int qemu_signalfd_init(sigset_t mask) |
|
371 |
{ |
|
372 |
int sigfd; |
|
373 |
|
|
374 |
sigfd = qemu_signalfd(&mask); |
|
375 |
if (sigfd == -1) { |
|
376 |
fprintf(stderr, "failed to create signalfd\n"); |
|
377 |
return -errno; |
|
378 |
} |
|
379 |
|
|
380 |
fcntl_setfl(sigfd, O_NONBLOCK); |
|
381 |
|
|
382 |
qemu_set_fd_handler2(sigfd, NULL, sigfd_handler, NULL, |
|
383 |
(void *)(unsigned long) sigfd); |
|
384 |
|
|
385 |
return 0; |
|
386 |
} |
|
333 | 387 |
|
334 | 388 |
int qemu_init_main_loop(void) |
335 | 389 |
{ |
336 | 390 |
int ret; |
391 |
sigset_t blocked_signals; |
|
337 | 392 |
|
338 | 393 |
cpu_set_debug_excp_handler(cpu_debug_handler); |
339 | 394 |
|
395 |
blocked_signals = block_io_signals(); |
|
396 |
|
|
397 |
ret = qemu_signalfd_init(blocked_signals); |
|
398 |
if (ret) |
|
399 |
return ret; |
|
400 |
|
|
401 |
/* Note eventfd must be drained before signalfd handlers run */ |
|
340 | 402 |
ret = qemu_event_init(); |
341 | 403 |
if (ret) |
342 | 404 |
return ret; |
... | ... | |
347 | 409 |
qemu_mutex_init(&qemu_global_mutex); |
348 | 410 |
qemu_mutex_lock(&qemu_global_mutex); |
349 | 411 |
|
350 |
unblock_io_signals(); |
|
351 | 412 |
qemu_thread_self(&io_thread); |
352 | 413 |
|
353 | 414 |
return 0; |
... | ... | |
586 | 647 |
} |
587 | 648 |
} |
588 | 649 |
|
589 |
static void unblock_io_signals(void)
|
|
650 |
static sigset_t block_io_signals(void)
|
|
590 | 651 |
{ |
591 | 652 |
sigset_t set; |
592 | 653 |
|
654 |
/* SIGUSR2 used by posix-aio-compat.c */ |
|
593 | 655 |
sigemptyset(&set); |
594 | 656 |
sigaddset(&set, SIGUSR2); |
595 |
sigaddset(&set, SIGIO); |
|
596 |
sigaddset(&set, SIGALRM); |
|
597 | 657 |
pthread_sigmask(SIG_UNBLOCK, &set, NULL); |
598 | 658 |
|
599 | 659 |
sigemptyset(&set); |
660 |
sigaddset(&set, SIGIO); |
|
661 |
sigaddset(&set, SIGALRM); |
|
600 | 662 |
sigaddset(&set, SIG_IPI); |
601 | 663 |
pthread_sigmask(SIG_BLOCK, &set, NULL); |
664 |
|
|
665 |
return set; |
|
602 | 666 |
} |
603 | 667 |
|
604 | 668 |
void qemu_mutex_lock_iothread(void) |
Also available in: Unified diff