lib: Add poll_funcs
authorVolker Lendecke <vl@samba.org>
Mon, 24 Feb 2014 11:43:51 +0000 (11:43 +0000)
committerJeremy Allison <jra@samba.org>
Wed, 23 Apr 2014 20:33:08 +0000 (22:33 +0200)
This is an abstraction for a tevent loop. It will be used in low-level
messaging with the goal to make low-leve our low-level messaging routines
usable also for other projects which are not based on tevent.

Signed-off-by: Volker Lendecke <vl@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
source3/lib/poll_funcs/poll_funcs.h [new file with mode: 0644]
source3/lib/poll_funcs/poll_funcs_tevent.c [new file with mode: 0644]
source3/lib/poll_funcs/poll_funcs_tevent.h [new file with mode: 0644]
source3/lib/poll_funcs/wscript_build [new file with mode: 0644]
source3/wscript_build

diff --git a/source3/lib/poll_funcs/poll_funcs.h b/source3/lib/poll_funcs/poll_funcs.h
new file mode 100644 (file)
index 0000000..b23e7d9
--- /dev/null
@@ -0,0 +1,131 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * Copyright (C) Volker Lendecke 2013
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/**
+ * @file poll_funcs.h
+ *
+ * @brief event loop abstraction
+ */
+
+/*
+ * This is inspired by AvahiWatch, the avahi event loop abstraction.
+ */
+
+#ifndef __POLL_FUNCS_H__
+#define __POLL_FUNCS_H__
+
+#include "replace.h"
+
+/**
+ * poll_watch and poll_timeout are undefined here, every implementation can
+ * implement its own structures.
+ */
+
+struct poll_watch;
+struct poll_timeout;
+
+struct poll_funcs {
+
+       /**
+        * @brief Create a new file descriptor watch
+        *
+        * @param[in] funcs The callback array
+        * @param[in] fd The fd to watch
+        * @param[in] events POLLIN and POLLOUT or'ed together
+        * @param[in] callback Function to call by the implementation
+        * @param[in] private_data Pointer to give back to callback
+        *
+        * @return A new poll_watch struct
+        */
+
+       struct poll_watch *(*watch_new)(
+               const struct poll_funcs *funcs, int fd, short events,
+               void (*callback)(struct poll_watch *w, int fd,
+                                short events, void *private_data),
+               void *private_data);
+
+       /**
+        * @brief Change the watched events for a struct poll_watch
+        *
+        * @param[in] w The poll_watch to change
+        * @param[in] events new POLLIN and POLLOUT or'ed together
+        */
+
+       void (*watch_update)(struct poll_watch *w, short events);
+
+       /**
+        * @brief Read events currently watched
+        *
+        * @param[in] w The poll_watch to inspect
+        *
+        * @returns The events currently watched
+        */
+
+       short (*watch_get_events)(struct poll_watch *w);
+
+       /**
+        * @brief Free a struct poll_watch
+        *
+        * @param[in] w The poll_watch struct to free
+        */
+
+       void (*watch_free)(struct poll_watch *w);
+
+
+       /**
+        * @brief Create a new timeout watch
+        *
+        * @param[in] funcs The callback array
+        * @param[in] tv The time when the timeout should trigger
+        * @param[in] callback Function to call at time "ts"
+        * @param[in] private_data Pointer to give back to callback
+        *
+        * @return A new poll_timeout struct
+        */
+
+       struct poll_timeout *(*timeout_new)(
+               const struct poll_funcs *funcs, const struct timeval *tv,
+               void (*callback)(struct poll_timeout *t, void *private_data),
+               void *private_data);
+
+       /**
+        * @brief Change the timeout of a watch
+        *
+        * @param[in] t The timeout watch to change
+        * @param[in] ts The new trigger time
+        */
+
+       void (*timeout_update)(struct poll_timeout *t,
+                              const struct timespec *ts);
+
+       /**
+        * @brief Free a poll_timeout
+        *
+        * @param[in] t The poll_timeout to free
+        */
+
+       void (*timeout_free)(struct poll_timeout *t);
+
+       /**
+        * @brief private data for use by the implmentation
+        */
+
+       void *private_data;
+};
+
+#endif
diff --git a/source3/lib/poll_funcs/poll_funcs_tevent.c b/source3/lib/poll_funcs/poll_funcs_tevent.c
new file mode 100644 (file)
index 0000000..6e75042
--- /dev/null
@@ -0,0 +1,143 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * Copyright (C) Volker Lendecke 2013
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "poll_funcs_tevent.h"
+#include "tevent.h"
+#include "system/select.h"
+
+struct poll_watch {
+       struct tevent_fd *fde;
+       int fd;
+       void (*callback)(struct poll_watch *w, int fd, short events,
+                        void *private_data);
+       void *private_data;
+};
+
+static uint16_t poll_events_to_tevent(short events)
+{
+       uint16_t ret = 0;
+
+       if (events & POLLIN) {
+               ret |= TEVENT_FD_READ;
+       }
+       if (events & POLLOUT) {
+               ret |= TEVENT_FD_WRITE;
+       }
+       return ret;
+}
+
+static short tevent_to_poll_events(uint16_t flags)
+{
+       short ret = 0;
+
+       if (flags & TEVENT_FD_READ) {
+               ret |= POLLIN;
+       }
+       if (flags & TEVENT_FD_WRITE) {
+               ret |= POLLOUT;
+       }
+       return ret;
+}
+
+static void tevent_watch_handler(struct tevent_context *ev,
+                                struct tevent_fd *fde, uint16_t flags,
+                                void *private_data);
+
+static struct poll_watch *tevent_watch_new(
+       const struct poll_funcs *funcs, int fd, short events,
+       void (*callback)(struct poll_watch *w, int fd, short events,
+                        void *private_data),
+       void *private_data)
+{
+       struct tevent_context *ev = talloc_get_type_abort(
+               funcs->private_data, struct tevent_context);
+       struct poll_watch *w;
+
+       w = talloc(ev, struct poll_watch);
+       if (w == NULL) {
+               return NULL;
+       }
+       w->fde = tevent_add_fd(ev, w, fd, poll_events_to_tevent(events),
+                              tevent_watch_handler, w);
+       if (w->fde == NULL) {
+               TALLOC_FREE(w);
+               return NULL;
+       }
+       w->fd = fd;
+       w->callback = callback;
+       w->private_data = private_data;
+       return w;
+}
+
+static void tevent_watch_handler(struct tevent_context *ev,
+                                struct tevent_fd *fde, uint16_t flags,
+                                void *private_data)
+{
+       struct poll_watch *w = talloc_get_type_abort(
+               private_data, struct poll_watch);
+
+       w->callback(w, w->fd, tevent_to_poll_events(flags),
+                   w->private_data);
+}
+
+static void tevent_watch_update(struct poll_watch *w, short events)
+{
+       tevent_fd_set_flags(w->fde, poll_events_to_tevent(events));
+}
+
+static short tevent_watch_get_events(struct poll_watch *w)
+{
+       return tevent_to_poll_events(tevent_fd_get_flags(w->fde));
+}
+
+static void tevent_watch_free(struct poll_watch *w)
+{
+       TALLOC_FREE(w);
+}
+
+static struct poll_timeout *tevent_timeout_new(
+       const struct poll_funcs *funcs, const struct timeval *tv,
+       void (*callback)(struct poll_timeout *t, void *private_data),
+       void *private_data)
+{
+       /* not implemented yet */
+       return NULL;
+}
+
+static void tevent_timeout_update(struct poll_timeout *t,
+                                 const struct timespec *ts)
+{
+       return;
+}
+
+static void tevent_timeout_free(struct poll_timeout *t)
+{
+       return;
+}
+
+void poll_funcs_init_tevent(struct poll_funcs *f, struct tevent_context *ev)
+{
+       f->watch_new = tevent_watch_new;
+       f->watch_update = tevent_watch_update;
+       f->watch_get_events = tevent_watch_get_events;
+       f->watch_free = tevent_watch_free;
+       f->timeout_new = tevent_timeout_new;
+       f->timeout_update = tevent_timeout_update;
+       f->timeout_free = tevent_timeout_free;
+       f->private_data = ev;
+}
diff --git a/source3/lib/poll_funcs/poll_funcs_tevent.h b/source3/lib/poll_funcs/poll_funcs_tevent.h
new file mode 100644 (file)
index 0000000..2e67720
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * Copyright (C) Volker Lendecke 2013
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __POLL_FUNCS_TEVENT_H__
+#define __POLL_FUNCS_TEVENT_H__
+
+#include "poll_funcs.h"
+#include "tevent.h"
+
+void poll_funcs_init_tevent(struct poll_funcs *f, struct tevent_context *ev);
+
+#endif
diff --git a/source3/lib/poll_funcs/wscript_build b/source3/lib/poll_funcs/wscript_build
new file mode 100644 (file)
index 0000000..ab24814
--- /dev/null
@@ -0,0 +1,5 @@
+#!/usr/bin/env python
+
+bld.SAMBA3_SUBSYSTEM('POLL_FUNCS_TEVENT',
+                     source='poll_funcs_tevent.c',
+                    deps='tevent')
index b872cbce83ed509013a641d77601213789f01627..fd53e2f3301acbad699daf946f35310ea663f04d 100755 (executable)
@@ -1452,6 +1452,7 @@ bld.RECURSE('auth')
 bld.RECURSE('libgpo/gpext')
 bld.RECURSE('lib/pthreadpool')
 bld.RECURSE('lib/asys')
+bld.RECURSE('lib/poll_funcs')
 bld.RECURSE('librpc')
 bld.RECURSE('librpc/idl')
 bld.RECURSE('libsmb')