1*59408346Syasuoka /* $OpenBSD: accept.c,v 1.1 2012/11/13 17:10:40 yasuoka Exp $ */
2*59408346Syasuoka
3*59408346Syasuoka /*
4*59408346Syasuoka * Copyright (c) 2012 Claudio Jeker <claudio@openbsd.org>
5*59408346Syasuoka *
6*59408346Syasuoka * Permission to use, copy, modify, and distribute this software for any
7*59408346Syasuoka * purpose with or without fee is hereby granted, provided that the above
8*59408346Syasuoka * copyright notice and this permission notice appear in all copies.
9*59408346Syasuoka *
10*59408346Syasuoka * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11*59408346Syasuoka * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12*59408346Syasuoka * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13*59408346Syasuoka * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14*59408346Syasuoka * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15*59408346Syasuoka * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16*59408346Syasuoka * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17*59408346Syasuoka */
18*59408346Syasuoka
19*59408346Syasuoka #include <sys/queue.h>
20*59408346Syasuoka #include <sys/time.h>
21*59408346Syasuoka #include <event.h>
22*59408346Syasuoka #include <stdlib.h>
23*59408346Syasuoka
24*59408346Syasuoka #include "accept.h"
25*59408346Syasuoka #include "log.h"
26*59408346Syasuoka
27*59408346Syasuoka
28*59408346Syasuoka struct accept_ev {
29*59408346Syasuoka LIST_ENTRY(accept_ev) entry;
30*59408346Syasuoka struct event ev;
31*59408346Syasuoka void (*accept_cb)(int, short, void *);
32*59408346Syasuoka void *arg;
33*59408346Syasuoka int fd;
34*59408346Syasuoka };
35*59408346Syasuoka
36*59408346Syasuoka struct {
37*59408346Syasuoka LIST_HEAD(, accept_ev) queue;
38*59408346Syasuoka struct event evt;
39*59408346Syasuoka } accept_queue;
40*59408346Syasuoka
41*59408346Syasuoka void accept_arm(void);
42*59408346Syasuoka void accept_unarm(void);
43*59408346Syasuoka void accept_cb(int, short, void *);
44*59408346Syasuoka void accept_timeout(int, short, void *);
45*59408346Syasuoka
46*59408346Syasuoka void
accept_init(void)47*59408346Syasuoka accept_init(void)
48*59408346Syasuoka {
49*59408346Syasuoka LIST_INIT(&accept_queue.queue);
50*59408346Syasuoka evtimer_set(&accept_queue.evt, accept_timeout, NULL);
51*59408346Syasuoka }
52*59408346Syasuoka
53*59408346Syasuoka int
accept_add(int fd,void (* cb)(int,short,void *),void * arg)54*59408346Syasuoka accept_add(int fd, void (*cb)(int, short, void *), void *arg)
55*59408346Syasuoka {
56*59408346Syasuoka struct accept_ev *av;
57*59408346Syasuoka
58*59408346Syasuoka if ((av = calloc(1, sizeof(*av))) == NULL)
59*59408346Syasuoka return -1;
60*59408346Syasuoka av->fd = fd;
61*59408346Syasuoka av->accept_cb = cb;
62*59408346Syasuoka av->arg = arg;
63*59408346Syasuoka LIST_INSERT_HEAD(&accept_queue.queue, av, entry);
64*59408346Syasuoka
65*59408346Syasuoka event_set(&av->ev, av->fd, EV_READ, accept_cb, av);
66*59408346Syasuoka event_add(&av->ev, NULL);
67*59408346Syasuoka
68*59408346Syasuoka log_debug("accept_add: accepting on fd %d", fd);
69*59408346Syasuoka
70*59408346Syasuoka return (0);
71*59408346Syasuoka }
72*59408346Syasuoka
73*59408346Syasuoka void
accept_del(int fd)74*59408346Syasuoka accept_del(int fd)
75*59408346Syasuoka {
76*59408346Syasuoka struct accept_ev *av;
77*59408346Syasuoka
78*59408346Syasuoka LIST_FOREACH(av, &accept_queue.queue, entry)
79*59408346Syasuoka if (av->fd == fd) {
80*59408346Syasuoka log_debug("accept_del: %i removed from queue", fd);
81*59408346Syasuoka event_del(&av->ev);
82*59408346Syasuoka LIST_REMOVE(av, entry);
83*59408346Syasuoka free(av);
84*59408346Syasuoka return;
85*59408346Syasuoka }
86*59408346Syasuoka }
87*59408346Syasuoka
88*59408346Syasuoka void
accept_pause(void)89*59408346Syasuoka accept_pause(void)
90*59408346Syasuoka {
91*59408346Syasuoka struct timeval evtpause = { 1, 0 };
92*59408346Syasuoka
93*59408346Syasuoka log_debug("accept_pause");
94*59408346Syasuoka accept_unarm();
95*59408346Syasuoka evtimer_add(&accept_queue.evt, &evtpause);
96*59408346Syasuoka }
97*59408346Syasuoka
98*59408346Syasuoka void
accept_unpause(void)99*59408346Syasuoka accept_unpause(void)
100*59408346Syasuoka {
101*59408346Syasuoka if (evtimer_pending(&accept_queue.evt, NULL)) {
102*59408346Syasuoka log_debug("accept_unpause");
103*59408346Syasuoka evtimer_del(&accept_queue.evt);
104*59408346Syasuoka accept_arm();
105*59408346Syasuoka }
106*59408346Syasuoka }
107*59408346Syasuoka
108*59408346Syasuoka void
accept_arm(void)109*59408346Syasuoka accept_arm(void)
110*59408346Syasuoka {
111*59408346Syasuoka struct accept_ev *av;
112*59408346Syasuoka LIST_FOREACH(av, &accept_queue.queue, entry)
113*59408346Syasuoka event_add(&av->ev, NULL);
114*59408346Syasuoka }
115*59408346Syasuoka
116*59408346Syasuoka void
accept_unarm(void)117*59408346Syasuoka accept_unarm(void)
118*59408346Syasuoka {
119*59408346Syasuoka struct accept_ev *av;
120*59408346Syasuoka LIST_FOREACH(av, &accept_queue.queue, entry)
121*59408346Syasuoka event_del(&av->ev);
122*59408346Syasuoka }
123*59408346Syasuoka
124*59408346Syasuoka void
accept_cb(int fd,short event,void * arg)125*59408346Syasuoka accept_cb(int fd, short event, void *arg)
126*59408346Syasuoka {
127*59408346Syasuoka struct accept_ev *av = arg;
128*59408346Syasuoka event_add(&av->ev, NULL);
129*59408346Syasuoka av->accept_cb(fd, event, av->arg);
130*59408346Syasuoka }
131*59408346Syasuoka
132*59408346Syasuoka void
accept_timeout(int fd,short event,void * bula)133*59408346Syasuoka accept_timeout(int fd, short event, void *bula)
134*59408346Syasuoka {
135*59408346Syasuoka log_debug("accept_timeout");
136*59408346Syasuoka accept_arm();
137*59408346Syasuoka }
138