2 Unix SMB/CIFS implementation.
3 Connect avahi to lib/tevents
4 Copyright (C) Volker Lendecke 2009
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
22 #include <avahi-common/watch.h>
24 struct avahi_poll_context
{
25 struct tevent_context
*ev
;
27 AvahiTimeout
**timeouts
;
31 struct avahi_poll_context
*ctx
;
32 struct tevent_fd
*fde
;
34 AvahiWatchEvent latest_event
;
35 AvahiWatchCallback callback
;
40 struct avahi_poll_context
*ctx
;
41 struct tevent_timer
*te
;
42 AvahiTimeoutCallback callback
;
46 static uint16_t avahi_flags_map_to_tevent(AvahiWatchEvent event
)
48 return ((event
& AVAHI_WATCH_IN
) ? TEVENT_FD_READ
: 0)
49 | ((event
& AVAHI_WATCH_OUT
) ? TEVENT_FD_WRITE
: 0);
52 static void avahi_fd_handler(struct tevent_context
*ev
,
53 struct tevent_fd
*fde
, uint16_t flags
,
56 static AvahiWatch
*avahi_watch_new(const AvahiPoll
*api
, int fd
,
57 AvahiWatchEvent event
,
58 AvahiWatchCallback callback
,
61 struct avahi_poll_context
*ctx
= talloc_get_type_abort(
62 api
->userdata
, struct avahi_poll_context
);
63 int num_watches
= talloc_array_length(ctx
->watches
);
64 AvahiWatch
**tmp
, *watch_ctx
;
66 tmp
= talloc_realloc(ctx
, ctx
->watches
, AvahiWatch
*, num_watches
+ 1);
72 watch_ctx
= talloc(tmp
, AvahiWatch
);
73 if (watch_ctx
== NULL
) {
76 ctx
->watches
[num_watches
] = watch_ctx
;
79 watch_ctx
->fde
= tevent_add_fd(ctx
->ev
, watch_ctx
, fd
,
80 avahi_flags_map_to_tevent(event
),
81 avahi_fd_handler
, watch_ctx
);
82 if (watch_ctx
->fde
== NULL
) {
85 watch_ctx
->callback
= callback
;
86 watch_ctx
->userdata
= userdata
;
90 TALLOC_FREE(watch_ctx
);
91 ctx
->watches
= talloc_realloc(ctx
, ctx
->watches
, AvahiWatch
*,
96 static void avahi_fd_handler(struct tevent_context
*ev
,
97 struct tevent_fd
*fde
, uint16_t flags
,
100 AvahiWatch
*watch_ctx
= talloc_get_type_abort(private_data
, AvahiWatch
);
102 watch_ctx
->latest_event
=
103 ((flags
& TEVENT_FD_READ
) ? AVAHI_WATCH_IN
: 0)
104 | ((flags
& TEVENT_FD_WRITE
) ? AVAHI_WATCH_OUT
: 0);
106 watch_ctx
->callback(watch_ctx
, watch_ctx
->fd
, watch_ctx
->latest_event
,
107 watch_ctx
->userdata
);
110 static void avahi_watch_update(AvahiWatch
*w
, AvahiWatchEvent event
)
112 tevent_fd_set_flags(w
->fde
, avahi_flags_map_to_tevent(event
));
115 static AvahiWatchEvent
avahi_watch_get_events(AvahiWatch
*w
)
117 return w
->latest_event
;
120 static void avahi_watch_free(AvahiWatch
*w
)
123 AvahiWatch
**watches
= w
->ctx
->watches
;
124 struct avahi_poll_context
*ctx
;
126 num_watches
= talloc_array_length(watches
);
128 for (i
=0; i
<num_watches
; i
++) {
129 if (w
== watches
[i
]) {
133 if (i
== num_watches
) {
138 memmove(&watches
[i
], &watches
[i
+1],
139 sizeof(*watches
) * (num_watches
- i
- 1));
140 ctx
->watches
= talloc_realloc(ctx
, watches
, AvahiWatch
*,
144 static void avahi_timeout_handler(struct tevent_context
*ev
,
145 struct tevent_timer
*te
,
146 struct timeval current_time
,
149 static AvahiTimeout
*avahi_timeout_new(const AvahiPoll
*api
,
150 const struct timeval
*tv
,
151 AvahiTimeoutCallback callback
,
154 struct avahi_poll_context
*ctx
= talloc_get_type_abort(
155 api
->userdata
, struct avahi_poll_context
);
156 int num_timeouts
= talloc_array_length(ctx
->timeouts
);
157 AvahiTimeout
**tmp
, *timeout_ctx
;
159 tmp
= talloc_realloc(ctx
, ctx
->timeouts
, AvahiTimeout
*,
166 timeout_ctx
= talloc(tmp
, AvahiTimeout
);
167 if (timeout_ctx
== NULL
) {
170 ctx
->timeouts
[num_timeouts
] = timeout_ctx
;
172 timeout_ctx
->ctx
= ctx
;
174 timeout_ctx
->te
= NULL
;
176 timeout_ctx
->te
= tevent_add_timer(ctx
->ev
, timeout_ctx
,
177 *tv
, avahi_timeout_handler
,
179 if (timeout_ctx
->te
== NULL
) {
183 timeout_ctx
->callback
= callback
;
184 timeout_ctx
->userdata
= userdata
;
188 TALLOC_FREE(timeout_ctx
);
189 ctx
->timeouts
= talloc_realloc(ctx
, ctx
->timeouts
, AvahiTimeout
*,
194 static void avahi_timeout_handler(struct tevent_context
*ev
,
195 struct tevent_timer
*te
,
196 struct timeval current_time
,
199 AvahiTimeout
*timeout_ctx
= talloc_get_type_abort(
200 private_data
, AvahiTimeout
);
202 TALLOC_FREE(timeout_ctx
->te
);
203 timeout_ctx
->callback(timeout_ctx
, timeout_ctx
->userdata
);
206 static void avahi_timeout_update(AvahiTimeout
*t
, const struct timeval
*tv
)
217 t
->te
= tevent_add_timer(t
->ctx
->ev
, t
, *tv
, avahi_timeout_handler
, t
);
219 * No failure mode defined here
221 SMB_ASSERT(t
->te
!= NULL
);
224 static void avahi_timeout_free(AvahiTimeout
*t
)
227 AvahiTimeout
**timeouts
= t
->ctx
->timeouts
;
228 struct avahi_poll_context
*ctx
;
230 num_timeouts
= talloc_array_length(timeouts
);
232 for (i
=0; i
<num_timeouts
; i
++) {
233 if (t
== timeouts
[i
]) {
237 if (i
== num_timeouts
) {
242 memmove(&timeouts
[i
], &timeouts
[i
+1],
243 sizeof(*timeouts
) * (num_timeouts
- i
- 1));
244 ctx
->timeouts
= talloc_realloc(ctx
, timeouts
, AvahiTimeout
*,
248 struct AvahiPoll
*tevent_avahi_poll(TALLOC_CTX
*mem_ctx
,
249 struct tevent_context
*ev
)
251 struct AvahiPoll
*result
;
252 struct avahi_poll_context
*ctx
;
254 result
= talloc(mem_ctx
, struct AvahiPoll
);
255 if (result
== NULL
) {
258 ctx
= talloc_zero(result
, struct avahi_poll_context
);
265 result
->watch_new
= avahi_watch_new
;
266 result
->watch_update
= avahi_watch_update
;
267 result
->watch_get_events
= avahi_watch_get_events
;
268 result
->watch_free
= avahi_watch_free
;
269 result
->timeout_new
= avahi_timeout_new
;
270 result
->timeout_update
= avahi_timeout_update
;
271 result
->timeout_free
= avahi_timeout_free
;
272 result
->userdata
= ctx
;