14
14
static nni_mtx nni_aio_lk ;
15
15
// These are used for expiration.
16
16
static nni_cv nni_aio_expire_cv ;
17
- static int nni_aio_expire_run ;
17
+ static bool nni_aio_expire_exit ;
18
18
static nni_thr nni_aio_expire_thr ;
19
19
static nni_list nni_aio_expire_list ;
20
20
static nni_aio * nni_aio_expire_aio ;
21
21
22
+ // Reaping items.
23
+ static nni_thr nni_aio_reap_thr ;
24
+ static nni_aio * nni_aio_reap_list ;
25
+ static nni_mtx nni_aio_reap_lk ;
26
+ static nni_cv nni_aio_reap_cv ;
27
+ static bool nni_aio_reap_exit ;
28
+
22
29
// Design notes.
23
30
//
24
31
// AIOs are only ever "completed" by the provider, which must call
76
83
nni_aio_fini (nni_aio * aio )
77
84
{
78
85
nni_aio_cancel_fn fn ;
79
- void * arg ;
86
+ void * arg ;
80
87
81
88
// TODO: This probably could just use nni_aio_stop.
82
89
@@ -134,6 +141,18 @@ nni_aio_free(nni_aio *aio)
134
141
}
135
142
}
136
143
144
+ void
145
+ nni_aio_reap (nni_aio * aio )
146
+ {
147
+ if (aio != NULL ) {
148
+ nni_mtx_lock (& nni_aio_reap_lk );
149
+ aio -> a_reap_next = nni_aio_reap_list ;
150
+ nni_aio_reap_list = aio ;
151
+ nni_cv_wake1 (& nni_aio_reap_cv );
152
+ nni_mtx_unlock (& nni_aio_reap_lk );
153
+ }
154
+ }
155
+
137
156
int
138
157
nni_aio_set_iov (nni_aio * aio , unsigned nio , const nni_iov * iov )
139
158
{
@@ -164,7 +183,7 @@ nni_aio_stop(nni_aio *aio)
164
183
{
165
184
if (aio != NULL ) {
166
185
nni_aio_cancel_fn fn ;
167
- void * arg ;
186
+ void * arg ;
168
187
169
188
nni_mtx_lock (& nni_aio_lk );
170
189
fn = aio -> a_cancel_fn ;
@@ -187,7 +206,7 @@ nni_aio_close(nni_aio *aio)
187
206
{
188
207
if (aio != NULL ) {
189
208
nni_aio_cancel_fn fn ;
190
- void * arg ;
209
+ void * arg ;
191
210
192
211
nni_mtx_lock (& nni_aio_lk );
193
212
fn = aio -> a_cancel_fn ;
347
366
nni_aio_abort (nni_aio * aio , int rv )
348
367
{
349
368
nni_aio_cancel_fn fn ;
350
- void * arg ;
369
+ void * arg ;
351
370
352
371
nni_mtx_lock (& nni_aio_lk );
353
372
fn = aio -> a_cancel_fn ;
@@ -471,21 +490,21 @@ nni_aio_expire_loop(void *unused)
471
490
472
491
NNI_ARG_UNUSED (unused );
473
492
474
- nni_thr_set_name (NULL , "nng:aio:expire" );
493
+ nni_thr_set_name (NULL , "nng:aio:expire" );
475
494
476
495
for (;;) {
477
496
nni_aio_cancel_fn fn ;
478
- nni_time now ;
479
- nni_aio * aio ;
480
- int rv ;
497
+ nni_time now ;
498
+ nni_aio * aio ;
499
+ int rv ;
481
500
482
501
now = nni_clock ();
483
502
484
503
nni_mtx_lock (& nni_aio_lk );
485
504
486
505
if ((aio = nni_list_first (list )) == NULL ) {
487
506
488
- if (nni_aio_expire_run == 0 ) {
507
+ if (nni_aio_expire_exit ) {
489
508
nni_mtx_unlock (& nni_aio_lk );
490
509
return ;
491
510
}
@@ -530,6 +549,41 @@ nni_aio_expire_loop(void *unused)
530
549
}
531
550
}
532
551
552
+ static void
553
+ nni_aio_reap_loop (void * unused )
554
+ {
555
+ NNI_ARG_UNUSED (unused );
556
+
557
+ nni_thr_set_name (NULL , "nng:aio:reap" );
558
+
559
+ nni_mtx_lock (& nni_aio_reap_lk );
560
+
561
+ for (;;) {
562
+ nni_aio * aio ;
563
+
564
+ if ((aio = nni_aio_reap_list ) == NULL ) {
565
+ if (nni_aio_reap_exit ) {
566
+ break ;
567
+ }
568
+
569
+ nni_cv_wait (& nni_aio_reap_cv );
570
+ continue ;
571
+ }
572
+ nni_aio_reap_list = NULL ;
573
+ nni_mtx_unlock (& nni_aio_reap_lk );
574
+
575
+ while (aio != NULL ) {
576
+ nni_aio * old = aio ;
577
+ aio = aio -> a_reap_next ;
578
+ nni_aio_free (old );
579
+ }
580
+
581
+ nni_mtx_lock (& nni_aio_reap_lk );
582
+ }
583
+
584
+ nni_mtx_unlock (& nni_aio_reap_lk );
585
+ }
586
+
533
587
void *
534
588
nni_aio_get_prov_extra (nni_aio * aio , unsigned index )
535
589
{
@@ -645,40 +699,60 @@ nni_sleep_aio(nng_duration ms, nng_aio *aio)
645
699
void
646
700
nni_aio_sys_fini (void )
647
701
{
648
- nni_mtx * mtx = & nni_aio_lk ;
649
- nni_cv * cv = & nni_aio_expire_cv ;
650
- nni_thr * thr = & nni_aio_expire_thr ;
702
+ nni_mtx * mtx1 = & nni_aio_lk ;
703
+ nni_cv * cv1 = & nni_aio_expire_cv ;
704
+ nni_thr * thr1 = & nni_aio_expire_thr ;
705
+ nni_mtx * mtx2 = & nni_aio_reap_lk ;
706
+ nni_cv * cv2 = & nni_aio_reap_cv ;
707
+ nni_thr * thr2 = & nni_aio_reap_thr ;
651
708
652
- if (nni_aio_expire_run ) {
653
- nni_mtx_lock (mtx );
654
- nni_aio_expire_run = 0 ;
655
- nni_cv_wake (cv );
656
- nni_mtx_unlock (mtx );
709
+ if (! nni_aio_expire_exit ) {
710
+ nni_mtx_lock (mtx1 );
711
+ nni_aio_expire_exit = true ;
712
+ nni_cv_wake (cv1 );
713
+ nni_mtx_unlock (mtx1 );
657
714
}
658
715
659
- nni_thr_fini (thr );
660
- nni_cv_fini (cv );
661
- nni_mtx_fini (mtx );
716
+ if (!nni_aio_reap_exit ) {
717
+ nni_mtx_lock (mtx2 );
718
+ nni_aio_reap_exit = true;
719
+ nni_cv_wake (cv2 );
720
+ nni_mtx_unlock (mtx2 );
721
+ }
722
+
723
+ nni_thr_fini (thr1 );
724
+ nni_cv_fini (cv1 );
725
+ nni_mtx_fini (mtx1 );
726
+
727
+ nni_thr_fini (thr2 );
728
+ nni_cv_fini (cv2 );
729
+ nni_mtx_fini (mtx2 );
662
730
}
663
731
664
732
int
665
733
nni_aio_sys_init (void )
666
734
{
667
- int rv ;
668
- nni_mtx * mtx = & nni_aio_lk ;
669
- nni_cv * cv = & nni_aio_expire_cv ;
670
- nni_thr * thr = & nni_aio_expire_thr ;
735
+ int rv , rv1 , rv2 ;
736
+ nni_thr * thr1 = & nni_aio_expire_thr ;
737
+ nni_thr * thr2 = & nni_aio_reap_thr ;
671
738
672
739
NNI_LIST_INIT (& nni_aio_expire_list , nni_aio , a_expire_node );
673
- nni_mtx_init (mtx );
674
- nni_cv_init (cv , mtx );
740
+ nni_mtx_init (& nni_aio_lk );
741
+ nni_cv_init (& nni_aio_expire_cv , & nni_aio_lk );
742
+ nni_mtx_init (& nni_aio_reap_lk );
743
+ nni_cv_init (& nni_aio_reap_cv , & nni_aio_reap_lk );
744
+
745
+ nni_aio_expire_exit = false;
746
+ nni_aio_reap_exit = false;
675
747
676
- if ((rv = nni_thr_init (thr , nni_aio_expire_loop , NULL )) != 0 ) {
748
+ rv1 = nni_thr_init (thr1 , nni_aio_expire_loop , NULL );
749
+ rv2 = nni_thr_init (thr2 , nni_aio_reap_loop , NULL );
750
+ if (((rv = rv1 ) != 0 ) || ((rv = rv2 ) != 0 )) {
677
751
nni_aio_sys_fini ();
678
752
return (rv );
679
753
}
680
754
681
- nni_aio_expire_run = 1 ;
682
- nni_thr_run (thr );
755
+ nni_thr_run ( thr1 ) ;
756
+ nni_thr_run (thr2 );
683
757
return (0 );
684
758
}
0 commit comments