#ifndef SUDO_EVENT_H
#define SUDO_EVENT_H
#include "sudo_queue.h"
#define SUDO_EV_TIMEOUT 0x01
#define SUDO_EV_READ 0x02
#define SUDO_EV_WRITE 0x04
#define SUDO_EV_PERSIST 0x08
#define SUDO_EVQ_INSERTED 0x01
#define SUDO_EVQ_ACTIVE 0x02
#define SUDO_EVQ_TIMEOUTS 0x04
#define SUDO_EVLOOP_ONCE 0x01
#define SUDO_EVLOOP_NONBLOCK 0x02
#define SUDO_EVBASE_LOOPONCE SUDO_EVLOOP_ONCE
#define SUDO_EVBASE_LOOPEXIT 0x02
#define SUDO_EVBASE_LOOPBREAK 0x04
#define SUDO_EVBASE_LOOPCONT 0x08
#define SUDO_EVBASE_GOT_EXIT 0x10
#define SUDO_EVBASE_GOT_BREAK 0x20
#define SUDO_EVBASE_GOT_MASK 0xf0
typedef void (*sudo_ev_callback_t)(int fd, int what, void *closure);
struct sudo_event {
TAILQ_ENTRY(sudo_event) entries;
TAILQ_ENTRY(sudo_event) active_entries;
TAILQ_ENTRY(sudo_event) timeouts_entries;
struct sudo_event_base *base;
int fd;
short events;
short revents;
short flags;
short pfd_idx;
sudo_ev_callback_t callback;
struct timeval timeout;
void *closure;
};
TAILQ_HEAD(sudo_event_list, sudo_event);
struct sudo_event_base {
struct sudo_event_list events;
struct sudo_event_list active;
struct sudo_event_list timeouts;
#ifdef HAVE_POLL
struct pollfd *pfds;
int pfd_max;
int pfd_high;
int pfd_free;
#else
fd_set *readfds_in;
fd_set *writefds_in;
fd_set *readfds_out;
fd_set *writefds_out;
int maxfd;
int highfd;
#endif
unsigned int flags;
};
__dso_public struct sudo_event_base *sudo_ev_base_alloc_v1(void);
#define sudo_ev_base_alloc() sudo_ev_base_alloc_v1()
__dso_public void sudo_ev_base_free_v1(struct sudo_event_base *base);
#define sudo_ev_base_free(_a) sudo_ev_base_free_v1((_a))
__dso_public struct sudo_event *sudo_ev_alloc_v1(int fd, short events, sudo_ev_callback_t callback, void *closure);
#define sudo_ev_alloc(_a, _b, _c, _d) sudo_ev_alloc_v1((_a), (_b), (_c), (_d))
__dso_public void sudo_ev_free_v1(struct sudo_event *ev);
#define sudo_ev_free(_a) sudo_ev_free_v1((_a))
__dso_public int sudo_ev_add_v1(struct sudo_event_base *head, struct sudo_event *ev, struct timeval *timo, bool tohead);
#define sudo_ev_add(_a, _b, _c, _d) sudo_ev_add_v1((_a), (_b), (_c), (_d))
__dso_public int sudo_ev_del_v1(struct sudo_event_base *head, struct sudo_event *ev);
#define sudo_ev_del(_a, _b) sudo_ev_del_v1((_a), (_b))
__dso_public int sudo_ev_loop_v1(struct sudo_event_base *head, int flags);
#define sudo_ev_loop(_a, _b) sudo_ev_loop_v1((_a), (_b))
__dso_public int sudo_ev_get_timeleft_v1(struct sudo_event *ev, struct timeval *tv);
#define sudo_ev_get_timeleft(_a, _b) sudo_ev_get_timeleft_v1((_a), (_b))
__dso_public void sudo_ev_loopexit_v1(struct sudo_event_base *base);
#define sudo_ev_loopexit(_a) sudo_ev_loopexit_v1((_a))
__dso_public void sudo_ev_loopbreak_v1(struct sudo_event_base *base);
#define sudo_ev_loopbreak(_a) sudo_ev_loopbreak_v1((_a))
__dso_public void sudo_ev_loopcontinue_v1(struct sudo_event_base *base);
#define sudo_ev_loopcontinue(_a) sudo_ev_loopcontinue_v1((_a))
__dso_public bool sudo_ev_got_exit_v1(struct sudo_event_base *base);
#define sudo_ev_got_exit(_a) sudo_ev_got_exit_v1((_a))
__dso_public bool sudo_ev_got_break_v1(struct sudo_event_base *base);
#define sudo_ev_got_break(_a) sudo_ev_got_break_v1((_a))
#define sudo_ev_get_fd(_ev) ((_ev) ? (_ev)->fd : -1)
#define sudo_ev_get_timeout(_ev) \
(ISSET((_ev)->flags, SUDO_EVQ_TIMEOUTS) ? &(_ev)->timeout : NULL)
#define sudo_ev_get_base(_ev) ((_ev) ? (_ev)->base : NULL)
#define sudo_ev_self_cbarg() ((void *)-1)
void sudo_ev_activate(struct sudo_event_base *base, struct sudo_event *ev);
int sudo_ev_base_alloc_impl(struct sudo_event_base *base);
void sudo_ev_base_free_impl(struct sudo_event_base *base);
int sudo_ev_add_impl(struct sudo_event_base *base, struct sudo_event *ev);
int sudo_ev_del_impl(struct sudo_event_base *base, struct sudo_event *ev);
int sudo_ev_scan_impl(struct sudo_event_base *base, int flags);
#endif