]>
Commit | Line | Data |
---|---|---|
acddc0ed | 1 | // SPDX-License-Identifier: ISC |
8429abe0 RW |
2 | /* $OpenBSD$ */ |
3 | ||
4 | /* | |
5 | * Copyright (c) 2012 Claudio Jeker <claudio@openbsd.org> | |
8429abe0 RW |
6 | */ |
7 | ||
eac6e3f0 | 8 | #include <zebra.h> |
8429abe0 RW |
9 | |
10 | #include "ldpd.h" | |
11 | #include "ldpe.h" | |
12 | #include "log.h" | |
13 | ||
14 | struct accept_ev { | |
15 | LIST_ENTRY(accept_ev) entry; | |
eac6e3f0 | 16 | struct thread *ev; |
cc9f21da | 17 | void (*accept_cb)(struct thread *); |
8429abe0 RW |
18 | void *arg; |
19 | int fd; | |
20 | }; | |
21 | ||
22 | struct { | |
eac6e3f0 RW |
23 | LIST_HEAD(, accept_ev) queue; |
24 | struct thread *evt; | |
8429abe0 RW |
25 | } accept_queue; |
26 | ||
27 | static void accept_arm(void); | |
28 | static void accept_unarm(void); | |
cc9f21da DS |
29 | static void accept_cb(struct thread *); |
30 | static void accept_timeout(struct thread *); | |
8429abe0 RW |
31 | |
32 | void | |
33 | accept_init(void) | |
34 | { | |
35 | LIST_INIT(&accept_queue.queue); | |
8429abe0 RW |
36 | } |
37 | ||
cc9f21da | 38 | int accept_add(int fd, void (*cb)(struct thread *), void *arg) |
8429abe0 RW |
39 | { |
40 | struct accept_ev *av; | |
41 | ||
42 | if ((av = calloc(1, sizeof(*av))) == NULL) | |
43 | return (-1); | |
44 | av->fd = fd; | |
45 | av->accept_cb = cb; | |
46 | av->arg = arg; | |
47 | LIST_INSERT_HEAD(&accept_queue.queue, av, entry); | |
48 | ||
66e78ae6 | 49 | thread_add_read(master, accept_cb, av, av->fd, &av->ev); |
8429abe0 RW |
50 | |
51 | log_debug("%s: accepting on fd %d", __func__, fd); | |
52 | ||
53 | return (0); | |
54 | } | |
55 | ||
56 | void | |
57 | accept_del(int fd) | |
58 | { | |
59 | struct accept_ev *av; | |
60 | ||
61 | LIST_FOREACH(av, &accept_queue.queue, entry) | |
62 | if (av->fd == fd) { | |
63 | log_debug("%s: %d removed from queue", __func__, fd); | |
2783a692 | 64 | THREAD_OFF(av->ev); |
8429abe0 RW |
65 | LIST_REMOVE(av, entry); |
66 | free(av); | |
67 | return; | |
68 | } | |
69 | } | |
70 | ||
71 | void | |
72 | accept_pause(void) | |
73 | { | |
8429abe0 RW |
74 | log_debug(__func__); |
75 | accept_unarm(); | |
66e78ae6 | 76 | thread_add_timer(master, accept_timeout, NULL, 1, &accept_queue.evt); |
8429abe0 RW |
77 | } |
78 | ||
79 | void | |
80 | accept_unpause(void) | |
81 | { | |
eac6e3f0 | 82 | if (accept_queue.evt != NULL) { |
8429abe0 | 83 | log_debug(__func__); |
2783a692 | 84 | THREAD_OFF(accept_queue.evt); |
8429abe0 RW |
85 | accept_arm(); |
86 | } | |
87 | } | |
88 | ||
89 | static void | |
90 | accept_arm(void) | |
91 | { | |
92 | struct accept_ev *av; | |
66e78ae6 | 93 | LIST_FOREACH(av, &accept_queue.queue, entry) { |
66e78ae6 QY |
94 | thread_add_read(master, accept_cb, av, av->fd, &av->ev); |
95 | } | |
8429abe0 RW |
96 | } |
97 | ||
98 | static void | |
99 | accept_unarm(void) | |
100 | { | |
101 | struct accept_ev *av; | |
102 | LIST_FOREACH(av, &accept_queue.queue, entry) | |
2783a692 | 103 | THREAD_OFF(av->ev); |
8429abe0 RW |
104 | } |
105 | ||
cc9f21da | 106 | static void accept_cb(struct thread *thread) |
8429abe0 | 107 | { |
eac6e3f0 | 108 | struct accept_ev *av = THREAD_ARG(thread); |
66e78ae6 | 109 | thread_add_read(master, accept_cb, av, av->fd, &av->ev); |
eac6e3f0 | 110 | av->accept_cb(thread); |
8429abe0 RW |
111 | } |
112 | ||
cc9f21da | 113 | static void accept_timeout(struct thread *thread) |
8429abe0 | 114 | { |
eac6e3f0 RW |
115 | accept_queue.evt = NULL; |
116 | ||
8429abe0 RW |
117 | log_debug(__func__); |
118 | accept_arm(); | |
119 | } |