Stackdb
Stackdb is a stackable, multi-target and -level source debugger and memory forensics library.
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
evloop.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2012, 2013, 2014 The University of Utah
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License as
6  * published by the Free Software Foundation; either version 2 of
7  * the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
17  */
18 
19 #include "evloop.h"
20 #include "log.h"
21 
22 #include <stdlib.h>
23 #include <glib.h>
24 #include <sys/select.h>
25 #include <sys/time.h>
26 #include <sys/types.h>
27 #include <unistd.h>
28 #include <inttypes.h>
29 #include <errno.h>
30 #include <string.h>
31 #include <assert.h>
32 
34  struct evloop *evloop = calloc(1,sizeof(*evloop));
35 
36  evloop->tab = g_hash_table_new(g_direct_hash,g_direct_equal);
37  evloop->nfds = -1;
38 
39  evloop->eh = ehandler;
40 
41  FD_ZERO(&evloop->rfds_master);
42  FD_ZERO(&evloop->wfds_master);
43  FD_ZERO(&evloop->xfds_master);
44 
45  return evloop;
46 }
47 
48 int evloop_set_fd(struct evloop *evloop,int fd,int fdtype,
49  evloop_handler_t handler,void *state) {
50  struct evloop_fdinfo *fdinfo;
51 
52  if (!handler) {
53  verror("must set a handler!\n");
54  return -1;
55  }
56 
57  fdinfo = (struct evloop_fdinfo *)g_hash_table_lookup(evloop->tab,
58  (gpointer)(uintptr_t)fd);
59  if (!fdinfo) {
60  fdinfo = calloc(1,sizeof(*fdinfo));
61  fdinfo->fd = fd;
62 
63  if (fd > evloop->nfds)
64  evloop->nfds = fd;
65 
66  g_hash_table_insert(evloop->tab,
67  (gpointer)(uintptr_t)fd,(gpointer)fdinfo);
68  }
69 
70  if (fdtype == EVLOOP_FDTYPE_R || fdtype == EVLOOP_FDTYPE_A) {
71  fdinfo->rh = handler;
72  fdinfo->rhstate = state;
73 
74  FD_SET(fd,&evloop->rfds_master);
75  }
76 
77  if (fdtype == EVLOOP_FDTYPE_W || fdtype == EVLOOP_FDTYPE_A) {
78  fdinfo->wh = handler;
79  fdinfo->whstate = state;
80 
81  FD_SET(fd,&evloop->wfds_master);
82  }
83 
84  if (fdtype == EVLOOP_FDTYPE_X || fdtype == EVLOOP_FDTYPE_A) {
85  fdinfo->xh = handler;
86  fdinfo->xhstate = state;
87 
88  FD_SET(fd,&evloop->xfds_master);
89  }
90 
91  vdebug(9,LA_LIB,LF_EVLOOP,"fd %d fdtype %d handler %p state %p\n",
92  fd,fdtype,handler,state);
93 
94  return 0;
95 }
96 
97 static int __evloop_unset_fd(struct evloop *evloop,int fd,int fdtype) {
98  struct evloop_fdinfo *fdinfo;
99  GHashTableIter iter;
100  int new_max_fd = -2;
101 
102  fdinfo = (struct evloop_fdinfo *)g_hash_table_lookup(evloop->tab,
103  (gpointer)(uintptr_t)fd);
104  if (!fdinfo) {
105  vwarnopt(5,LA_LIB,LF_EVLOOP,"no such fd %d\n",fd);
106  return -1;
107  }
108 
109  vdebug(9,LA_LIB,LF_EVLOOP,"fd %d fdtype %d\n",fd,fdtype);
110 
111  /*
112  * Note that below we clear both fdsets in case we're removing an fd
113  * during the handling of a select() call in evloop_run().
114  */
115  if (fdtype == EVLOOP_FDTYPE_R || fdtype == EVLOOP_FDTYPE_A) {
116  fdinfo->rh = NULL;
117  fdinfo->rhstate = NULL;
118 
119  FD_CLR(fd,&evloop->rfds_master);
120  FD_CLR(fd,&evloop->rfds);
121  }
122 
123  if (fdtype == EVLOOP_FDTYPE_W || fdtype == EVLOOP_FDTYPE_A) {
124  fdinfo->wh = NULL;
125  fdinfo->whstate = NULL;
126 
127  FD_CLR(fd,&evloop->wfds_master);
128  FD_CLR(fd,&evloop->wfds);
129  }
130 
131  if (fdtype == EVLOOP_FDTYPE_X || fdtype == EVLOOP_FDTYPE_A) {
132  fdinfo->xh = NULL;
133  fdinfo->xhstate = NULL;
134 
135  FD_CLR(fd,&evloop->xfds_master);
136  FD_CLR(fd,&evloop->xfds);
137  }
138 
139  /* Recalculate evloop->nfds if we have no handlers left. */
140  if (!fdinfo->rh && !fdinfo->wh && !fdinfo->xh) {
141  /* Recalculate evloop->nfds. */
142  g_hash_table_iter_init(&iter,evloop->tab);
143  while (g_hash_table_iter_next(&iter,NULL,(gpointer)&fdinfo)) {
144  /*
145  * Skip the one we're deleting; the expectation is that this
146  * function is only called when the FD will also be removed
147  * from the hashtable.
148  */
149  if (fdinfo->fd == fd)
150  continue;
151 
152  if (fdinfo->fd > new_max_fd)
153  new_max_fd = fdinfo->fd;
154  }
155 
156  evloop->nfds = new_max_fd;
157 
158  vdebug(9,LA_LIB,LF_EVLOOP,"removed fd %d (except from hashtable); nfds = %d\n",
159  fd,evloop->nfds);
160  }
161 
162  return 0;
163 }
164 
165 int evloop_unset_fd(struct evloop *evloop,int fd,int fdtype) {
166  struct evloop_fdinfo *fdinfo;
167 
168  fdinfo = (struct evloop_fdinfo *)g_hash_table_lookup(evloop->tab,
169  (gpointer)(uintptr_t)fd);
170  if (!fdinfo) {
171  vwarnopt(5,LA_LIB,LF_EVLOOP,"no such fd %d\n",fd);
172  return -1;
173  }
174 
175  __evloop_unset_fd(evloop,fd,fdtype);
176 
177  vdebug(9,LA_LIB,LF_EVLOOP,"fd %d fdtype %d\n",fd,fdtype);
178 
179  /* Remove the fd if we have no handlers left. */
180  if (!fdinfo->rh && !fdinfo->wh && !fdinfo->xh) {
181  g_hash_table_remove(evloop->tab,(gpointer)(uintptr_t)fd);
182  free(fdinfo);
183 
184  vdebug(9,LA_LIB,LF_EVLOOP,"removed fd %d completely; nfds = %d\n",
185  fd,evloop->nfds);
186  }
187 
188  return 0;
189 }
190 
191 int evloop_maxsize(struct evloop *evloop) {
192  return evloop->nfds;
193 }
194 
195 int evloop_run(struct evloop *evloop,evloop_flags_t flags,struct timeval *timeout,
196  struct evloop_fdinfo **error_fdinfo) {
197  int rc;
198  int hrc;
199  int i;
200  struct evloop_fdinfo *fdinfo;
201  GHashTableIter iter;
202 
203  if (evloop->nfds < 0) {
204  vwarnopt(3,LA_LIB,LF_EVLOOP,"no file descriptors to monitor!\n");
205  //errno = EINVAL;
206  return 0;
207  }
208 
209  while (1) {
210  evloop->rfds = evloop->rfds_master;
211  evloop->wfds = evloop->wfds_master;
212  evloop->xfds = evloop->xfds_master;
213 
214  if (evloop->nfds < 0) {
215  /*
216  * We removed all the FDs; end.
217  *
218  * User must distinguish this case from the timeout
219  * expiration case by calling evloop_maxsize() and checking to
220  * see if it is < 0.
221  */
222  return 0;
223  }
224 
225  rc = select(evloop->nfds + 1,&evloop->rfds,&evloop->wfds,&evloop->xfds,timeout);
226  if (rc == 0) {
227  /* Timeout expired; return to user. */
228  return 0;
229  }
230  else if (rc < 0) {
231  if (errno == EINTR) {
232  if (flags & EVLOOP_RETONINT)
233  return -1;
234  else
235  continue;
236  }
237  else {
238  verror("select: %s\n",strerror(errno));
239  return -1;
240  }
241  }
242 
243  vdebug(9,LA_LIB,LF_EVLOOP,"select() -> %d\n",rc);
244 
245  for (i = 0; i < evloop->nfds + 1; ++i) {
246  if (FD_ISSET(i,&evloop->rfds)) {
247  fdinfo = (struct evloop_fdinfo *) \
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");
252  FD_CLR(i,&evloop->rfds_master);
253  }
254  else {
255  vdebug(9,LA_LIB,LF_EVLOOP,"rfd %d\n",i);
256 
257  hrc = fdinfo->rh(i,EVLOOP_FDTYPE_R,fdinfo->rhstate);
258  if (hrc == EVLOOP_HRET_BADERROR) {
259  if (error_fdinfo)
260  *error_fdinfo = fdinfo;
261  verror("immediately fatal error on rfd %d\n",i);
262  if (evloop->eh)
263  evloop->eh(hrc,i,EVLOOP_FDTYPE_R,fdinfo);
264  else
266  return -1;
267  }
268  else if (hrc == EVLOOP_HRET_ERROR) {
269  if (error_fdinfo && !*error_fdinfo) {
270  *error_fdinfo = fdinfo;
271  verror("triggering fatal error on rfd %d;"
272  " finishing this pass\n",i);
273  if (evloop->eh)
274  evloop->eh(hrc,i,EVLOOP_FDTYPE_R,fdinfo);
275  else
277  }
278  else {
279  verror("fatal error on rfd %d;"
280  " finishing this pass\n",i);
281  if (evloop->eh)
282  evloop->eh(hrc,i,EVLOOP_FDTYPE_R,fdinfo);
283  else
285  }
286  }
287  else if (hrc == EVLOOP_HRET_REMOVETYPE) {
289  }
290  else if (hrc == EVLOOP_HRET_REMOVEALLTYPES) {
292  }
293  else if (hrc == EVLOOP_HRET_DONE_SUCCESS
294  || hrc == EVLOOP_HRET_DONE_FAILURE) {
295  goto done_removeall;
296  }
297  }
298  }
299  else if (FD_ISSET(i,&evloop->wfds)) {
300  fdinfo = (struct evloop_fdinfo *) \
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");
305  FD_CLR(i,&evloop->wfds_master);
306  }
307  else {
308  vdebug(9,LA_LIB,LF_EVLOOP,"wfd %d\n",i);
309 
310  hrc = fdinfo->wh(i,EVLOOP_FDTYPE_W,fdinfo->whstate);
311  if (hrc == EVLOOP_HRET_BADERROR) {
312  if (error_fdinfo)
313  *error_fdinfo = fdinfo;
314  verror("immediately fatal error on wfd %d\n",i);
315  if (evloop->eh)
316  evloop->eh(hrc,i,EVLOOP_FDTYPE_W,fdinfo);
317  else
319  return -1;
320  }
321  else if (hrc == EVLOOP_HRET_ERROR) {
322  if (error_fdinfo && !*error_fdinfo) {
323  *error_fdinfo = fdinfo;
324  verror("triggering fatal error on wfd %d;"
325  " finishing this pass\n",i);
326  if (evloop->eh)
327  evloop->eh(hrc,i,EVLOOP_FDTYPE_W,fdinfo);
328  else
330  }
331  else {
332  verror("fatal error on wfd %d;"
333  " finishing this pass\n",i);
334  if (evloop->eh)
335  evloop->eh(hrc,i,EVLOOP_FDTYPE_W,fdinfo);
336  else
338  }
339  }
340  else if (hrc == EVLOOP_HRET_REMOVETYPE) {
342  }
343  else if (hrc == EVLOOP_HRET_REMOVEALLTYPES) {
345  }
346  else if (hrc == EVLOOP_HRET_DONE_SUCCESS
347  || hrc == EVLOOP_HRET_DONE_FAILURE) {
348  goto done_removeall;
349  }
350  }
351  }
352  else if (FD_ISSET(i,&evloop->xfds)) {
353  fdinfo = (struct evloop_fdinfo *) \
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");
358  FD_CLR(i,&evloop->xfds_master);
359  }
360  else {
361  vdebug(9,LA_LIB,LF_EVLOOP,"xfd %d\n",i);
362 
363  hrc = fdinfo->xh(i,EVLOOP_FDTYPE_X,fdinfo->xhstate);
364  if (hrc == EVLOOP_HRET_BADERROR) {
365  if (error_fdinfo)
366  *error_fdinfo = fdinfo;
367  verror("immediately fatal error on xfd %d\n",i);
368  if (evloop->eh)
369  evloop->eh(hrc,i,EVLOOP_FDTYPE_X,fdinfo);
370  else
372  return -1;
373  }
374  else if (hrc == EVLOOP_HRET_ERROR) {
375  if (error_fdinfo && !*error_fdinfo) {
376  *error_fdinfo = fdinfo;
377  verror("triggering fatal error on xfd %d;"
378  " finishing this pass\n",i);
379  if (evloop->eh)
380  evloop->eh(hrc,i,EVLOOP_FDTYPE_X,fdinfo);
381  else
383  }
384  else {
385  verror("fatal error on xfd %d;"
386  " finishing this pass\n",i);
387  if (evloop->eh)
388  evloop->eh(hrc,i,EVLOOP_FDTYPE_X,fdinfo);
389  else
391  }
392  }
393  else if (hrc == EVLOOP_HRET_REMOVETYPE) {
395  }
396  else if (hrc == EVLOOP_HRET_REMOVEALLTYPES) {
398  }
399  else if (hrc == EVLOOP_HRET_DONE_SUCCESS
400  || hrc == EVLOOP_HRET_DONE_FAILURE) {
401  goto done_removeall;
402  }
403  }
404  }
405  }
406  }
407 
408  /* Never reached. */
409  return -1;
410 
411  done_removeall:
412  /* Remove all FDs; don't signal any though! */
413  g_hash_table_iter_init(&iter,evloop->tab);
414 
415  while (g_hash_table_iter_next(&iter,NULL,(gpointer)&fdinfo)) {
416  __evloop_unset_fd(evloop,fdinfo->fd,EVLOOP_FDTYPE_A);
417  g_hash_table_iter_remove(&iter);
418 
419  vdebug(9,LA_LIB,LF_EVLOOP,"removed fd %d completely; nfds = %d\n",
420  fdinfo->fd,evloop->nfds);
421  free(fdinfo);
422  }
423 
424  if (hrc == EVLOOP_HRET_DONE_SUCCESS) {
425  vdebug(5,LA_LIB,LF_EVLOOP,"evloop finished success\n");
426  return 0;
427  }
428  else {
429  vdebug(5,LA_LIB,LF_EVLOOP,"evloop finished failure\n");
430  return -1;
431  }
432 }
433 
434 int evloop_handleone(struct evloop *evloop,evloop_flags_t flags,
435  struct timeval *timeout,
436  struct evloop_fdinfo **handled_fdinfo,
437  int *handled_fdtype,int *handled_hrc) {
438  int rc;
439  int hrc;
440  int i;
441  struct evloop_fdinfo *fdinfo = NULL;
442  GHashTableIter iter;
443  char *fdtypestr;
444  int fdtype;
445  void *hstate;
447  fd_set *hmset;
448 
449  if (evloop->nfds < 0) {
450  /*
451  * All the FDs are gone; end.
452  *
453  * User must distinguish this case from the timeout
454  * expiration case by calling evloop_maxsize() and checking to
455  * see if it is < 0.
456  */
457  vwarnopt(3,LA_LIB,LF_EVLOOP,"no file descriptors to monitor!\n");
458  return 0;
459  }
460 
461  /*
462  * This is a while loop, but if one or more FDs is successfully
463  * handled, it returns to the caller. The loop is only for handling
464  * I/O conditions
465  */
466  while (1) {
467  evloop->rfds = evloop->rfds_master;
468  evloop->wfds = evloop->wfds_master;
469  evloop->xfds = evloop->xfds_master;
470 
471  if (evloop->nfds < 0) {
472  return 0;
473  }
474 
475  rc = select(evloop->nfds + 1,&evloop->rfds,&evloop->wfds,&evloop->xfds,timeout);
476  if (rc == 0) {
477  /* Timeout expired; return to user. */
478  return 0;
479  }
480  else if (rc < 0) {
481  if (errno == EINTR) {
482  if (flags & EVLOOP_RETONINT)
483  return -1;
484  else
485  continue;
486  }
487  else {
488  verror("select: %s\n",strerror(errno));
489  return -1;
490  }
491  }
492 
493  vdebug(9,LA_LIB,LF_EVLOOP,"select() -> %d\n",rc);
494 
495  for (i = 0; i < evloop->nfds + 1; ++i) {
496  fdinfo = NULL;
497  fdtypestr = NULL;
498  fdtype = -1;
499  hmset = NULL;
500  hstate = NULL;
501  handler = NULL;
502 
503  if (FD_ISSET(i,&evloop->rfds)) {
504  fdinfo = (struct evloop_fdinfo *) \
505  g_hash_table_lookup(evloop->tab,(gpointer)(uintptr_t)i);
506  fdtypestr = "rfd";
507  fdtype = EVLOOP_FDTYPE_R;
508  hmset = &evloop->rfds_master;
509  if (fdinfo) {
510  hstate = fdinfo->rhstate;
511  handler = fdinfo->rh;
512  }
513  }
514  else if (FD_ISSET(i,&evloop->wfds)) {
515  fdinfo = (struct evloop_fdinfo *) \
516  g_hash_table_lookup(evloop->tab,(gpointer)(uintptr_t)i);
517  fdtypestr = "wfd";
518  fdtype = EVLOOP_FDTYPE_W;
519  hmset = &evloop->wfds_master;
520  if (fdinfo) {
521  hstate = fdinfo->whstate;
522  handler = fdinfo->wh;
523  }
524  }
525  else if (FD_ISSET(i,&evloop->xfds)) {
526  fdinfo = (struct evloop_fdinfo *) \
527  g_hash_table_lookup(evloop->tab,(gpointer)(uintptr_t)i);
528  fdtypestr = "xfd";
529  fdtype = EVLOOP_FDTYPE_X;
530  hmset = &evloop->xfds_master;
531  if (fdinfo) {
532  hstate = fdinfo->xhstate;
533  handler = fdinfo->xh;
534  }
535  }
536  else {
537  /*
538  * If we didn't find a set FD, keep looking.
539  */
540  continue;
541  }
542 
543  /*
544  * If we get here, we will handle this FD in fdinfo; break out.
545  */
546  break;
547  }
548 
549  /*
550  * From this point, we return directly.
551  */
552  if (!fdinfo) {
553  if (i < evloop->nfds + 1) {
554  vwarn("BUG: %s %d select but not in evloop; clearing!\n",
555  fdtypestr,i);
556  FD_CLR(i,hmset);
557  errno = EBADFD;
558  return -1;
559  }
560  else {
561  vwarn("BUG: select returned %d fds, but nothing set in evloop!\n",
562  rc);
563  errno = ENOENT;
564  return -1;
565  }
566  }
567  else if (!handler) {
568  vwarn("BUG: %s %d set in select but no %s handler; clearing\n",
569  fdtypestr,i,fdtypestr);
570  FD_CLR(i,hmset);
571  errno = EBADSLT;
572  return -1;
573  }
574  else {
575  vdebug(9,LA_LIB,LF_EVLOOP,"%s %d\n",fdtypestr,i);
576 
577  hrc = handler(i,fdtype,hstate);
578 
579  if (handled_fdinfo)
580  *handled_fdinfo = fdinfo;
581  if (handled_fdtype)
582  *handled_fdtype = fdtype;
583  if (handled_hrc)
584  *handled_hrc = hrc;
585 
586  if (hrc == EVLOOP_HRET_SUCCESS) {
587  return 0;
588  }
589  else if (hrc == EVLOOP_HRET_BADERROR) {
591  "severe fatal error on %s %d\n",fdtypestr,i);
592  if (evloop->eh)
593  evloop->eh(hrc,i,fdtype,fdinfo);
594  else
595  evloop_unset_fd(evloop,i,fdtype);
596  }
597  else if (hrc == EVLOOP_HRET_ERROR) {
598  vdebug(3,LA_LIB,LF_EVLOOP,"error on %s %d\n",fdtypestr,i);
599  if (evloop->eh)
600  evloop->eh(hrc,i,fdtype,fdinfo);
601  else
602  evloop_unset_fd(evloop,i,fdtype);
603  }
604  else if (hrc == EVLOOP_HRET_REMOVETYPE) {
605  evloop_unset_fd(evloop,i,fdtype);
606  }
607  else if (hrc == EVLOOP_HRET_REMOVEALLTYPES) {
609  }
610  else if (hrc == EVLOOP_HRET_DONE_SUCCESS
611  || hrc == EVLOOP_HRET_DONE_FAILURE) {
612  /* Remove all FDs; don't signal any though! */
613  g_hash_table_iter_init(&iter,evloop->tab);
614 
615  while (g_hash_table_iter_next(&iter,NULL,(gpointer)&fdinfo)) {
616  __evloop_unset_fd(evloop,fdinfo->fd,EVLOOP_FDTYPE_A);
617  g_hash_table_iter_remove(&iter);
618 
620  "removed fd %d completely; nfds = %d\n",
621  fdinfo->fd,evloop->nfds);
622  free(fdinfo);
623  }
624 
625  /* Can't return it because we just freed it! */
626  if (handled_fdinfo)
627  *handled_fdinfo = NULL;
628 
629  if (hrc == EVLOOP_HRET_DONE_SUCCESS)
630  vdebug(5,LA_LIB,LF_EVLOOP,"evloop finished success\n");
631  else
632  vdebug(5,LA_LIB,LF_EVLOOP,"evloop finished failure\n");
633 
634  return 0;
635  }
636  else {
637  verror("bad user handler return code %d!\n",hrc);
638  errno = ENOTSUP;
639  return -1;
640  }
641 
642  /* "Success" now, no matter what. */
643  return 0;
644  }
645  }
646 
647  /* Never reached. */
648  assert(0);
649  return -1;
650 }
651 
652 void evloop_free(struct evloop *evloop) {
653  g_hash_table_destroy(evloop->tab);
654  free(evloop);
655 }
void * xhstate
Definition: evloop.h:90
#define EVLOOP_HRET_REMOVEALLTYPES
Definition: evloop.h:38
#define vwarnopt(level, area, flags, format,...)
Definition: log.h:37
int evloop_set_fd(struct evloop *evloop, int fd, int fdtype, evloop_handler_t handler, void *state)
Definition: evloop.c:48
evloop_handler_t xh
Definition: evloop.h:89
void * rhstate
Definition: evloop.h:86
evloop_error_handler_t eh
Definition: evloop.h:69
result_t handler(struct probe *probe, tid_t tid, void *data, struct probe *trigger, struct probe *base)
Definition: probetargets.c:59
static uint64_t unsigned int i
fd_set rfds
Definition: evloop.h:71
#define assert(x)
Definition: dlmalloc.c:1456
fd_set wfds_master
Definition: evloop.h:76
struct evloop * evloop_create(evloop_error_handler_t ehandler)
Definition: evloop.c:33
#define verror(format,...)
Definition: log.h:30
#define EVLOOP_HRET_REMOVETYPE
Definition: evloop.h:37
evloop_flags_t
Definition: evloop.h:45
#define EVLOOP_HRET_DONE_SUCCESS
Definition: evloop.h:39
Definition: evloop.h:66
evloop_handler_t wh
Definition: evloop.h:87
#define vwarn(format,...)
Definition: log.h:33
void free(void *ptr)
Definition: debugserver.c:207
fd_set xfds
Definition: evloop.h:73
int evloop_maxsize(struct evloop *evloop)
Definition: evloop.c:191
int nfds
Definition: evloop.h:67
Definition: log.h:68
int evloop_handleone(struct evloop *evloop, evloop_flags_t flags, struct timeval *timeout, struct evloop_fdinfo **handled_fdinfo, int *handled_fdtype, int *handled_hrc)
Definition: evloop.c:434
Definition: log.h:101
fd_set wfds
Definition: evloop.h:72
#define EVLOOP_FDTYPE_X
Definition: evloop.h:32
evloop_handler_t rh
Definition: evloop.h:85
#define EVLOOP_FDTYPE_A
Definition: evloop.h:29
#define vdebug(devel, areas, flags, format,...)
Definition: log.h:302
#define EVLOOP_HRET_ERROR
Definition: evloop.h:35
void * whstate
Definition: evloop.h:88
int evloop_unset_fd(struct evloop *evloop, int fd, int fdtype)
Definition: evloop.c:165
void evloop_free(struct evloop *evloop)
Definition: evloop.c:652
void * calloc(size_t nmemb, size_t size)
Definition: debugserver.c:200
fd_set xfds_master
Definition: evloop.h:77
#define EVLOOP_HRET_DONE_FAILURE
Definition: evloop.h:40
fd_set rfds_master
Definition: evloop.h:75
#define EVLOOP_HRET_SUCCESS
Definition: evloop.h:36
GHashTable * tab
Definition: evloop.h:79
int(* evloop_error_handler_t)(int errortype, int fd, int fdtype, struct evloop_fdinfo *error_fdinfo)
Definition: evloop.h:63
#define EVLOOP_FDTYPE_W
Definition: evloop.h:31
#define EVLOOP_FDTYPE_R
Definition: evloop.h:30
#define EVLOOP_HRET_BADERROR
Definition: evloop.h:34
int evloop_run(struct evloop *evloop, evloop_flags_t flags, struct timeval *timeout, struct evloop_fdinfo **error_fdinfo)
Definition: evloop.c:195
int(* evloop_handler_t)(int fd, int fdtype, void *state)
Definition: evloop.h:62