Beispiel #1
0
static int eloop_sock_table_dispatch_table(struct eloop_sock_table *table,
					   struct pollfd **pollfds_map,
					   int max_pollfd_map,
					   short int revents)
{
	int i;
	struct pollfd *pfd;

	if (!table || !table->table)
		return 0;

	table->changed = 0;
	for (i = 0; i < table->count; i++) {
		pfd = find_pollfd(pollfds_map, table->table[i].sock,
				  max_pollfd_map);
		if (!pfd)
			continue;

		if (!(pfd->revents & revents))
			continue;

		table->table[i].handler(table->table[i].sock,
					table->table[i].eloop_data,
					table->table[i].user_data);
		if (table->changed)
			return 1;
	}

	return 0;
}
Beispiel #2
0
static void
cm_remove_fd(struct select_state *selstate, int fd)
{
    struct pollfd *pfd = find_pollfd(selstate, fd);

    *pfd = selstate->fds[selstate->nfds - 1];
    selstate->nfds--;
}
Beispiel #3
0
/* Get the output events for fd in the form of ssflags. */
static unsigned int
cm_get_ssflags(struct select_state *selstate, int fd)
{
    struct pollfd *pfd = find_pollfd(selstate, fd);

    /*
     * OS X sets POLLHUP without POLLOUT on connection error.  Catch this as
     * well as other error events such as POLLNVAL, but only if POLLIN and
     * POLLOUT aren't set, as we can get POLLHUP along with POLLIN with TCP
     * data still to be read.
     */
    if (pfd->revents != 0 && !(pfd->revents & (POLLIN | POLLOUT)))
        return SSF_EXCEPTION;

    return ((pfd->revents & POLLIN) ? SSF_READ : 0) |
        ((pfd->revents & POLLOUT) ? SSF_WRITE : 0) |
        ((pfd->revents & POLLERR) ? SSF_EXCEPTION : 0);
}
Beispiel #4
0
void
_cogl_poll_renderer_modify_fd (CoglRenderer *renderer,
                               int fd,
                               CoglPollFDEvent events)
{
  int fd_index = find_pollfd (renderer, fd);

  if (fd_index == -1)
    g_warn_if_reached ();
  else
    {
      CoglPollFD *pollfd =
        &g_array_index (renderer->poll_sources, CoglPollFD, fd_index);

      pollfd->events = events;
      renderer->poll_fds_age++;
    }
}
Beispiel #5
0
void
_cogl_poll_renderer_remove_fd (CoglRenderer *renderer, int fd)
{
  int i = find_pollfd (renderer, fd);
  GList *l;

  if (i < 0)
    return;

  g_array_remove_index_fast (renderer->poll_fds, i);
  renderer->poll_fds_age++;

  for (l = renderer->poll_sources; l; l = l->next)
    {
      CoglPollSource *source = l->data;
      if (source->fd == fd)
        {
          renderer->poll_sources =
            g_list_delete_link (renderer->poll_sources, l);
          g_slice_free (CoglPollSource, source);
          break;
        }
    }
}
Beispiel #6
0
/* Poll for writing (and not reading) on fd the next time we poll. */
static void
cm_write(struct select_state *selstate, int fd)
{
    find_pollfd(selstate, fd)->events = POLLOUT;
}
Beispiel #7
0
/* Poll for reading (and not writing) on fd the next time we poll. */
static void
cm_read(struct select_state *selstate, int fd)
{
    find_pollfd(selstate, fd)->events = POLLIN;
}
Beispiel #8
0
/*
 * Process any terminated methods. For each method determined to have
 * terminated, the function determines its return value and calls the
 * appropriate handling function, depending on the type of the method.
 */
void
process_terminated_methods(void)
{
	method_el_t	*me = uu_list_first(method_list);

	while (me != NULL) {
		struct pollfd	*pfd;
		pid_t		pid;
		int		status;
		int		ret;
		method_el_t	*tmp;

		pfd = find_pollfd(me->fd);

		/*
		 * We expect to get a POLLHUP back on the fd of the process's
		 * open psinfo file from /proc when the method terminates.
		 * A POLLERR could(?) mask a POLLHUP, so handle this
		 * also.
		 */
		if ((pfd->revents & (POLLHUP|POLLERR)) == 0) {
			me = uu_list_next(method_list, me);
			continue;
		}

		/* get the method's exit code (no need to loop for EINTR) */
		pid = waitpid(me->pid, &status, WNOHANG);

		switch (pid) {
		case 0:					/* child still around */
			/*
			 * Either poll() is sending us invalid POLLHUP events
			 * or is flagging a POLLERR on the fd. Neither should
			 * happen, but in the event they do, ignore this fd
			 * this time around and wait out the termination
			 * of its associated method. This may result in
			 * inetd swiftly looping in event_loop(), but means
			 * we don't miss the termination of a method.
			 */
			me = uu_list_next(method_list, me);
			continue;

		case -1:				/* non-existent child */
			assert(errno == ECHILD);
			/*
			 * the method must not be owned by inetd due to it
			 * persisting over an inetd restart. Let's assume the
			 * best, that it was successful.
			 */
			ret = IMRET_SUCCESS;
			break;

		default:				/* child terminated */
			if (WIFEXITED(status)) {
				ret = WEXITSTATUS(status);
				debug_msg("process %ld of instance %s returned "
				    "%d", pid, me->inst->fmri, ret);
			} else if (WIFSIGNALED(status)) {
				/*
				 * Terminated by signal.  This may be due
				 * to a kill that we sent from a disable or
				 * offline event. We flag it as a failure, but
				 * this flagged failure will only be processed
				 * in the case of non-start methods, or when
				 * the instance is still enabled.
				 */
				debug_msg("process %ld of instance %s exited "
				    "due to signal %d", pid, me->inst->fmri,
				    WTERMSIG(status));
				ret = IMRET_FAILURE;
			} else {
				/*
				 * Can we actually get here?  Don't think so.
				 * Treat it as a failure, anyway.
				 */
				debug_msg("waitpid() for %s method of "
				    "instance %s returned %d",
				    methods[me->method].name, me->inst->fmri,
				    status);
				ret = IMRET_FAILURE;
			}
		}

		remove_method_ids(me->inst, me->pid, me->cid, me->method);

		/* continue state transition processing of the instance */
		if (me->method != IM_START) {
			process_non_start_term(me->inst, ret);
		} else {
			process_start_term(me->inst, me->proto_name);
		}

		if (me->cid != -1)
			(void) abandon_contract(me->cid);

		tmp = me;
		me = uu_list_next(method_list, me);
		unregister_method(tmp);
	}
}