예제 #1
0
static inline int net_pollsetup(FAR struct socket *psock,
                                FAR struct pollfd *fds)
{
  FAR struct uip_conn *conn = psock->s_conn;
  FAR struct net_poll_s *info;
  FAR struct uip_callback_s *cb;
  uip_lock_t flags;
  int ret;

  /* Sanity check */

#ifdef CONFIG_DEBUG
  if (!conn || !fds)
    {
      return -EINVAL;
    }
#endif

  /* Allocate a container to hold the poll information */

  info = (FAR struct net_poll_s *)kmalloc(sizeof(struct net_poll_s));
  if (!info)
    {
      return -ENOMEM;
    }
  
  /* Some of the  following must be atomic */

  flags = uip_lock();

  /* Allocate a TCP/IP callback structure */

  cb = uip_tcpcallbackalloc(conn);
  if (!cb)
    {
      ret = -EBUSY;
      goto errout_with_lock;
    }

  /* Initialize the poll info container */

  info->psock  = psock;
  info->fds    = fds;
  info->cb     = cb;

  /* Initialize the callback structure.  Save the reference to the info
   * structure as callback private data so that it will be available during
   * callback processing.
   */

  cb->flags    = (UIP_NEWDATA|UIP_BACKLOG|UIP_POLL|UIP_CLOSE|UIP_ABORT|UIP_TIMEDOUT);
  cb->priv     = (FAR void *)info;
  cb->event    = poll_interrupt;

  /* Save the reference in the poll info structure as fds private as well
   * for use durring poll teardown as well.
   */

  fds->priv    = (FAR void *)info;

#ifdef CONFIG_NET_TCPBACKLOG
  /* Check for read data or backlogged connection availability now */

  if (!sq_empty(&conn->readahead) || uip_backlogavailable(conn))
#else
  /* Check for read data availability now */

  if (!sq_empty(&conn->readahead))
#endif
    {
      fds->revents |= (POLLOUT & fds->events);
    }

  /* Check for a loss of connection events */

  if (!_SS_ISCONNECTED(psock->s_flags))
    {
      fds->revents |= (POLLERR | POLLHUP);
    }

  /* Check if any requested events are already in effect */

  if (fds->revents != 0)
    {
      /* Yes.. then signal the poll logic */

      sem_post(fds->sem);
    }

  uip_unlock(flags);
  return OK;

errout_with_lock:
  kfree(info);
  uip_unlock(flags);
  return ret;
}
예제 #2
0
static inline int net_pollsetup(FAR struct socket *psock, struct pollfd *fds)
{
  FAR struct uip_conn *conn = psock->s_conn;
  FAR struct uip_callback_s *cb;
  uip_lock_t flags;
  int ret;

  /* Sanity check */

#ifdef CONFIG_DEBUG
  if (!conn || !fds)
    {
      return -EINVAL;
    }
#endif

  /* Some of the  following must be atomic */

  flags = uip_lock();

  /* Allocate a TCP/IP callback structure */

  cb = uip_tcpcallbackalloc(conn);
  if (!cb)
    {
      ret = -EBUSY;
      goto errout_with_irq;
    }

  /* Initialize the callbcack structure */

  cb->flags    = UIP_NEWDATA|UIP_BACKLOG|UIP_POLL|UIP_CLOSE|UIP_ABORT|UIP_TIMEDOUT;
  cb->priv     = (FAR void *)fds;
  cb->event    = poll_interrupt;

  /* Save the nps reference in the poll structure for use at teardown as well */

  fds->priv    = (FAR void *)cb;

#ifdef CONFIG_NET_TCPBACKLOG
  /* Check for read data or backlogged connection availability now */

  if (!sq_empty(&conn->readahead) || uip_backlogavailable(conn))
#else
  /* Check for read data availability now */

  if (!sq_empty(&conn->readahead))
#endif
    {
      fds->revents = fds->events & POLLIN;
      if (fds->revents != 0)
        {
          /* If data is available now, the signal the poll logic */

          sem_post(fds->sem);
        }
    }
  uip_unlock(flags);
  return OK;

errout_with_irq:
  uip_unlock(flags);
  return ret;
}