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)
226
t->te = event_add_timed(t->ctx->ev, t, *tv, avahi_timeout_handler, t);
228
* No failure mode defined here
230
SMB_ASSERT(t->te != NULL);
233
static void avahi_timeout_free(AvahiTimeout *t)
236
AvahiTimeout **timeouts = t->ctx->timeouts;
237
struct avahi_poll_context *ctx;
239
num_timeouts = talloc_get_size(timeouts)/sizeof(*timeouts);
241
for (i=0; i<num_timeouts; i++) {
242
if (t == timeouts[i]) {
246
if (i == num_timeouts) {
251
memmove(&timeouts[i], &timeouts[i+1],
252
sizeof(*timeouts) * (num_timeouts - i - 1));
253
ctx->timeouts = talloc_realloc(ctx, timeouts, AvahiTimeout *,
257
struct AvahiPoll *tevent_avahi_poll(TALLOC_CTX *mem_ctx,
258
struct event_context *ev)
260
struct AvahiPoll *result;
261
struct avahi_poll_context *ctx;
263
result = talloc(mem_ctx, struct AvahiPoll);
264
if (result == NULL) {
267
ctx = talloc_zero(result, struct avahi_poll_context);
274
result->watch_new = avahi_watch_new;
275
result->watch_update = avahi_watch_update;
276
result->watch_get_events = avahi_watch_get_events;
277
result->watch_free = avahi_watch_free;
278
result->timeout_new = avahi_timeout_new;
279
result->timeout_update = avahi_timeout_update;
280
result->timeout_free = avahi_timeout_free;
281
result->userdata = ctx;