@@ -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