Revision a76bab49 block-raw-posix.c

b/block-raw-posix.c
101 101
#endif
102 102
} BDRVRawState;
103 103

  
104
static int posix_aio_init(void);
105

  
104 106
static int fd_open(BlockDriverState *bs);
105 107

  
106 108
static int raw_open(BlockDriverState *bs, const char *filename, int flags)
......
108 110
    BDRVRawState *s = bs->opaque;
109 111
    int fd, open_flags, ret;
110 112

  
113
    posix_aio_init();
114

  
111 115
    s->lseek_err_cnt = 0;
112 116

  
113 117
    open_flags = O_BINARY;
......
437 441
    int ret;
438 442
} RawAIOCB;
439 443

  
440
static int aio_sig_fd = -1;
441
static int aio_sig_num = SIGUSR2;
442
static RawAIOCB *first_aio; /* AIO issued */
443
static int aio_initialized = 0;
444
typedef struct PosixAioState
445
{
446
    int fd;
447
    RawAIOCB *first_aio;
448
} PosixAioState;
444 449

  
445
static void qemu_aio_poll(void *opaque)
450
static void posix_aio_read(void *opaque)
446 451
{
452
    PosixAioState *s = opaque;
447 453
    RawAIOCB *acb, **pacb;
448 454
    int ret;
449 455
    size_t offset;
......
457 463
    while (offset < 128) {
458 464
        ssize_t len;
459 465

  
460
        len = read(aio_sig_fd, sig.buf + offset, 128 - offset);
466
        len = read(s->fd, sig.buf + offset, 128 - offset);
461 467
        if (len == -1 && errno == EINTR)
462 468
            continue;
463 469
        if (len == -1 && errno == EAGAIN) {
......
472 478
    }
473 479

  
474 480
    for(;;) {
475
        pacb = &first_aio;
481
        pacb = &s->first_aio;
476 482
        for(;;) {
477 483
            acb = *pacb;
478 484
            if (!acb)
......
507 513
 the_end: ;
508 514
}
509 515

  
510
void qemu_aio_init(void)
516
static int posix_aio_flush(void *opaque)
511 517
{
512
    sigset_t mask;
518
    PosixAioState *s = opaque;
519
    return !!s->first_aio;
520
}
513 521

  
514
    if (aio_initialized)
515
        return;
522
static PosixAioState *posix_aio_state;
516 523

  
517
    aio_initialized = 1;
524
static int posix_aio_init(void)
525
{
526
    sigset_t mask;
527
    PosixAioState *s;
528
  
529
    if (posix_aio_state)
530
        return 0;
531

  
532
    s = qemu_malloc(sizeof(PosixAioState));
533
    if (s == NULL)
534
        return -ENOMEM;
518 535

  
519 536
    /* Make sure to block AIO signal */
520 537
    sigemptyset(&mask);
521
    sigaddset(&mask, aio_sig_num);
538
    sigaddset(&mask, SIGUSR2);
522 539
    sigprocmask(SIG_BLOCK, &mask, NULL);
523 540
    
524
    aio_sig_fd = qemu_signalfd(&mask);
541
    s->first_aio = NULL;
542
    s->fd = qemu_signalfd(&mask);
525 543

  
526
    fcntl(aio_sig_fd, F_SETFL, O_NONBLOCK);
544
    fcntl(s->fd, F_SETFL, O_NONBLOCK);
527 545

  
528
    qemu_set_fd_handler2(aio_sig_fd, NULL, qemu_aio_poll, NULL, NULL);
546
    qemu_aio_set_fd_handler(s->fd, posix_aio_read, NULL, posix_aio_flush, s);
529 547

  
530 548
#if defined(__GLIBC__) && defined(__linux__)
531 549
    {
......
539 557
        aio_init(&ai);
540 558
    }
541 559
#endif
542
}
543

  
544
/* Wait for all IO requests to complete.  */
545
void qemu_aio_flush(void)
546
{
547
    qemu_aio_poll(NULL);
548
    while (first_aio) {
549
        qemu_aio_wait();
550
    }
551
}
552

  
553
void qemu_aio_wait(void)
554
{
555
    int ret;
556

  
557
    if (qemu_bh_poll())
558
        return;
559

  
560
    if (!first_aio)
561
        return;
562

  
563
    do {
564
        fd_set rdfds;
565

  
566
        FD_ZERO(&rdfds);
567
        FD_SET(aio_sig_fd, &rdfds);
560
    posix_aio_state = s;
568 561

  
569
        ret = select(aio_sig_fd + 1, &rdfds, NULL, NULL, NULL);
570
        if (ret == -1 && errno == EINTR)
571
            continue;
572
    } while (ret == 0);
573

  
574
    qemu_aio_poll(NULL);
562
    return 0;
575 563
}
576 564

  
577 565
static RawAIOCB *raw_aio_setup(BlockDriverState *bs,
......
588 576
    if (!acb)
589 577
        return NULL;
590 578
    acb->aiocb.aio_fildes = s->fd;
591
    acb->aiocb.aio_sigevent.sigev_signo = aio_sig_num;
579
    acb->aiocb.aio_sigevent.sigev_signo = SIGUSR2;
592 580
    acb->aiocb.aio_sigevent.sigev_notify = SIGEV_SIGNAL;
593 581
    acb->aiocb.aio_buf = buf;
594 582
    if (nb_sectors < 0)
......
596 584
    else
597 585
        acb->aiocb.aio_nbytes = nb_sectors * 512;
598 586
    acb->aiocb.aio_offset = sector_num * 512;
599
    acb->next = first_aio;
600
    first_aio = acb;
587
    acb->next = posix_aio_state->first_aio;
588
    posix_aio_state->first_aio = acb;
601 589
    return acb;
602 590
}
603 591

  
......
688 676
    }
689 677

  
690 678
    /* remove the callback from the queue */
691
    pacb = &first_aio;
679
    pacb = &posix_aio_state->first_aio;
692 680
    for(;;) {
693 681
        if (*pacb == NULL) {
694 682
            break;
......
701 689
    }
702 690
}
703 691

  
704
# else /* CONFIG_AIO */
705

  
706
void qemu_aio_init(void)
692
#else /* CONFIG_AIO */
693
static int posix_aio_init(void)
707 694
{
708 695
}
709

  
710
void qemu_aio_flush(void)
711
{
712
}
713

  
714
void qemu_aio_wait(void)
715
{
716
    qemu_bh_poll();
717
}
718

  
719 696
#endif /* CONFIG_AIO */
720 697

  
721 698
static void raw_close(BlockDriverState *bs)
......
921 898
    BDRVRawState *s = bs->opaque;
922 899
    int fd, open_flags, ret;
923 900

  
901
    posix_aio_init();
902

  
924 903
#ifdef CONFIG_COCOA
925 904
    if (strstart(filename, "/dev/cdrom", NULL)) {
926 905
        kern_return_t kernResult;

Also available in: Unified diff