summaryrefslogtreecommitdiff
path: root/tools/libs/light/libxl_test_fdevent.c
blob: 2d875d995f2d25e2621d54340d394c49f704873e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
/*
 * fdevent test helpr for the libxl event system
 */

#include "libxl_internal.h"

#include "libxl_test_fdevent.h"

typedef struct {
    libxl__ao *ao;
    libxl__ev_fd fd;
    libxl__ao_abortable abrt;
} libxl__test_fdevent;

static void fdevent_complete(libxl__egc *egc, libxl__test_fdevent *tfe,
                             int rc);

static void tfe_init(libxl__test_fdevent *tfe, libxl__ao *ao)
{
    tfe->ao = ao;
    libxl__ev_fd_init(&tfe->fd);
    libxl__ao_abortable_init(&tfe->abrt);
}

static void tfe_cleanup(libxl__gc *gc, libxl__test_fdevent *tfe)
{
    libxl__ev_fd_deregister(gc, &tfe->fd);
    libxl__ao_abortable_deregister(&tfe->abrt);
}

static void tfe_fd_cb(libxl__egc *egc, libxl__ev_fd *ev,
                      int fd, short events, short revents)
{
    libxl__test_fdevent *tfe = CONTAINER_OF(ev,*tfe,fd);
    STATE_AO_GC(tfe->ao);
    fdevent_complete(egc, tfe, 0);
}

static void tfe_abrt_cb(libxl__egc *egc, libxl__ao_abortable *abrt,
                        int rc)
{
    libxl__test_fdevent *tfe = CONTAINER_OF(abrt,*tfe,abrt);
    STATE_AO_GC(tfe->ao);
    fdevent_complete(egc, tfe, rc);
}

static void fdevent_complete(libxl__egc *egc, libxl__test_fdevent *tfe,
                             int rc)
{
    STATE_AO_GC(tfe->ao);
    tfe_cleanup(gc, tfe);
    libxl__ao_complete(egc, ao, rc);
}

int libxl_test_fdevent(libxl_ctx *ctx, int fd, short events,
                       libxl_asyncop_how *ao_how)
{
    int rc;
    libxl__test_fdevent *tfe;

    AO_CREATE(ctx, 0, ao_how);
    GCNEW(tfe);

    tfe_init(tfe, ao);

    rc = libxl__ev_fd_register(gc, &tfe->fd, tfe_fd_cb, fd, events);
    if (rc) goto out;

    tfe->abrt.ao = ao;
    tfe->abrt.callback = tfe_abrt_cb;
    rc = libxl__ao_abortable_register(&tfe->abrt);
    if (rc) goto out;

    return AO_INPROGRESS;

 out:
    tfe_cleanup(gc, tfe);
    return AO_CREATE_FAIL(rc);
}