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; }
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--; }
/* 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); }
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++; } }
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; } } }
/* 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; }
/* 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; }
/* * 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); } }