@@ -2358,11 +2358,13 @@ get_io_flags_udp(struct context *c, struct multi_io *multi_io, const unsigned in
23582358}
23592359
23602360void
2361- io_wait_dowork (struct context * c , const unsigned int flags )
2361+ io_wait_dowork (struct context * c , const unsigned int flags , int z )
23622362{
23632363 unsigned int out_socket ;
23642364 unsigned int out_tuntap ;
23652365 struct event_set_return esr [4 ];
2366+ struct event_set * event_set = ((z & THREAD_RTWL ) != 0 ) ? c -> c2 .event_set : c -> c2 .event_set2 ;
2367+ unsigned int * event_set_status = ((z & THREAD_RTWL ) != 0 ) ? & (c -> c2 .event_set_status ) : & (c -> c2 .event_set_status2 );
23662368
23672369 /* These shifts all depend on EVENT_READ and EVENT_WRITE */
23682370 static uintptr_t socket_shift = SOCKET_SHIFT ; /* depends on SOCKET_READ and SOCKET_WRITE */
@@ -2380,29 +2382,29 @@ io_wait_dowork(struct context *c, const unsigned int flags)
23802382 /*
23812383 * Decide what kind of events we want to wait for.
23822384 */
2383- event_reset (c -> c2 . event_set );
2385+ event_reset (event_set );
23842386
2385- multi_io_process_flags (c , c -> c2 . event_set , flags , & out_socket , & out_tuntap );
2387+ multi_io_process_flags (c , event_set , flags , & out_socket , & out_tuntap );
23862388
23872389#if defined(TARGET_LINUX ) || defined(TARGET_FREEBSD )
23882390 if (out_socket & EVENT_READ && c -> c2 .did_open_tun )
23892391 {
2390- dco_event_set (& c -> c1 .tuntap -> dco , c -> c2 . event_set , (void * )dco_shift );
2392+ dco_event_set (& c -> c1 .tuntap -> dco , event_set , (void * )dco_shift );
23912393 }
23922394#endif
23932395
23942396#ifdef ENABLE_MANAGEMENT
23952397 if (management )
23962398 {
2397- management_socket_set (management , c -> c2 . event_set , (void * )management_shift , NULL );
2399+ management_socket_set (management , event_set , (void * )management_shift , NULL );
23982400 }
23992401#endif
24002402
24012403#ifdef ENABLE_ASYNC_PUSH
24022404 /* arm inotify watcher */
24032405 if (c -> options .mode == MODE_SERVER )
24042406 {
2405- event_ctl (c -> c2 . event_set , c -> c2 .inotify_fd , EVENT_READ , (void * )file_shift );
2407+ event_ctl (event_set , c -> c2 .inotify_fd , EVENT_READ , (void * )file_shift );
24062408 }
24072409#endif
24082410
@@ -2416,7 +2418,7 @@ io_wait_dowork(struct context *c, const unsigned int flags)
24162418 * (6) timeout (tv) expired
24172419 */
24182420
2419- c -> c2 . event_set_status = ES_ERROR ;
2421+ * event_set_status = ES_ERROR ;
24202422
24212423 if (!c -> sig -> signal_received )
24222424 {
@@ -2434,14 +2436,14 @@ io_wait_dowork(struct context *c, const unsigned int flags)
24342436 /*
24352437 * Wait for something to happen.
24362438 */
2437- status = event_wait (c -> c2 . event_set , & c -> c2 .timeval , esr , SIZE (esr ));
2439+ status = event_wait (event_set , & c -> c2 .timeval , esr , SIZE (esr ));
24382440
24392441 check_status (status , "event_wait" , NULL , NULL );
24402442
24412443 if (status > 0 )
24422444 {
24432445 int i ;
2444- c -> c2 . event_set_status = 0 ;
2446+ * event_set_status = 0 ;
24452447 for (i = 0 ; i < status ; ++ i )
24462448 {
24472449 const struct event_set_return * e = & esr [i ];
@@ -2452,7 +2454,7 @@ io_wait_dowork(struct context *c, const unsigned int flags)
24522454 struct event_arg * ev_arg = (struct event_arg * )e -> arg ;
24532455 if (ev_arg -> type != EVENT_ARG_LINK_SOCKET )
24542456 {
2455- c -> c2 . event_set_status = ES_ERROR ;
2457+ * event_set_status = ES_ERROR ;
24562458 msg (D_LINK_ERRORS , "io_work: non socket event delivered" );
24572459 return ;
24582460 }
@@ -2464,30 +2466,30 @@ io_wait_dowork(struct context *c, const unsigned int flags)
24642466 shift = (uintptr_t )e -> arg ;
24652467 }
24662468
2467- c -> c2 . event_set_status |= ((e -> rwflags & 3 ) << shift );
2469+ * event_set_status |= ((e -> rwflags & 3 ) << shift );
24682470 }
24692471 }
24702472 else if (status == 0 )
24712473 {
2472- c -> c2 . event_set_status = ES_TIMEOUT ;
2474+ * event_set_status = ES_TIMEOUT ;
24732475 }
24742476 }
24752477 else
24762478 {
2477- c -> c2 . event_set_status = SOCKET_READ ;
2479+ * event_set_status = SOCKET_READ ;
24782480 }
24792481 }
24802482
24812483 /* 'now' should always be a reasonably up-to-date timestamp */
24822484 update_time ();
24832485
24842486 /* set signal_received if a signal was received */
2485- if (c -> c2 . event_set_status & ES_ERROR )
2487+ if (* event_set_status & ES_ERROR )
24862488 {
24872489 get_signal (& c -> sig -> signal_received );
24882490 }
24892491
2490- dmsg (D_EVENT_WAIT , "I/O WAIT status=0x%04x" , c -> c2 . event_set_status );
2492+ dmsg (D_EVENT_WAIT , "I/O WAIT status=0x%04x" , * event_set_status );
24912493}
24922494
24932495void threaded_fwd_inp_intf (struct context * c , struct link_socket * sock , struct thread_pointer * b )
@@ -2507,7 +2509,7 @@ void threaded_fwd_inp_intf(struct context *c, struct link_socket *sock, struct t
25072509}
25082510
25092511void
2510- process_io (struct context * c , struct link_socket * sock , struct thread_pointer * b )
2512+ process_io (struct context * c , struct link_socket * sock , struct thread_pointer * b , int z )
25112513{
25122514 const unsigned int status = c -> c2 .event_set_status ;
25132515
@@ -2520,17 +2522,17 @@ process_io(struct context *c, struct link_socket *sock, struct thread_pointer *b
25202522#endif
25212523
25222524 /* TCP/UDP port ready to accept write */
2523- if (status & SOCKET_WRITE )
2525+ if (( status & SOCKET_WRITE ) && (( z & THREAD_RTWL ) != 0 ) )
25242526 {
25252527 process_outgoing_link (c , sock );
25262528 }
25272529 /* TUN device ready to accept write */
2528- else if (status & TUN_WRITE )
2530+ else if (( status & TUN_WRITE ) && (( z & THREAD_RLWT ) != 0 ) )
25292531 {
25302532 process_outgoing_tun (c , sock );
25312533 }
25322534 /* Incoming data on TCP/UDP port */
2533- else if (status & SOCKET_READ )
2535+ else if (( status & SOCKET_READ ) && (( z & THREAD_RLWT ) != 0 ) )
25342536 {
25352537 read_incoming_link (c , sock );
25362538 if (!IS_SIG (c ))
@@ -2539,15 +2541,52 @@ process_io(struct context *c, struct link_socket *sock, struct thread_pointer *b
25392541 }
25402542 }
25412543 /* Incoming data on TUN device */
2542- else if (status & TUN_READ )
2544+ else if (( status & TUN_READ ) && (( z & THREAD_RTWL ) != 0 ) )
25432545 {
25442546 threaded_fwd_inp_intf (c , sock , b );
25452547 }
2546- else if (status & DCO_READ )
2548+ else if (( status & DCO_READ ) && (( z & THREAD_RTWL ) != 0 ) )
25472549 {
25482550 if (!IS_SIG (c ))
25492551 {
25502552 process_incoming_dco (c );
25512553 }
25522554 }
25532555}
2556+
2557+ void threaded_dual_init (struct dual_args * d )
2558+ {
2559+ if ((d -> a == 0 ) && (d -> c -> c2 .buffers ))
2560+ {
2561+ if ((d -> z & THREAD_RLWT ) != 0 )
2562+ {
2563+ d -> c -> c2 .buffers -> read_link_buf .len = 0 ;
2564+ d -> c -> c2 .buf2 = d -> c -> c2 .buffers -> read_link_buf ;
2565+ d -> a = 1 ;
2566+ }
2567+ if ((d -> z & THREAD_RTWL ) != 0 )
2568+ {
2569+ d -> c -> c2 .buffers -> read_tun_buf .len = 0 ;
2570+ d -> c -> c2 .buf = d -> c -> c2 .buffers -> read_tun_buf ;
2571+ d -> a = 1 ;
2572+ }
2573+ }
2574+ }
2575+
2576+ void * threaded_process_io (void * a )
2577+ {
2578+ struct dual_args * d = (struct dual_args * )a ;
2579+ while (true)
2580+ {
2581+ if (d -> b -> p -> z != 1 ) { break ; }
2582+ pthread_mutex_lock (& (d -> i ));
2583+ if (d -> b -> p -> z != 1 ) { break ; }
2584+ threaded_dual_init (d );
2585+ if (d -> a == 1 )
2586+ {
2587+ process_io (d -> c , d -> c -> c2 .link_sockets [0 ], d -> b , d -> z );
2588+ }
2589+ pthread_mutex_unlock (& (d -> o ));
2590+ }
2591+ return NULL ;
2592+ }
0 commit comments