@@ -543,12 +543,32 @@ virtio_input_get_config(struct virtio_input *vi, uint8_t select,
543
543
return found ;
544
544
}
545
545
546
+ static void
547
+ virtio_input_teardown (void * param )
548
+ {
549
+ struct virtio_input * vi ;
550
+
551
+ vi = (struct virtio_input * )param ;
552
+ if (vi ) {
553
+ pthread_mutex_destroy (& vi -> mtx );
554
+ if (vi -> event_queue )
555
+ free (vi -> event_queue );
556
+ if (vi -> fd > 0 )
557
+ close (vi -> fd );
558
+ if (vi -> evdev )
559
+ free (vi -> evdev );
560
+ if (vi -> serial )
561
+ free (vi -> serial );
562
+ free (vi );
563
+ vi = NULL ;
564
+ }
565
+ }
566
+
546
567
static int
547
568
virtio_input_init (struct vmctx * ctx , struct pci_vdev * dev , char * opts )
548
569
{
549
570
struct virtio_input * vi ;
550
571
pthread_mutexattr_t attr ;
551
- bool mutex_initialized = false;
552
572
char * opt ;
553
573
int flags , ver ;
554
574
int rc ;
@@ -570,41 +590,41 @@ virtio_input_init(struct vmctx *ctx, struct pci_vdev *dev, char *opts)
570
590
opt = strsep (& opts , "," );
571
591
if (!opt ) {
572
592
WPRINTF (("%s: evdev path is NULL\n" , __func__ ));
573
- goto fail ;
593
+ goto opt_fail ;
574
594
}
575
595
576
596
vi -> evdev = strdup (opt );
577
597
if (!vi -> evdev ) {
578
598
WPRINTF (("%s: strdup failed\n" , __func__ ));
579
- goto fail ;
599
+ goto opt_fail ;
580
600
}
581
601
582
602
if (opts ) {
583
603
vi -> serial = strdup (opts );
584
604
if (!vi -> serial ) {
585
605
WPRINTF (("%s: strdup serial failed\n" , __func__ ));
586
- goto fail ;
606
+ goto serial_fail ;
587
607
}
588
608
}
589
609
590
610
vi -> fd = open (vi -> evdev , O_RDWR );
591
611
if (vi -> fd < 0 ) {
592
612
WPRINTF (("open %s failed %d\n" , vi -> evdev , errno ));
593
- goto fail ;
613
+ goto open_fail ;
594
614
}
595
615
flags = fcntl (vi -> fd , F_GETFL );
596
616
fcntl (vi -> fd , F_SETFL , flags | O_NONBLOCK );
597
617
598
618
rc = ioctl (vi -> fd , EVIOCGVERSION , & ver ); /* is it a evdev device? */
599
619
if (rc < 0 ) {
600
620
WPRINTF (("%s: get version failed\n" , vi -> evdev ));
601
- goto fail ;
621
+ goto evdev_fail ;
602
622
}
603
623
604
624
rc = ioctl (vi -> fd , EVIOCGRAB , 1 ); /* exclusive access */
605
625
if (rc < 0 ) {
606
626
WPRINTF (("%s: grab device failed %d\n" , vi -> evdev , errno ));
607
- goto fail ;
627
+ goto evdev_fail ;
608
628
}
609
629
610
630
/* init mutex attribute properly to avoid deadlock */
@@ -619,21 +639,21 @@ virtio_input_init(struct vmctx *ctx, struct pci_vdev *dev, char *opts)
619
639
if (rc )
620
640
DPRINTF (("vtinput: pthread_mutex_init failed with "
621
641
"error %d!\n" , rc ));
622
- mutex_initialized = (rc == 0 ) ? true : false;
623
642
624
643
vi -> event_qsize = VIRTIO_INPUT_PACKET_SIZE ;
625
644
vi -> event_qindex = 0 ;
626
645
vi -> event_queue = calloc (vi -> event_qsize ,
627
646
sizeof (struct virtio_input_event_elem ));
628
647
if (!vi -> event_queue ) {
629
648
WPRINTF (("vtinput: could not alloc event queue buf\n" ));
630
- goto fail ;
649
+ goto evqueue_fail ;
631
650
}
632
651
633
- vi -> mevp = mevent_add (vi -> fd , EVF_READ , virtio_input_read_event , vi , NULL , NULL );
652
+ vi -> mevp = mevent_add (vi -> fd , EVF_READ , virtio_input_read_event , vi ,
653
+ virtio_input_teardown , vi );
634
654
if (vi -> mevp == NULL ) {
635
655
WPRINTF (("vtinput: could not register event\n" ));
636
- goto fail ;
656
+ goto mevent_fail ;
637
657
}
638
658
639
659
virtio_linkup (& vi -> base , & virtio_input_ops , vi , dev , vi -> queues , BACKEND_VBSU );
@@ -665,32 +685,29 @@ virtio_input_init(struct vmctx *ctx, struct pci_vdev *dev, char *opts)
665
685
return rc ;
666
686
667
687
fail :
668
- if (vi ) {
669
- if (mutex_initialized )
670
- pthread_mutex_destroy (& vi -> mtx );
671
- if (vi -> event_queue ) {
672
- free (vi -> event_queue );
673
- vi -> event_queue = NULL ;
674
- }
675
- if (vi -> mevp ) {
676
- mevent_delete (vi -> mevp );
677
- vi -> mevp = NULL ;
678
- }
679
- if (vi -> fd > 0 ) {
680
- close (vi -> fd );
681
- vi -> fd = -1 ;
682
- }
683
- if (vi -> serial ) {
684
- free (vi -> serial );
685
- vi -> serial = NULL ;
686
- }
687
- if (vi -> evdev ) {
688
- free (vi -> evdev );
689
- vi -> evdev = NULL ;
690
- }
691
- free (vi );
692
- vi = NULL ;
688
+ /* all resources will be freed in the teardown callback */
689
+ mevent_delete (vi -> mevp );
690
+ return -1 ;
691
+
692
+ mevent_fail :
693
+ free (vi -> event_queue );
694
+ vi -> event_queue = NULL ;
695
+ evqueue_fail :
696
+ pthread_mutex_destroy (& vi -> mtx );
697
+ evdev_fail :
698
+ close (vi -> fd );
699
+ vi -> fd = -1 ;
700
+ open_fail :
701
+ if (vi -> serial ) {
702
+ free (vi -> serial );
703
+ vi -> serial = NULL ;
693
704
}
705
+ serial_fail :
706
+ free (vi -> evdev );
707
+ vi -> evdev = NULL ;
708
+ opt_fail :
709
+ free (vi );
710
+ vi = NULL ;
694
711
return -1 ;
695
712
}
696
713
@@ -700,21 +717,8 @@ virtio_input_deinit(struct vmctx *ctx, struct pci_vdev *dev, char *opts)
700
717
struct virtio_input * vi ;
701
718
702
719
vi = (struct virtio_input * )dev -> arg ;
703
- if (vi ) {
704
- pthread_mutex_destroy (& vi -> mtx );
705
- if (vi -> event_queue )
706
- free (vi -> event_queue );
707
- if (vi -> mevp )
708
- mevent_delete (vi -> mevp );
709
- if (vi -> fd > 0 )
710
- close (vi -> fd );
711
- if (vi -> evdev )
712
- free (vi -> evdev );
713
- if (vi -> serial )
714
- free (vi -> serial );
715
- free (vi );
716
- vi = NULL ;
717
- }
720
+ if (vi && vi -> mevp )
721
+ mevent_delete (vi -> mevp );
718
722
}
719
723
720
724
struct pci_vdev_ops pci_ops_virtio_input = {
0 commit comments