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