summaryrefslogtreecommitdiffstats
path: root/zbar/processor/posix.h
diff options
context:
space:
mode:
Diffstat (limited to 'zbar/processor/posix.h')
-rw-r--r--zbar/processor/posix.h132
1 files changed, 132 insertions, 0 deletions
diff --git a/zbar/processor/posix.h b/zbar/processor/posix.h
new file mode 100644
index 0000000..7ed05cc
--- /dev/null
+++ b/zbar/processor/posix.h
@@ -0,0 +1,132 @@
+/*------------------------------------------------------------------------
+ * Copyright 2007-2009 (c) Jeff Brown <spadix@users.sourceforge.net>
+ *
+ * This file is part of the ZBar Bar Code Reader.
+ *
+ * The ZBar Bar Code Reader is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU Lesser Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * The ZBar Bar Code Reader 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 Lesser Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser Public License
+ * along with the ZBar Bar Code Reader; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * http://sourceforge.net/projects/zbar
+ *------------------------------------------------------------------------*/
+#ifndef _PROCESSOR_POSIX_H_
+#define _PROCESSOR_POSIX_H_
+
+#include "processor.h"
+
+#ifdef HAVE_POLL_H
+#include <poll.h>
+#endif
+
+#ifdef HAVE_POLL_H
+typedef int(poll_handler_t)(zbar_processor_t *, int);
+
+/* poll information */
+typedef struct poll_desc_s {
+ int num; /* number of descriptors */
+ struct pollfd *fds; /* poll descriptors */
+ poll_handler_t **handlers; /* poll handlers */
+} poll_desc_t;
+#endif
+
+struct processor_state_s {
+#ifdef HAVE_POLL_H
+ poll_desc_t polling; /* polling registration */
+ poll_desc_t thr_polling; /* thread copy */
+#endif
+ int kick_fds[2]; /* poll kicker */
+ poll_handler_t *pre_poll_handler; /* special case */
+};
+
+#ifdef HAVE_POLL_H
+static inline int alloc_polls(volatile poll_desc_t *p)
+{
+ p->fds = realloc(p->fds, p->num * sizeof(struct pollfd));
+ p->handlers = realloc(p->handlers, p->num * sizeof(poll_handler_t *));
+ /* FIXME should check for ENOMEM */
+ return (0);
+}
+
+static inline int add_poll(zbar_processor_t *proc, int fd,
+ poll_handler_t *handler)
+{
+ processor_state_t *state = proc->state;
+
+ _zbar_mutex_lock(&proc->mutex);
+
+ poll_desc_t *polling = &state->polling;
+ unsigned i = polling->num++;
+ zprintf(5, "[%d] fd=%d handler=%p\n", i, fd, handler);
+ if (!alloc_polls(polling)) {
+ memset(&polling->fds[i], 0, sizeof(struct pollfd));
+ polling->fds[i].fd = fd;
+ polling->fds[i].events = POLLIN;
+ polling->handlers[i] = handler;
+ } else
+ i = -1;
+
+ _zbar_mutex_unlock(&proc->mutex);
+
+ if (proc->input_thread.started) {
+ assert(state->kick_fds[1] >= 0);
+ if (write(state->kick_fds[1], &i /* unused */, sizeof(unsigned)) < 0)
+ return (-1);
+ } else if (!proc->threaded) {
+ state->thr_polling.num = polling->num;
+ state->thr_polling.fds = polling->fds;
+ state->thr_polling.handlers = polling->handlers;
+ }
+ return (i);
+}
+
+static inline int remove_poll(zbar_processor_t *proc, int fd)
+{
+ processor_state_t *state = proc->state;
+
+ _zbar_mutex_lock(&proc->mutex);
+
+ poll_desc_t *polling = &state->polling;
+ int i;
+ for (i = polling->num - 1; i >= 0; i--)
+ if (polling->fds[i].fd == fd)
+ break;
+ zprintf(5, "[%d] fd=%d n=%d\n", i, fd, polling->num);
+
+ if (i >= 0) {
+ if (i + 1 < polling->num) {
+ int n = polling->num - i - 1;
+ memmove(&polling->fds[i], &polling->fds[i + 1],
+ n * sizeof(struct pollfd));
+ memmove(&polling->handlers[i], &polling->handlers[i + 1],
+ n * sizeof(poll_handler_t));
+ }
+ polling->num--;
+ i = alloc_polls(polling);
+ }
+
+ _zbar_mutex_unlock(&proc->mutex);
+
+ if (proc->input_thread.started) {
+ if (write(state->kick_fds[1], &i /* unused */, sizeof(unsigned)) < 0)
+ return (-1);
+ } else if (!proc->threaded) {
+ state->thr_polling.num = polling->num;
+ state->thr_polling.fds = polling->fds;
+ state->thr_polling.handlers = polling->handlers;
+ }
+ return (i);
+}
+#endif
+
+#endif