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 event_context
*ev
;
27 AvahiTimeout
**timeouts
;
31 struct avahi_poll_context
*ctx
;
34 AvahiWatchEvent latest_event
;
35 AvahiWatchCallback callback
;
40 struct avahi_poll_context
*ctx
;
41 struct timed_event
*te
;
42 AvahiTimeoutCallback callback
;
46 static uint16_t avahi_flags_map_to_tevent(AvahiWatchEvent event
)
48 return ((event
& AVAHI_WATCH_IN
) ? EVENT_FD_READ
: 0)
49 | ((event
& AVAHI_WATCH_OUT
) ? EVENT_FD_WRITE
: 0);
52 static void avahi_fd_handler(struct event_context
*ev
,
53 struct fd_event
*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_get_size(ctx
->watches
)/sizeof(*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
= event_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 event_context
*ev
,
97 struct fd_event
*fde
, uint16_t flags
,
100 AvahiWatch
*watch_ctx
= talloc_get_type_abort(private_data
, AvahiWatch
);
102 watch_ctx
->latest_event
=
103 ((flags
& EVENT_FD_READ
) ? AVAHI_WATCH_IN
: 0)
104 | ((flags
& EVENT_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 if (event
& AVAHI_WATCH_IN
) {
113 event_fd_set_readable(w
->fde
);
115 event_fd_set_not_readable(w
->fde
);
117 if (event
& AVAHI_WATCH_OUT
) {
118 event_fd_set_writeable(w
->fde
);
120 event_fd_set_not_writeable(w
->fde
);
124 static AvahiWatchEvent
avahi_watch_get_events(AvahiWatch
*w
)
126 return w
->latest_event
;
129 static void avahi_watch_free(AvahiWatch
*w
)
132 AvahiWatch
**watches
= w
->ctx
->watches
;
133 struct avahi_poll_context
*ctx
;
135 num_watches
= talloc_get_size(watches
) / sizeof(*watches
);
137 for (i
=0; i
<num_watches
; i
++) {
138 if (w
== watches
[i
]) {
142 if (i
== num_watches
) {
147 memmove(&watches
[i
], &watches
[i
+1],
148 sizeof(*watches
) * (num_watches
- i
- 1));
149 ctx
->watches
= talloc_realloc(ctx
, watches
, AvahiWatch
*,
153 static void avahi_timeout_handler(struct event_context
*ev
,
154 struct timed_event
*te
,
155 struct timeval current_time
,
158 static AvahiTimeout
*avahi_timeout_new(const AvahiPoll
*api
,
159 const struct timeval
*tv
,
160 AvahiTimeoutCallback callback
,
163 struct avahi_poll_context
*ctx
= talloc_get_type_abort(
164 api
->userdata
, struct avahi_poll_context
);
165 int num_timeouts
= talloc_get_size(ctx
->timeouts
)/sizeof(*ctx
->timeouts
);
166 AvahiTimeout
**tmp
, *timeout_ctx
;
168 tmp
= talloc_realloc(ctx
, ctx
->timeouts
, AvahiTimeout
*,
175 timeout_ctx
= talloc(tmp
, AvahiTimeout
);
176 if (timeout_ctx
== NULL
) {
179 ctx
->timeouts
[num_timeouts
] = timeout_ctx
;
181 timeout_ctx
->ctx
= ctx
;
183 timeout_ctx
->te
= NULL
;
185 timeout_ctx
->te
= event_add_timed(ctx
->ev
, timeout_ctx
,
186 *tv
, avahi_timeout_handler
,
188 if (timeout_ctx
->te
== NULL
) {
192 timeout_ctx
->callback
= callback
;
193 timeout_ctx
->userdata
= userdata
;
197 TALLOC_FREE(timeout_ctx
);
198 ctx
->timeouts
= talloc_realloc(ctx
, ctx
->timeouts
, AvahiTimeout
*,
203 static void avahi_timeout_handler(struct event_context
*ev
,
204 struct timed_event
*te
,
205 struct timeval current_time
,
208 AvahiTimeout
*timeout_ctx
= talloc_get_type_abort(
209 private_data
, AvahiTimeout
);
211 TALLOC_FREE(timeout_ctx
->te
);
212 timeout_ctx
->callback(timeout_ctx
, timeout_ctx
->userdata
);
215 static void avahi_timeout_update(AvahiTimeout
*t
, const struct timeval
*tv
)
219 t
->te
= event_add_timed(t
->ctx
->ev
, t
, *tv
, avahi_timeout_handler
, t
);
221 * No failure mode defined here
223 SMB_ASSERT(t
->te
!= NULL
);
226 static void avahi_timeout_free(AvahiTimeout
*t
)
229 AvahiTimeout
**timeouts
= t
->ctx
->timeouts
;
230 struct avahi_poll_context
*ctx
;
232 num_timeouts
= talloc_get_size(timeouts
)/sizeof(*timeouts
);
234 for (i
=0; i
<num_timeouts
; i
++) {
235 if (t
== timeouts
[i
]) {
239 if (i
== num_timeouts
) {
244 memmove(&timeouts
[i
], &timeouts
[i
+1],
245 sizeof(*timeouts
) * (num_timeouts
- i
- 1));
246 ctx
->timeouts
= talloc_realloc(ctx
, timeouts
, AvahiTimeout
*,
250 struct AvahiPoll
*tevent_avahi_poll(TALLOC_CTX
*mem_ctx
,
251 struct event_context
*ev
)
253 struct AvahiPoll
*result
;
254 struct avahi_poll_context
*ctx
;
256 result
= talloc(mem_ctx
, struct AvahiPoll
);
257 if (result
== NULL
) {
260 ctx
= talloc_zero(result
, struct avahi_poll_context
);
267 result
->watch_new
= avahi_watch_new
;
268 result
->watch_update
= avahi_watch_update
;
269 result
->watch_get_events
= avahi_watch_get_events
;
270 result
->watch_free
= avahi_watch_free
;
271 result
->timeout_new
= avahi_timeout_new
;
272 result
->timeout_update
= avahi_timeout_update
;
273 result
->timeout_free
= avahi_timeout_free
;
274 result
->userdata
= ctx
;