xref: /openbsd/usr.sbin/npppd/npppd/accept.c (revision 59408346)
1 /*	$OpenBSD: accept.c,v 1.1 2012/11/13 17:10:40 yasuoka Exp $ */
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/queue.h>
20 #include <sys/time.h>
21 #include <event.h>
22 #include <stdlib.h>
23 
24 #include "accept.h"
25 #include "log.h"
26 
27 
28 struct accept_ev {
29 	LIST_ENTRY(accept_ev)	 entry;
30 	struct event		 ev;
31 	void			(*accept_cb)(int, short, void *);
32 	void			*arg;
33 	int			 fd;
34 };
35 
36 struct {
37 	LIST_HEAD(, accept_ev)	queue;
38 	struct event		evt;
39 } accept_queue;
40 
41 void	accept_arm(void);
42 void	accept_unarm(void);
43 void	accept_cb(int, short, void *);
44 void	accept_timeout(int, short, void *);
45 
46 void
accept_init(void)47 accept_init(void)
48 {
49 	LIST_INIT(&accept_queue.queue);
50 	evtimer_set(&accept_queue.evt, accept_timeout, NULL);
51 }
52 
53 int
accept_add(int fd,void (* cb)(int,short,void *),void * arg)54 accept_add(int fd, void (*cb)(int, short, void *), void *arg)
55 {
56 	struct accept_ev	*av;
57 
58 	if ((av = calloc(1, sizeof(*av))) == NULL)
59 		return -1;
60 	av->fd = fd;
61 	av->accept_cb = cb;
62 	av->arg = arg;
63 	LIST_INSERT_HEAD(&accept_queue.queue, av, entry);
64 
65 	event_set(&av->ev, av->fd, EV_READ, accept_cb, av);
66 	event_add(&av->ev, NULL);
67 
68 	log_debug("accept_add: accepting on fd %d", fd);
69 
70 	return (0);
71 }
72 
73 void
accept_del(int fd)74 accept_del(int fd)
75 {
76 	struct accept_ev	*av;
77 
78 	LIST_FOREACH(av, &accept_queue.queue, entry)
79 		if (av->fd == fd) {
80 			log_debug("accept_del: %i removed from queue", fd);
81 			event_del(&av->ev);
82 			LIST_REMOVE(av, entry);
83 			free(av);
84 			return;
85 		}
86 }
87 
88 void
accept_pause(void)89 accept_pause(void)
90 {
91 	struct timeval evtpause = { 1, 0 };
92 
93 	log_debug("accept_pause");
94 	accept_unarm();
95 	evtimer_add(&accept_queue.evt, &evtpause);
96 }
97 
98 void
accept_unpause(void)99 accept_unpause(void)
100 {
101 	if (evtimer_pending(&accept_queue.evt, NULL)) {
102 		log_debug("accept_unpause");
103 		evtimer_del(&accept_queue.evt);
104 		accept_arm();
105 	}
106 }
107 
108 void
accept_arm(void)109 accept_arm(void)
110 {
111 	struct accept_ev	*av;
112 	LIST_FOREACH(av, &accept_queue.queue, entry)
113 		event_add(&av->ev, NULL);
114 }
115 
116 void
accept_unarm(void)117 accept_unarm(void)
118 {
119 	struct accept_ev	*av;
120 	LIST_FOREACH(av, &accept_queue.queue, entry)
121 		event_del(&av->ev);
122 }
123 
124 void
accept_cb(int fd,short event,void * arg)125 accept_cb(int fd, short event, void *arg)
126 {
127 	struct accept_ev	*av = arg;
128 	event_add(&av->ev, NULL);
129 	av->accept_cb(fd, event, av->arg);
130 }
131 
132 void
accept_timeout(int fd,short event,void * bula)133 accept_timeout(int fd, short event, void *bula)
134 {
135 	log_debug("accept_timeout");
136 	accept_arm();
137 }
138