diff options
Diffstat (limited to 'zbar/processor/posix.h')
-rw-r--r-- | zbar/processor/posix.h | 132 |
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 |