static int async_ioloop_worker() { int status = 0; while (mlist_len (s_waiters) && status >= 0) { ASSERT (mlist_len (s_pollfd_list) == mlist_len (s_pollfd_ptrs)); ASSERT (mlist_len (s_pollfd_list) == mlist_len (s_waiters)); int list_len = mlist_len (s_pollfd_list); int nfds = poll (s_pollfd_list, list_len, -1); if (nfds == -1 && errno == EINTR) continue; if (nfds == -1) return -1; size_t i, proc; for (i = 0, proc = 0; i < list_len && proc < nfds; ++i) { if (s_pollfd_list[i].revents != 0) { *s_pollfd_ptrs[i] = s_pollfd_list[i]; int cont_status = async_run_stack (s_waiters[i], NULL); if (cont_status < 0) status = -1; ++proc; } } for (i = list_len; i --> 0; ) { if (s_pollfd_list[i].revents != 0) { mlist_remove (s_pollfd_list, i); mlist_remove (s_pollfd_ptrs, i); mlist_remove (s_waiters, i); } } } return status; }
/* Parse a single option. */ static int opts_parse_opt(const char *cmd, int key, char *arg, struct opts *opts) { struct event event; struct event *event_node; memset(&event, 0, sizeof(event)); switch (key) { case 'T': _req_opt('T')->cnt++; opts->htime = arg ? atoi(arg) : -1; break; case 'P': _req_opt('T')->cnt++; opts->ptime = arg ? atoi(arg) : -1; break; case 'c': _req_opt('c')->cnt++; strncpy(opts->ftrace_clock, arg, NAME_MAX); break; case 's': _req_opt('s')->cnt++; opts->ftrace_buffsz = arg ? atoi(arg) : -1; break; case 'v': _req_opt('v')->cnt++; if (arg[0] >= '0' && arg[0] <= '9') *opts->loglevel = arg ? atoi(arg) : 0; else { int ok; *opts->loglevel = str2loglevel(arg, &ok); if (!ok) LOGW("loglevel [%s] invalid. Falling back to default\n", arg); } break; case 'z': _req_opt('z')->cnt++; opts->daemon = 1; break; case 'm': _req_opt('m')->cnt++; strncpy(opts->debugfs_path, arg, PATH_MAX); break; case 'w': _req_opt('w')->cnt++; strncpy(opts->workdir, arg, PATH_MAX); break; case 'o': _req_opt('o')->cnt++; strncpy(opts->outfname, arg, PATH_MAX); break; case 'p': _req_opt('p')->cnt++; opts->pid = arg ? atoi(arg) : 0; break; case 't': _req_opt('t')->cnt++; opts->threads = 1; break; case 'e': _req_opt('e')->cnt++; strncpy(event.name, arg, PATH_MAX); event.id = uq_eid++; assert_np(mlist_add_last(etrace.event_list, &event)); break; case 'f': _req_opt('f')->cnt++; assert_np(event_node = mdata_curr(etrace.event_list)); if (event_node->filter && strnlen(event_node->filter, FILTER_MAX) > 0) { LOGE("Filer [%s] is overwritten by [%s] for event [%s] (#%d)", event_node->filter, arg, event_node->name, mlist_len(etrace.event_list)); LOGE("Check order for options -e and -f\n"); return E_OPT_USAGE; } event_node->filter = strndup(arg, FILTER_MAX); break; case 'i': _req_opt('i')->cnt++; opts->rid = arg ? atoi(arg) : 0; break; case 'u': _req_opt('u')->cnt++; opts_help(stdout, HELP_USAGE | HELP_EXIT); break; case 'h': _req_opt('h')->cnt++; opts_help(stdout, HELP_LONG | HELP_EXIT); break; case 'D': _req_opt('D')->cnt++; doc_print(); etrace_exit(0); break; case '?': /* getopt_long already printed an error message. */ opts_help(stderr, HELP_TRY | HELP_EXIT_ERR); break; case ':': /* getopt_long already printed an error message. */ fprintf(stderr, "%s: option `-%c' requires an argument\n", cmd, optopt); opts_help(stderr, HELP_TRY | HELP_EXIT_ERR); break; case 'V': _req_opt('V')->cnt++; opts_help(stdout, HELP_VERSION | HELP_EXIT); break; default: fprintf(stderr, "etrace: unrecognized option '-%c'\n", (char)key); opts_help(stderr, HELP_TRY | HELP_EXIT_ERR); break; } return OPT_OK; }