int oo_spinloop_run_pending_sigs(ci_netif* ni, citp_waitable* w, citp_signal_info* si, int have_timeout) { int inside_lib; if( have_timeout ) return -EINTR; if( w ) ci_sock_unlock(ni, w); inside_lib = si->inside_lib; si->inside_lib = 0; ci_compiler_barrier(); citp_signal_run_pending(si); si->inside_lib = inside_lib; ci_compiler_barrier(); if( w ) ci_sock_lock(ni, w); if( ~si->aflags & OO_SIGNAL_FLAG_NEED_RESTART ) /* handler sets need_restart, exit if no restart is necessary */ return -EINTR; return 0; }
static int ci_udp_recvmsg_block(ci_udp_iomsg_args* a, ci_netif* ni, ci_udp_state* us, int timeout) { int rc; #ifndef __KERNEL__ { citp_signal_info* si; struct pollfd pfd; #if !CI_CFG_CITP_INSIDE_LIB_IS_FLAG int inside_lib; #endif pfd.fd = a->fd; pfd.events = POLLIN; if( timeout == 0 ) timeout = -1; /* Ideally, we should do the same as in citp_tcp_accept(), but since * we do not have lib_context and citp_exit_lib() out of unix/ * subdirectory, we copy it contents. */ si = citp_signal_get_specific_inited(); continue_to_block: #if !CI_CFG_CITP_INSIDE_LIB_IS_FLAG inside_lib = si->inside_lib; ci_assert_gt(inside_lib, 0); #endif si->inside_lib = 0; ci_compiler_barrier(); if(CI_UNLIKELY( si->aflags & OO_SIGNAL_FLAG_HAVE_PENDING )) citp_signal_run_pending(si); rc = ci_sys_poll(&pfd, 1, timeout); #if CI_CFG_CITP_INSIDE_LIB_IS_FLAG si->inside_lib = 1; #else si->inside_lib = inside_lib; #endif if( rc > 0 ) return 0; else if( rc == 0 ) rc = -EAGAIN; else if( errno == EINTR && (si->aflags & OO_SIGNAL_FLAG_NEED_RESTART) && timeout == -1 ) { /* Blocking recv() should only be restarted if there is no timeout. */ goto continue_to_block; } else rc = -errno; return rc; } #else /* __KERNEL__ */ { int mask; s64 t; if( timeout == 0 ) t = -1; else t = msecs_to_jiffies(timeout); mask = POLLIN; rc = efab_tcp_helper_poll_udp(a->filp, &mask, &t); if( rc == 0 ) { if( mask ) { return 0; } else rc = -EAGAIN; } else if( rc == -ERESTARTSYS && us->s.so.rcvtimeo_msec ) rc = -EINTR; } return rc; #endif /* __KERNEL__ */ }