static void mowgli_config_file_error(mowgli_config_file_t *cf, const char *format, ...) { va_list ap; char buffer[1024]; char *ptr; va_start(ap, format); vsnprintf(buffer, sizeof buffer, format, ap); va_end(ap); if ((ptr = strchr(buffer, '\n')) != NULL) *ptr = '\0'; if (cf != NULL) { if (cf->curline < 0) cf->curline = -cf->curline; mowgli_log("%s:%d: %s", cf->filename, cf->curline, buffer); /* mark config parse as failed */ cf->curline = -cf->curline; } else mowgli_log("mowgli_config_file_parse(): %s", buffer); }
static void mowgli_epoll_eventloop_select(mowgli_eventloop_t *eventloop, int delay) { mowgli_epoll_eventloop_private_t *priv; int i, num, o_errno; return_if_fail(eventloop != NULL); priv = eventloop->poller; num = epoll_wait(priv->epoll_fd, priv->pfd, priv->pfd_size, delay); o_errno = errno; mowgli_eventloop_synchronize(eventloop); if (num < 0) { if (mowgli_eventloop_ignore_errno(errno)) return; mowgli_log("mowgli_epoll_eventloop_select(): epoll_wait failed: %d (%s)", o_errno, strerror(o_errno)); return; } for (i = 0; i < num; i++) { mowgli_eventloop_pollable_t *pollable = priv->pfd[i].data.ptr; if (priv->pfd[i].events & (EPOLLIN | EPOLLHUP | EPOLLERR)) mowgli_pollable_trigger(eventloop, pollable, MOWGLI_EVENTLOOP_IO_READ); if (priv->pfd[i].events & (EPOLLOUT | EPOLLHUP | EPOLLERR)) mowgli_pollable_trigger(eventloop, pollable, MOWGLI_EVENTLOOP_IO_WRITE); } }
static void mowgli_linebuf_write_data(mowgli_eventloop_t *eventloop, mowgli_eventloop_io_t *io, mowgli_eventloop_io_dir_t dir, void *userdata) { mowgli_linebuf_t *linebuf = (mowgli_linebuf_t *) userdata; mowgli_linebuf_buf_t *buffer = &(linebuf->writebuf); int ret; if ((ret = mowgli_vio_write(linebuf->vio, buffer->buffer, buffer->buflen)) <= 0) if (linebuf->vio->error.code != MOWGLI_VIO_ERR_NONE) /* If we have a genuine error, we shouldn't come back to this func * Otherwise we'll try again. */ if (ret != 0) { mowgli_pollable_setselect(eventloop, io, MOWGLI_EVENTLOOP_IO_WRITE, NULL); mowgli_log("mowgli_vio_write returned error [%ld]: %s", linebuf->vio->error.code, linebuf->vio->error.string); return; } buffer->buflen -= ret; /* Anything else to write? */ if (buffer->buflen == 0) { if (!mowgli_vio_hasflag(linebuf->vio, MOWGLI_VIO_FLAGS_NEEDWRITE)) mowgli_pollable_setselect(eventloop, io, MOWGLI_EVENTLOOP_IO_WRITE, NULL); if ((linebuf->flags & MOWGLI_LINEBUF_SHUTTING_DOWN) != 0) mowgli_linebuf_do_shutdown(linebuf); } else { mowgli_pollable_setselect(eventloop, io, MOWGLI_EVENTLOOP_IO_WRITE, mowgli_linebuf_write_data); } }
void mowgli_simple_eventloop_timeout_once(mowgli_eventloop_t *eventloop, int timeout) { time_t delay, currtime; int t; return_if_fail(eventloop != NULL); return_if_fail(eventloop->eventloop_ops != NULL); mowgli_eventloop_synchronize(eventloop); currtime = mowgli_eventloop_get_time(eventloop); delay = mowgli_eventloop_next_timer(eventloop); while (delay <= currtime) { mowgli_eventloop_run_timers(eventloop); mowgli_eventloop_synchronize(eventloop); currtime = mowgli_eventloop_get_time(eventloop); delay = mowgli_eventloop_next_timer(eventloop); } if (timeout) t = timeout; else t = (delay - currtime) * 1000; #ifdef DEBUG mowgli_log("delay: %ld, currtime: %ld, select period: %d", delay, currtime, t); #endif eventloop->eventloop_ops->select(eventloop, t); }
void mowgli_queue_bootstrap(void) { mowgli_queue_heap = mowgli_heap_create(sizeof(mowgli_queue_t), 256, BH_NOW); if (mowgli_queue_heap == NULL) mowgli_log("mowgli_queue_heap was not created, expect problems."); }
static void mowgli_null_eventloop_setselect(mowgli_eventloop_t *eventloop, mowgli_eventloop_pollable_t *pollable, mowgli_eventloop_io_dir_t dir, mowgli_eventloop_io_cb_t *event_function) { mowgli_log("null eventloop does not really do polling, events for pollable<%p> will be ignored", (void *)pollable); switch (dir) { case MOWGLI_EVENTLOOP_IO_READ: pollable->read_function = event_function; break; case MOWGLI_EVENTLOOP_IO_WRITE: pollable->write_function = event_function; break; default: mowgli_log("unhandled pollable direction %d", dir); break; } return; }
mowgli_eventloop_t * mowgli_eventloop_create(void) { mowgli_eventloop_t *eventloop; if (eventloop_heap == NULL) eventloop_heap = mowgli_heap_create(sizeof(mowgli_eventloop_t), 16, BH_NOW); eventloop = mowgli_heap_alloc(eventloop_heap); eventloop->eventloop_ops = &_mowgli_null_pollops; #ifdef HAVE_SELECT eventloop->eventloop_ops = &_mowgli_select_pollops; #endif #ifdef HAVE_POLL_H eventloop->eventloop_ops = &_mowgli_poll_pollops; #endif #ifdef HAVE_SYS_EPOLL_H eventloop->eventloop_ops = &_mowgli_epoll_pollops; #endif #ifdef HAVE_KQUEUE eventloop->eventloop_ops = &_mowgli_kqueue_pollops; #endif #ifdef HAVE_DISPATCH_BLOCK eventloop->eventloop_ops = &_mowgli_qnx_pollops; #endif #ifdef HAVE_PORT_CREATE eventloop->eventloop_ops = &_mowgli_ports_pollops; #endif #if 0 eventloop->eventloop_ops = &_mowgli_winsock_pollops; #endif if (mowgli_mutex_init(&eventloop->mutex) != 0) { mowgli_log("couldn't create mutex for eventloop %p, aborting...", (void *) eventloop); abort(); } eventloop->eventloop_ops->pollsetup(eventloop); eventloop->deadline = -1; mowgli_eventloop_calibrate(eventloop); return eventloop; }
mowgli_interface_t * mowgli_interface_get(const char *id, uint32_t abirev) { mowgli_interface_base_t *base_iface; mowgli_mutex_lock(&mowgli_interface_lock); base_iface = mowgli_patricia_retrieve(mowgli_interface_dict, id); if (base_iface->abirev != abirev) { mowgli_log("requested interface %s, abi mismatch %" PRIu32 " != %" PRIu32, id, abirev, base_iface->abirev); base_iface = NULL; } mowgli_mutex_unlock(&mowgli_interface_lock); return base_iface; }
static void mowgli_epoll_eventloop_destroy(mowgli_eventloop_t *eventloop, mowgli_eventloop_pollable_t *pollable) { mowgli_epoll_eventloop_private_t *priv; struct epoll_event ep_event; return_if_fail(eventloop != NULL); return_if_fail(pollable != NULL); priv = eventloop->poller; pollable->slot = 0; ep_event.events = pollable->slot; ep_event.data.ptr = pollable; if (epoll_ctl(priv->epoll_fd, EPOLL_CTL_DEL, pollable->fd, &ep_event) != 0) { if (mowgli_eventloop_ignore_errno(errno)) return; mowgli_log("mowgli_epoll_eventloop_destroy(): epoll_ctl failed: %d (%s)", errno, strerror(errno)); } }
static mowgli_signal_handler_t mowgli_signal_install_handler_full(int signum, mowgli_signal_handler_t handler, int *sigtoblock, size_t sigtoblocksize) { struct sigaction action, old_action; size_t i; action.sa_handler = handler; action.sa_flags = SA_RESTART; sigemptyset(&action.sa_mask); for (i = 0; i < sigtoblocksize; i++) sigaddset(&action.sa_mask, sigtoblock[i]); if (sigaction(signum, &action, &old_action) == -1) { mowgli_log("Failed to install signal handler for signal %d", signum); return NULL; } return old_action.sa_handler; }
static void mowgli_epoll_eventloop_setselect(mowgli_eventloop_t *eventloop, mowgli_eventloop_pollable_t *pollable, mowgli_eventloop_io_dir_t dir, mowgli_eventloop_io_cb_t *event_function) { mowgli_epoll_eventloop_private_t *priv; struct epoll_event ep_event; int op = -1; unsigned int old_flags; return_if_fail(eventloop != NULL); return_if_fail(pollable != NULL); priv = eventloop->poller; old_flags = pollable->slot; # ifdef DEBUG mowgli_log("setselect %p fd %d func %p", pollable, pollable->fd, event_function); # endif switch (dir) { case MOWGLI_EVENTLOOP_IO_READ: pollable->read_function = event_function; pollable->slot |= EPOLLIN; break; case MOWGLI_EVENTLOOP_IO_WRITE: pollable->write_function = event_function; pollable->slot |= EPOLLOUT; break; default: mowgli_log("unhandled pollable direction %d", dir); break; } # ifdef DEBUG mowgli_log("%p -> read %p : write %p", pollable, pollable->read_function, pollable->write_function); # endif if (pollable->read_function == NULL) pollable->slot &= ~EPOLLIN; if (pollable->write_function == NULL) pollable->slot &= ~EPOLLOUT; if ((old_flags == 0) && (pollable->slot == 0)) return; else if (pollable->slot <= 0) op = EPOLL_CTL_DEL; else if ((old_flags == 0) && (pollable->slot != 0)) op = EPOLL_CTL_ADD; else if (pollable->slot != old_flags) op = EPOLL_CTL_MOD; if (op == -1) return; ep_event.events = pollable->slot; ep_event.data.ptr = pollable; if (epoll_ctl(priv->epoll_fd, op, pollable->fd, &ep_event) != 0) { if (mowgli_eventloop_ignore_errno(errno)) return; mowgli_log("mowgli_epoll_eventloop_setselect(): epoll_ctl failed: %d (%s)", errno, strerror(errno)); } return; }
void mowgli_formatter_format_from_argstack(char *buf, size_t bufstr, const char *fmtstr, const char *descstr, mowgli_argstack_t *stack) { size_t pos = 0; char *i = buf; const char *fiter = fmtstr; return_if_fail(buf != NULL); return_if_fail(fmtstr != NULL); return_if_fail(descstr != NULL); *i = '\0'; while (*fiter && pos <= bufstr) { int arg; mowgli_argstack_element_t *e; pos = strlen(buf); switch(*fiter) { case '%': fiter++; arg = atoi(fiter); e = mowgli_node_nth_data(&stack->stack, arg - 1); while (isdigit(*fiter)) fiter++; if (e == NULL) { arg = snprintf(i, bufstr - (i - buf), "(unknown)"); i += arg; continue; } switch(e->type) { case MOWGLI_ARG_STRING: arg = snprintf(i, bufstr - (i - buf), "%s", e->data.string); i += arg; break; case MOWGLI_ARG_NUMERIC: arg = snprintf(i, bufstr - (i - buf), "%d", e->data.numeric); i += arg; break; case MOWGLI_ARG_POINTER: arg = snprintf(i, bufstr - (i - buf), "%p", e->data.pointer); i += arg; break; case MOWGLI_ARG_BOOLEAN: arg = snprintf(i, bufstr - (i - buf), "%s", e->data.boolean ? "TRUE" : "FALSE"); i += arg; break; default: mowgli_log("unhandled type"); break; } continue; break; default: *i = *fiter; } i++; fiter++; } }
void mowgli_init(void) { mowgli_log("mowgli_init() is a deprecated function, provided only for backwards compatibility with Mowgli-1. You should remove it if you no longer support using Mowgli-1."); }