示例#1
0
/*! Run signal handler immediatedly, just now.
** \param  signum   Signal number
** \param  info     Saved info for sa_sigaction handler
** \param  context  Saved context for sa_sigaction handler
** \param  our_info Our signal info
*/
ci_inline void citp_signal_run_now(int signum, siginfo_t *info,
                                   void *context,
                                   citp_signal_info *our_info)
{
  int need_restart;

  LOG_SIG(log("%s: SIGNAL %d - run immediately", __FUNCTION__, signum));

  /* Try to keep order: old signals first, and need_restart is from the
   * last one */
  if (our_info && (our_info->aflags & OO_SIGNAL_FLAG_HAVE_PENDING))
    citp_signal_run_pending(our_info);

  need_restart = citp_signal_run_app_handler(signum, info, context);

  /* Set need_restart flag in accordance with sa_restart.
   * The last signal wins, so we set need_restart to 1 if necessary.
   */
  if (our_info) {
    LOG_SIG(log("%s: SIGNAL %d - set need restart flag to %d", __FUNCTION__,
                signum, need_restart));
    if( need_restart )
      ci_atomic32_or(&our_info->aflags, OO_SIGNAL_FLAG_NEED_RESTART);
    else
      ci_atomic32_and(&our_info->aflags, ~OO_SIGNAL_FLAG_NEED_RESTART);
  }
}
示例#2
0
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;
}
示例#3
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__ */
}