Example #1
0
int poll(FAR struct pollfd *fds, nfds_t nfds, int timeout)
{
  WDOG_ID wdog;
  sem_t sem;
  int count = 0;
  int ret;

  sem_init(&sem, 0, 0);
  ret = poll_setup(fds, nfds, &sem);
  if (ret >= 0)
    {
      if (timeout >= 0)
        {
          /* Wait for the poll event with a timeout.  Note that the
           * millisecond timeout has to be converted to system clock
           * ticks for wd_start
           */

          wdog = wd_create();
          wd_start(wdog,  MSEC2TICK(timeout), poll_timeout, 1, (uint32_t)&sem);
          poll_semtake(&sem);
          wd_delete(wdog);
        }
      else
        {
          /* Wait for the poll event with no timeout */

          poll_semtake(&sem);
        }

      /* Teardown the poll operation and get the count of events */

      ret = poll_teardown(fds, nfds, &count);
    }

  sem_destroy(&sem);

  /* Check for errors */

  if (ret < 0)
    {
      set_errno(-ret);
      return ERROR;
    }

  return count;
}
Example #2
0
int poll(FAR struct pollfd *fds, nfds_t nfds, int timeout)
{
  struct timespec abstime;
  irqstate_t flags;
  sem_t sem;
  int count = 0;
  int ret;

  sem_init(&sem, 0, 0);
  ret = poll_setup(fds, nfds, &sem);
  if (ret >= 0)
    {
      if (timeout == 0)
        {
          /* Poll returns immediately whether we have a poll event or not. */
        }
      else if (timeout > 0)
        {
          time_t   sec;
          uint32_t nsec;

          /* Either wait for either a poll event(s) to occur or for the
           * specified timeout to elapse with no event.
           *
           * NOTE: If a poll event is pending (i.e., the semaphore has already
           * been incremented), sem_timedwait() will not wait, but will return
           * immediately.
           */

           sec  = timeout / MSEC_PER_SEC;
           nsec = (timeout - MSEC_PER_SEC * sec) * NSEC_PER_MSEC;

           /* Make sure that the following are atomic by disabling interrupts.
            * Interrupts will be re-enabled while we are waiting.
            */

           flags = irqsave();
           (void)clock_gettime(CLOCK_REALTIME, &abstime);

           abstime.tv_sec  += sec;
           abstime.tv_nsec += nsec;
           if (abstime.tv_nsec > NSEC_PER_SEC)
             {
               abstime.tv_sec++;
               abstime.tv_nsec -= NSEC_PER_SEC;
             }

           (void)sem_timedwait(&sem, &abstime);
           irqrestore(flags);
        }
      else
        {
          /* Wait for the poll event with no timeout */

          poll_semtake(&sem);
        }

      /* Teardown the poll operation and get the count of events.  Zero will be
       * returned in the case of a timeout.
       */

      ret = poll_teardown(fds, nfds, &count);
    }

  sem_destroy(&sem);

  /* Check for errors */

  if (ret < 0)
    {
      set_errno(-ret);
      return ERROR;
    }

  return count;
}
Example #3
0
File: main.c Project: Issic47/libre
/**
 * Main polling loop for async I/O events. This function will only return when
 * re_cancel() is called or an error occured.
 *
 * @param signalh Optional Signal handler
 *
 * @return 0 if success, otherwise errorcode
 */
int re_main(re_signal_h *signalh)
{
	struct re *re = re_get();
	int err;

#ifdef HAVE_SIGNAL
	if (signalh) {
		(void)signal(SIGINT, signal_handler);
		(void)signal(SIGALRM, signal_handler);
		(void)signal(SIGTERM, signal_handler);
	}
#endif

	if (re->polling) {
		DEBUG_WARNING("main loop already polling\n");
		return EALREADY;
	}

	err = poll_setup(re);
	if (err)
		goto out;

	DEBUG_INFO("Using async I/O polling method: `%s'\n",
		   poll_method_name(re->method));

	re->polling = true;

#ifdef HAVE_ACTSCHED
	if (METHOD_ACTSCHED == re->method) {
		err = actsched_start();
		goto out;
	}
#endif

	re_lock(re);
	for (;;) {

		if (re->sig) {
			if (signalh)
				signalh(re->sig);

			re->sig = 0;
		}

		if (!re->polling) {
			err = 0;
			break;
		}

		err = fd_poll(re);
		if (err) {
			if (EINTR == err)
				continue;

#ifdef DARWIN
			/* NOTE: workaround for Darwin */
			if (EBADF == err)
				continue;
#endif

			break;
		}

		tmr_poll(&re->tmrl);
	}
	re_unlock(re);

 out:
	re->polling = false;

	return err;
}
Example #4
0
File: main.c Project: Issic47/libre
/**
 * Listen for events on a file descriptor
 *
 * @param fd     File descriptor
 * @param flags  Wanted event flags
 * @param fh     Event handler
 * @param arg    Handler argument
 *
 * @return 0 if success, otherwise errorcode
 */
int fd_listen(int fd, int flags, fd_h *fh, void *arg)
{
	struct re *re = re_get();
	int err = 0;

	DEBUG_INFO("fd_listen: fd=%d flags=0x%02x\n", fd, flags);

	if (fd < 0) {
		DEBUG_WARNING("fd_listen: corrupt fd %d\n", fd);
		return EBADF;
	}

	if (flags || fh) {
		err = poll_setup(re);
		if (err)
			return err;
	}

	if (fd >= re->maxfds) {
		if (flags) {
			DEBUG_WARNING("fd_listen: fd=%d flags=0x%02x"
				      " - Max %d fds\n",
				      fd, flags, re->maxfds);
		}
		return EMFILE;
	}

	/* Update fh set */
	if (re->fhs) {
		re->fhs[fd].flags = flags;
		re->fhs[fd].fh    = fh;
		re->fhs[fd].arg   = arg;
	}

	re->nfds = max(re->nfds, fd+1);

	switch (re->method) {

#ifdef HAVE_POLL
	case METHOD_POLL:
		err = set_poll_fds(re, fd, flags);
		break;
#endif

#ifdef HAVE_EPOLL
	case METHOD_EPOLL:
		if (re->epfd <= 0)
			return EBADFD;
		err = set_epoll_fds(re, fd, flags);
		break;
#endif
	default:
		break;
	}

	if (err) {
		if (flags && fh) {
			fd_close(fd);
			DEBUG_WARNING("fd_listen: fd=%d flags=0x%02x (%m)\n",
				      fd, flags, err);
		}
	}

	return err;
}