]>
Commit | Line | Data |
---|---|---|
8429abe0 RW |
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 | ||
eac6e3f0 | 19 | #include <zebra.h> |
8429abe0 RW |
20 | |
21 | #include "ldpd.h" | |
22 | #include "ldpe.h" | |
23 | #include "log.h" | |
24 | ||
25 | struct accept_ev { | |
26 | LIST_ENTRY(accept_ev) entry; | |
eac6e3f0 RW |
27 | struct thread *ev; |
28 | int (*accept_cb)(struct thread *); | |
8429abe0 RW |
29 | void *arg; |
30 | int fd; | |
31 | }; | |
32 | ||
33 | struct { | |
eac6e3f0 RW |
34 | LIST_HEAD(, accept_ev) queue; |
35 | struct thread *evt; | |
8429abe0 RW |
36 | } accept_queue; |
37 | ||
38 | static void accept_arm(void); | |
39 | static void accept_unarm(void); | |
eac6e3f0 RW |
40 | static int accept_cb(struct thread *); |
41 | static int accept_timeout(struct thread *); | |
8429abe0 RW |
42 | |
43 | void | |
44 | accept_init(void) | |
45 | { | |
46 | LIST_INIT(&accept_queue.queue); | |
8429abe0 RW |
47 | } |
48 | ||
49 | int | |
eac6e3f0 | 50 | accept_add(int fd, int (*cb)(struct thread *), void *arg) |
8429abe0 RW |
51 | { |
52 | struct accept_ev *av; | |
53 | ||
54 | if ((av = calloc(1, sizeof(*av))) == NULL) | |
55 | return (-1); | |
56 | av->fd = fd; | |
57 | av->accept_cb = cb; | |
58 | av->arg = arg; | |
59 | LIST_INSERT_HEAD(&accept_queue.queue, av, entry); | |
60 | ||
66e78ae6 QY |
61 | av->ev = NULL; |
62 | thread_add_read(master, accept_cb, av, av->fd, &av->ev); | |
8429abe0 RW |
63 | |
64 | log_debug("%s: accepting on fd %d", __func__, fd); | |
65 | ||
66 | return (0); | |
67 | } | |
68 | ||
69 | void | |
70 | accept_del(int fd) | |
71 | { | |
72 | struct accept_ev *av; | |
73 | ||
74 | LIST_FOREACH(av, &accept_queue.queue, entry) | |
75 | if (av->fd == fd) { | |
76 | log_debug("%s: %d removed from queue", __func__, fd); | |
eac6e3f0 | 77 | THREAD_READ_OFF(av->ev); |
8429abe0 RW |
78 | LIST_REMOVE(av, entry); |
79 | free(av); | |
80 | return; | |
81 | } | |
82 | } | |
83 | ||
84 | void | |
85 | accept_pause(void) | |
86 | { | |
8429abe0 RW |
87 | log_debug(__func__); |
88 | accept_unarm(); | |
66e78ae6 QY |
89 | accept_queue.evt = NULL; |
90 | thread_add_timer(master, accept_timeout, NULL, 1, &accept_queue.evt); | |
8429abe0 RW |
91 | } |
92 | ||
93 | void | |
94 | accept_unpause(void) | |
95 | { | |
eac6e3f0 | 96 | if (accept_queue.evt != NULL) { |
8429abe0 | 97 | log_debug(__func__); |
eac6e3f0 | 98 | THREAD_TIMER_OFF(accept_queue.evt); |
8429abe0 RW |
99 | accept_arm(); |
100 | } | |
101 | } | |
102 | ||
103 | static void | |
104 | accept_arm(void) | |
105 | { | |
106 | struct accept_ev *av; | |
66e78ae6 QY |
107 | LIST_FOREACH(av, &accept_queue.queue, entry) { |
108 | av->ev = NULL; | |
109 | thread_add_read(master, accept_cb, av, av->fd, &av->ev); | |
110 | } | |
8429abe0 RW |
111 | } |
112 | ||
113 | static void | |
114 | accept_unarm(void) | |
115 | { | |
116 | struct accept_ev *av; | |
117 | LIST_FOREACH(av, &accept_queue.queue, entry) | |
eac6e3f0 | 118 | THREAD_READ_OFF(av->ev); |
8429abe0 RW |
119 | } |
120 | ||
eac6e3f0 RW |
121 | static int |
122 | accept_cb(struct thread *thread) | |
8429abe0 | 123 | { |
eac6e3f0 | 124 | struct accept_ev *av = THREAD_ARG(thread); |
66e78ae6 QY |
125 | av->ev = NULL; |
126 | thread_add_read(master, accept_cb, av, av->fd, &av->ev); | |
eac6e3f0 RW |
127 | av->accept_cb(thread); |
128 | ||
129 | return (0); | |
8429abe0 RW |
130 | } |
131 | ||
eac6e3f0 RW |
132 | static int |
133 | accept_timeout(struct thread *thread) | |
8429abe0 | 134 | { |
eac6e3f0 RW |
135 | accept_queue.evt = NULL; |
136 | ||
8429abe0 RW |
137 | log_debug(__func__); |
138 | accept_arm(); | |
eac6e3f0 RW |
139 | |
140 | return (0); | |
8429abe0 | 141 | } |