@@ -268,6 +268,7 @@ struct op_ensure_ctx {
268
268
void * read_buf ;
269
269
int read_maxlen ;
270
270
struct __kernel_timespec ts ;
271
+ int flags ;
271
272
};
272
273
273
274
VALUE um_timeout_ensure (VALUE arg ) {
@@ -390,7 +391,7 @@ int um_read_each_safe_loop_singleshot(struct op_ensure_ctx *ctx, int total) {
390
391
}
391
392
}
392
393
393
- int um_read_each_multishot_process_results (struct op_ensure_ctx * ctx , int * total ) {
394
+ int read_each_multishot_process_results (struct op_ensure_ctx * ctx , int * total ) {
394
395
__s32 result = 0 ;
395
396
__u32 flags = 0 ;
396
397
__s32 bad_result = 0 ;
@@ -441,7 +442,7 @@ VALUE um_read_each_safe_loop(VALUE arg) {
441
442
if (!ctx -> op -> list_results .head )
442
443
rb_raise (rb_eRuntimeError , "no result found!\n" );
443
444
444
- if (!um_read_each_multishot_process_results (ctx , & total ))
445
+ if (!read_each_multishot_process_results (ctx , & total ))
445
446
return INT2NUM (total );
446
447
}
447
448
}
@@ -539,7 +540,6 @@ VALUE um_socket(struct um *machine, int domain, int type, int protocol, uint fla
539
540
int result = 0 ;
540
541
541
542
io_uring_prep_socket (sqe , domain , type , protocol , flags );
542
-
543
543
um_await_op (machine , op , & result , NULL );
544
544
545
545
um_raise_on_error_result (result );
@@ -552,7 +552,6 @@ VALUE um_connect(struct um *machine, int fd, const struct sockaddr *addr, sockle
552
552
int result = 0 ;
553
553
554
554
io_uring_prep_connect (sqe , fd , addr , addrlen );
555
-
556
555
um_await_op (machine , op , & result , NULL );
557
556
558
557
um_raise_on_error_result (result );
@@ -565,7 +564,6 @@ VALUE um_send(struct um *machine, int fd, VALUE buffer, int len, int flags) {
565
564
int result = 0 ;
566
565
567
566
io_uring_prep_send (sqe , fd , RSTRING_PTR (buffer ), len , flags );
568
-
569
567
um_await_op (machine , op , & result , NULL );
570
568
571
569
um_raise_on_error_result (result );
@@ -579,21 +577,52 @@ VALUE um_recv(struct um *machine, int fd, VALUE buffer, int maxlen, int flags) {
579
577
580
578
void * ptr = um_prepare_read_buffer (buffer , maxlen , 0 );
581
579
io_uring_prep_recv (sqe , fd , ptr , maxlen , flags );
582
-
583
580
um_await_op (machine , op , & result , NULL );
584
581
585
582
um_raise_on_error_result (result );
586
583
um_update_read_buffer (machine , buffer , 0 , result , flags );
587
584
return INT2NUM (result );
588
585
}
589
586
587
+ static inline void recv_each_prepare_op (struct op_ensure_ctx * ctx ) {
588
+ struct um_op * op = um_op_idle_checkout (ctx -> machine , OP_RECV_MULTISHOT );
589
+ struct io_uring_sqe * sqe = um_get_sqe (ctx -> machine , op );
590
+ io_uring_prep_recv_multishot (sqe , ctx -> fd , 0 , -1 , ctx -> bgid );
591
+ sqe -> buf_group = ctx -> bgid ;
592
+ sqe -> flags |= IOSQE_BUFFER_SELECT ;
593
+ op -> flags |= OP_F_MULTISHOT ;
594
+ ctx -> op = op ;
595
+ }
596
+
597
+ VALUE recv_each_safe_loop (VALUE arg ) {
598
+ struct op_ensure_ctx * ctx = (struct op_ensure_ctx * )arg ;
599
+ int total = 0 ;
600
+ recv_each_prepare_op (ctx );
601
+
602
+ while (1 ) {
603
+ um_await_op (ctx -> machine , ctx -> op , NULL , NULL );
604
+ if (!ctx -> op -> aux )
605
+ rb_raise (rb_eRuntimeError , "no associated schedule op found" );
606
+ ctx -> op -> aux = NULL ;
607
+ if (!ctx -> op -> list_results .head )
608
+ rb_raise (rb_eRuntimeError , "no result found!\n" );
609
+
610
+ if (!read_each_multishot_process_results (ctx , & total ))
611
+ return INT2NUM (total );
612
+ }
613
+ }
614
+
615
+ VALUE um_recv_each (struct um * machine , int fd , int bgid , int flags ) {
616
+ struct op_ensure_ctx ctx = { .machine = machine , .fd = fd , .bgid = bgid , .read_buf = NULL , .flags = flags };
617
+ return rb_ensure (recv_each_safe_loop , (VALUE )& ctx , um_multishot_ensure , (VALUE )& ctx );
618
+ }
619
+
590
620
VALUE um_bind (struct um * machine , int fd , struct sockaddr * addr , socklen_t addrlen ) {
591
621
struct um_op * op = um_op_idle_checkout (machine , OP_BIND );
592
622
struct io_uring_sqe * sqe = um_get_sqe (machine , op );
593
623
int result = 0 ;
594
624
595
625
io_uring_prep_bind (sqe , fd , addr , addrlen );
596
-
597
626
um_await_op (machine , op , & result , NULL );
598
627
599
628
um_raise_on_error_result (result );
@@ -606,7 +635,6 @@ VALUE um_listen(struct um *machine, int fd, int backlog) {
606
635
int result = 0 ;
607
636
608
637
io_uring_prep_listen (sqe , fd , backlog );
609
-
610
638
um_await_op (machine , op , & result , NULL );
611
639
612
640
um_raise_on_error_result (result );
@@ -660,4 +688,4 @@ VALUE um_debug(struct um *machine) {
660
688
printf ("scheduled head %p tail %p\n" , machine -> list_scheduled .head , machine -> list_scheduled .tail );
661
689
printf ("\n" );
662
690
return machine -> self ;
663
- }
691
+ }
0 commit comments