24 #include <sys/select.h>
26 #include <sys/types.h>
36 evloop->
tab = g_hash_table_new(g_direct_hash,g_direct_equal);
39 evloop->
eh = ehandler;
53 verror(
"must set a handler!\n");
58 (gpointer)(uintptr_t)fd);
60 fdinfo =
calloc(1,
sizeof(*fdinfo));
63 if (fd > evloop->
nfds)
66 g_hash_table_insert(evloop->
tab,
67 (gpointer)(uintptr_t)fd,(gpointer)fdinfo);
92 fd,fdtype,handler,state);
97 static int __evloop_unset_fd(
struct evloop *
evloop,
int fd,
int fdtype) {
103 (gpointer)(uintptr_t)fd);
120 FD_CLR(fd,&evloop->
rfds);
128 FD_CLR(fd,&evloop->
wfds);
136 FD_CLR(fd,&evloop->
xfds);
140 if (!fdinfo->
rh && !fdinfo->
wh && !fdinfo->
xh) {
142 g_hash_table_iter_init(&iter,evloop->
tab);
143 while (g_hash_table_iter_next(&iter,NULL,(gpointer)&fdinfo)) {
149 if (fdinfo->fd == fd)
152 if (fdinfo->fd > new_max_fd)
153 new_max_fd = fdinfo->fd;
156 evloop->
nfds = new_max_fd;
169 (gpointer)(uintptr_t)fd);
175 __evloop_unset_fd(evloop,fd,fdtype);
180 if (!fdinfo->
rh && !fdinfo->
wh && !fdinfo->
xh) {
181 g_hash_table_remove(evloop->
tab,(gpointer)(uintptr_t)fd);
203 if (evloop->
nfds < 0) {
214 if (evloop->
nfds < 0) {
225 rc = select(evloop->
nfds + 1,&evloop->
rfds,&evloop->
wfds,&evloop->
xfds,timeout);
231 if (errno == EINTR) {
238 verror(
"select: %s\n",strerror(errno));
245 for (i = 0; i < evloop->
nfds + 1; ++
i) {
246 if (FD_ISSET(i,&evloop->
rfds)) {
248 g_hash_table_lookup(evloop->
tab,(gpointer)(uintptr_t)i);
249 if (!fdinfo || !fdinfo->
rh) {
250 vwarn(
"BUG: fd set in select, but not in evloop table"
251 " or no read handler; removing!\n");
260 *error_fdinfo = fdinfo;
261 verror(
"immediately fatal error on rfd %d\n",i);
269 if (error_fdinfo && !*error_fdinfo) {
270 *error_fdinfo = fdinfo;
271 verror(
"triggering fatal error on rfd %d;"
272 " finishing this pass\n",i);
279 verror(
"fatal error on rfd %d;"
280 " finishing this pass\n",i);
299 else if (FD_ISSET(i,&evloop->
wfds)) {
301 g_hash_table_lookup(evloop->
tab,(gpointer)(uintptr_t)i);
302 if (!fdinfo || !fdinfo->
wh) {
303 vwarn(
"BUG: fd set in select, but not in evloop table"
304 " or no write handler; removing!\n");
313 *error_fdinfo = fdinfo;
314 verror(
"immediately fatal error on wfd %d\n",i);
322 if (error_fdinfo && !*error_fdinfo) {
323 *error_fdinfo = fdinfo;
324 verror(
"triggering fatal error on wfd %d;"
325 " finishing this pass\n",i);
332 verror(
"fatal error on wfd %d;"
333 " finishing this pass\n",i);
352 else if (FD_ISSET(i,&evloop->
xfds)) {
354 g_hash_table_lookup(evloop->
tab,(gpointer)(uintptr_t)i);
355 if (!fdinfo || !fdinfo->
xh) {
356 vwarn(
"BUG: fd set in select, but not in evloop table"
357 " or no exception handler; removing!\n");
366 *error_fdinfo = fdinfo;
367 verror(
"immediately fatal error on xfd %d\n",i);
375 if (error_fdinfo && !*error_fdinfo) {
376 *error_fdinfo = fdinfo;
377 verror(
"triggering fatal error on xfd %d;"
378 " finishing this pass\n",i);
385 verror(
"fatal error on xfd %d;"
386 " finishing this pass\n",i);
413 g_hash_table_iter_init(&iter,evloop->
tab);
415 while (g_hash_table_iter_next(&iter,NULL,(gpointer)&fdinfo)) {
417 g_hash_table_iter_remove(&iter);
420 fdinfo->fd,evloop->
nfds);
435 struct timeval *timeout,
437 int *handled_fdtype,
int *handled_hrc) {
449 if (evloop->
nfds < 0) {
471 if (evloop->
nfds < 0) {
475 rc = select(evloop->
nfds + 1,&evloop->
rfds,&evloop->
wfds,&evloop->
xfds,timeout);
481 if (errno == EINTR) {
488 verror(
"select: %s\n",strerror(errno));
495 for (i = 0; i < evloop->
nfds + 1; ++
i) {
503 if (FD_ISSET(i,&evloop->
rfds)) {
505 g_hash_table_lookup(evloop->
tab,(gpointer)(uintptr_t)i);
511 handler = fdinfo->
rh;
514 else if (FD_ISSET(i,&evloop->
wfds)) {
516 g_hash_table_lookup(evloop->
tab,(gpointer)(uintptr_t)i);
522 handler = fdinfo->
wh;
525 else if (FD_ISSET(i,&evloop->
xfds)) {
527 g_hash_table_lookup(evloop->
tab,(gpointer)(uintptr_t)i);
533 handler = fdinfo->
xh;
553 if (i < evloop->nfds + 1) {
554 vwarn(
"BUG: %s %d select but not in evloop; clearing!\n",
561 vwarn(
"BUG: select returned %d fds, but nothing set in evloop!\n",
568 vwarn(
"BUG: %s %d set in select but no %s handler; clearing\n",
569 fdtypestr,i,fdtypestr);
577 hrc = handler(i,fdtype,hstate);
580 *handled_fdinfo = fdinfo;
582 *handled_fdtype = fdtype;
591 "severe fatal error on %s %d\n",fdtypestr,i);
593 evloop->
eh(hrc,i,fdtype,fdinfo);
600 evloop->
eh(hrc,i,fdtype,fdinfo);
613 g_hash_table_iter_init(&iter,evloop->
tab);
615 while (g_hash_table_iter_next(&iter,NULL,(gpointer)&fdinfo)) {
617 g_hash_table_iter_remove(&iter);
620 "removed fd %d completely; nfds = %d\n",
621 fdinfo->fd,evloop->
nfds);
627 *handled_fdinfo = NULL;
637 verror(
"bad user handler return code %d!\n",hrc);
653 g_hash_table_destroy(evloop->
tab);
#define EVLOOP_HRET_REMOVEALLTYPES
#define vwarnopt(level, area, flags, format,...)
int evloop_set_fd(struct evloop *evloop, int fd, int fdtype, evloop_handler_t handler, void *state)
evloop_error_handler_t eh
result_t handler(struct probe *probe, tid_t tid, void *data, struct probe *trigger, struct probe *base)
static uint64_t unsigned int i
struct evloop * evloop_create(evloop_error_handler_t ehandler)
#define verror(format,...)
#define EVLOOP_HRET_REMOVETYPE
#define EVLOOP_HRET_DONE_SUCCESS
#define vwarn(format,...)
int evloop_maxsize(struct evloop *evloop)
int evloop_handleone(struct evloop *evloop, evloop_flags_t flags, struct timeval *timeout, struct evloop_fdinfo **handled_fdinfo, int *handled_fdtype, int *handled_hrc)
#define vdebug(devel, areas, flags, format,...)
#define EVLOOP_HRET_ERROR
int evloop_unset_fd(struct evloop *evloop, int fd, int fdtype)
void evloop_free(struct evloop *evloop)
void * calloc(size_t nmemb, size_t size)
#define EVLOOP_HRET_DONE_FAILURE
#define EVLOOP_HRET_SUCCESS
int(* evloop_error_handler_t)(int errortype, int fd, int fdtype, struct evloop_fdinfo *error_fdinfo)
#define EVLOOP_HRET_BADERROR
int evloop_run(struct evloop *evloop, evloop_flags_t flags, struct timeval *timeout, struct evloop_fdinfo **error_fdinfo)
int(* evloop_handler_t)(int fd, int fdtype, void *state)