1 /*
2  * fdevent test helpr for the libxl event system
3  */
4 
5 #include "libxl_internal.h"
6 
7 #include "libxl_test_fdevent.h"
8 
9 typedef struct {
10     libxl__ao *ao;
11     libxl__ev_fd fd;
12     libxl__ao_abortable abrt;
13 } libxl__test_fdevent;
14 
15 static void fdevent_complete(libxl__egc *egc, libxl__test_fdevent *tfe,
16                              int rc);
17 
tfe_init(libxl__test_fdevent * tfe,libxl__ao * ao)18 static void tfe_init(libxl__test_fdevent *tfe, libxl__ao *ao)
19 {
20     tfe->ao = ao;
21     libxl__ev_fd_init(&tfe->fd);
22     libxl__ao_abortable_init(&tfe->abrt);
23 }
24 
tfe_cleanup(libxl__gc * gc,libxl__test_fdevent * tfe)25 static void tfe_cleanup(libxl__gc *gc, libxl__test_fdevent *tfe)
26 {
27     libxl__ev_fd_deregister(gc, &tfe->fd);
28     libxl__ao_abortable_deregister(&tfe->abrt);
29 }
30 
tfe_fd_cb(libxl__egc * egc,libxl__ev_fd * ev,int fd,short events,short revents)31 static void tfe_fd_cb(libxl__egc *egc, libxl__ev_fd *ev,
32                       int fd, short events, short revents)
33 {
34     libxl__test_fdevent *tfe = CONTAINER_OF(ev,*tfe,fd);
35     STATE_AO_GC(tfe->ao);
36     fdevent_complete(egc, tfe, 0);
37 }
38 
tfe_abrt_cb(libxl__egc * egc,libxl__ao_abortable * abrt,int rc)39 static void tfe_abrt_cb(libxl__egc *egc, libxl__ao_abortable *abrt,
40                         int rc)
41 {
42     libxl__test_fdevent *tfe = CONTAINER_OF(abrt,*tfe,abrt);
43     STATE_AO_GC(tfe->ao);
44     fdevent_complete(egc, tfe, rc);
45 }
46 
fdevent_complete(libxl__egc * egc,libxl__test_fdevent * tfe,int rc)47 static void fdevent_complete(libxl__egc *egc, libxl__test_fdevent *tfe,
48                              int rc)
49 {
50     STATE_AO_GC(tfe->ao);
51     tfe_cleanup(gc, tfe);
52     libxl__ao_complete(egc, ao, rc);
53 }
54 
libxl_test_fdevent(libxl_ctx * ctx,int fd,short events,libxl_asyncop_how * ao_how)55 int libxl_test_fdevent(libxl_ctx *ctx, int fd, short events,
56                        libxl_asyncop_how *ao_how)
57 {
58     int rc;
59     libxl__test_fdevent *tfe;
60 
61     AO_CREATE(ctx, 0, ao_how);
62     GCNEW(tfe);
63 
64     tfe_init(tfe, ao);
65 
66     rc = libxl__ev_fd_register(gc, &tfe->fd, tfe_fd_cb, fd, events);
67     if (rc) goto out;
68 
69     tfe->abrt.ao = ao;
70     tfe->abrt.callback = tfe_abrt_cb;
71     rc = libxl__ao_abortable_register(&tfe->abrt);
72     if (rc) goto out;
73 
74     return AO_INPROGRESS;
75 
76  out:
77     tfe_cleanup(gc, tfe);
78     return AO_CREATE_FAIL(rc);
79 }
80