コード例 #1
0
ファイル: iv_event_raw_posix.c プロジェクト: kostas1/ivykis
static void iv_event_raw_got_event(void *_this)
{
	struct iv_event_raw *this = (struct iv_event_raw *)_this;
	int toread;
	char buf[1024];
	int ret;

	toread = eventfd_unavailable ? sizeof(buf) : 8;

	do {
		ret = read(this->event_rfd.fd, buf, toread);
	} while (ret < 0 && errno == EINTR);

	if (ret <= 0) {
		if (ret == 0) {
			iv_fatal("iv_event_raw: reading from event fd "
				 "returned zero");
		} else if (errno != EAGAIN) {
			iv_fatal("iv_event_raw: reading from event fd "
				 "returned error %d[%s]", errno,
				 strerror(errno));
		}
		return;
	}

	this->handler(this->cookie);
}
コード例 #2
0
ファイル: iv_fd_kqueue.c プロジェクト: RustinCohle/ivykis
static void iv_fd_kqueue_poll(struct iv_state *st,
			      struct iv_list_head *active,
			      const struct timespec *abs)
{
	struct kevent kev[UPLOAD_BATCH];
	int num;
	struct kevent batch[st->numfds ? 2 * st->numfds : 1];
	struct timespec rel;
	int ret;
	int run_events;
	int i;

	iv_fd_kqueue_upload(st, kev, UPLOAD_BATCH, &num);

	ret = kevent(st->u.kqueue.kqueue_fd, kev, num,
		     batch, ARRAY_SIZE(batch), to_relative(st, &rel, abs));

	__iv_invalidate_now(st);

	if (ret < 0) {
		if (errno == EINTR)
			return;

		iv_fatal("iv_fd_kqueue_poll: got error %d[%s]", errno,
			 strerror(errno));
	}

	run_events = 0;
	for (i = 0; i < ret; i++) {
		struct iv_fd_ *fd;

		if (batch[i].filter == EVFILT_USER) {
			run_events = 1;
			continue;
		}

		if (batch[i].flags & EV_ERROR) {
			int err = batch[i].data;
			int fd = batch[i].ident;

			iv_fatal("iv_fd_kqueue_poll: got error %d[%s] "
				 "polling fd %d", err, strerror(err), fd);
		}

		fd = (void *)batch[i].udata;
		if (batch[i].filter == EVFILT_READ) {
			iv_fd_make_ready(active, fd, MASKIN);
		} else if (batch[i].filter == EVFILT_WRITE) {
			iv_fd_make_ready(active, fd, MASKOUT);
		} else {
			iv_fatal("iv_fd_kqueue_poll: got message from "
				 "filter %d", batch[i].filter);
		}
	}

	if (run_events)
		iv_event_run_pending_events();
}
コード例 #3
0
ファイル: iv_fd_port.c プロジェクト: buytenh/ivykis
static void iv_fd_port_event_send(struct iv_state *dest)
{
    if (port_send(dest->u.port.port_fd, 0, NULL) < 0) {
        iv_fatal("iv_fd_port_event_send: port_send got "
                 "error %d[%s]", errno, strerror(errno));
    }
}
コード例 #4
0
ファイル: iv_fd_port.c プロジェクト: buytenh/ivykis
static void iv_fd_port_upload_one(struct iv_state *st, struct iv_fd_ *fd)
{
    if (__iv_fd_port_upload_one(st, fd) < 0) {
        iv_fatal("iv_fd_port_upload_one: got error %d[%s]", errno,
                 strerror(errno));
    }
}
コード例 #5
0
ファイル: iv_fd.c プロジェクト: pexip/os-syslog-ng
static void iv_fd_init_first_thread(struct iv_state *st)
{
	int euid;
	char *exclude;

	euid = geteuid();

	signal(SIGPIPE, SIG_IGN);
	signal(SIGURG, SIG_IGN);

	sanitise_nofile_rlimit(euid);

	exclude = getenv("IV_EXCLUDE_POLL_METHOD");
	if (exclude != NULL && getuid() != euid)
		exclude = NULL;

#ifdef HAVE_PORT_CREATE
	consider_poll_method(st, exclude, &iv_fd_poll_method_port);
#endif
#ifdef HAVE_SYS_DEVPOLL_H
	consider_poll_method(st, exclude, &iv_fd_poll_method_dev_poll);
#endif
#ifdef HAVE_EPOLL_CREATE
	consider_poll_method(st, exclude, &iv_fd_poll_method_epoll);
#endif
#ifdef HAVE_KQUEUE
	consider_poll_method(st, exclude, &iv_fd_poll_method_kqueue);
#endif
	consider_poll_method(st, exclude, &iv_fd_poll_method_poll);

	if (method == NULL)
		iv_fatal("iv_init: can't find suitable event dispatcher");
}
コード例 #6
0
ファイル: iv_fd_port.c プロジェクト: buytenh/ivykis
static int iv_fd_port_timer_create(struct iv_state *st)
{
    port_notify_t pn;
    struct sigevent se;
    timer_t id;
    int ret;

    se.sigev_notify = SIGEV_PORT;
    se.sigev_value.sival_ptr = &pn;
    pn.portnfy_port = st->u.port.port_fd;
    pn.portnfy_user = NULL;

    ret = timer_create(CLOCK_MONOTONIC, &se, &id);
    if (ret < 0) {
        if (errno == EPERM)
            return 0;

        iv_fatal("iv_fd_port_timer_create: got error %d[%s]",
                 errno, strerror(errno));
    }

    st->u.port.timer_id = id;

    return 1;
}
コード例 #7
0
ファイル: iv_popen.c プロジェクト: kostas1/ivykis
static void iv_popen_child(void *cookie)
{
	struct iv_popen_spawn_info *info = cookie;
	int devnull;

	devnull = open("/dev/null", O_RDWR);
	if (devnull < 0) {
		iv_fatal("iv_popen_child: got error %d[%s] opening "
			 "/dev/null", errno, strerror(errno));
	}

	if (info->for_read) {
		dup2(devnull, 0);
		dup2(info->data_pipe[1], 1);
		dup2(devnull, 2);
	} else {
		dup2(info->data_pipe[0], 0);
		dup2(devnull, 1);
		dup2(devnull, 2);
	}

	close(info->data_pipe[0]);
	close(info->data_pipe[1]);
	close(devnull);

	execvp(info->this->file, info->this->argv);
	perror("execvp");
}
コード例 #8
0
ファイル: iv_fd.c プロジェクト: pexip/os-syslog-ng
void iv_fd_init(struct iv_state *st)
{
	if (method == NULL)
		iv_fd_init_first_thread(st);
	else if (method->init(st) < 0)
		iv_fatal("iv_init: can't initialize event dispatcher");

	st->numfds = 0;
	st->handled_fd = NULL;
}
コード例 #9
0
ファイル: iv_task.c プロジェクト: kostas1/ivykis
void iv_task_register(struct iv_task *_t)
{
	struct iv_state *st = iv_get_state();
	struct iv_task_ *t = (struct iv_task_ *)_t;

	if (!iv_list_empty(&t->list))
		iv_fatal("iv_task_register: called with task still on a list");

	st->numobjs++;
	iv_list_add_tail(&t->list, &st->tasks);
}
コード例 #10
0
ファイル: iv_task.c プロジェクト: kostas1/ivykis
void iv_task_unregister(struct iv_task *_t)
{
	struct iv_state *st = iv_get_state();
	struct iv_task_ *t = (struct iv_task_ *)_t;

	if (iv_list_empty(&t->list))
		iv_fatal("iv_task_unregister: called with task not on a list");

	st->numobjs--;
	iv_list_del_init(&t->list);
}
コード例 #11
0
ファイル: iv_work.c プロジェクト: RustinCohle/ivykis
/* worker thread ************************************************************/
static void __iv_work_thread_die(struct work_pool_thread *thr)
{
	struct work_pool_priv *pool = thr->pool;

	if (thr->kicked)
		iv_fatal("__iv_work_thread_die: called on kicked thread");

	if (!iv_list_empty(&thr->list))
		iv_fatal("__iv_work_thread_die: thread still on list");

	iv_event_unregister(&thr->kick);
	free(thr);

	pool->started_threads--;

	if (pool->thread_stop != NULL)
		pool->thread_stop(pool->cookie);

	if (pool->shutting_down && !pool->started_threads)
		iv_event_post(&pool->ev);
}
コード例 #12
0
ファイル: iv_fd.c プロジェクト: pexip/os-syslog-ng
void iv_fd_set_handler_err(struct iv_fd *_fd, void (*handler_err)(void *))
{
	struct iv_state *st = iv_get_state();
	struct iv_fd_ *fd = (struct iv_fd_ *)_fd;

	if (!fd->registered) {
		iv_fatal("iv_fd_set_handler_err: called with fd which "
			 "is not registered");
	}

	fd->handler_err = handler_err;
	notify_fd(st, fd);
}
コード例 #13
0
ファイル: iv_timer.c プロジェクト: kostas1/ivykis
void iv_timer_unregister(struct iv_timer *_t)
{
	struct iv_state *st = iv_get_state();
	struct iv_timer_ *t = (struct iv_timer_ *)_t;
	struct iv_timer_ **m;
	struct iv_timer_ **p;

	if (t->index == -1) {
		iv_fatal("iv_timer_unregister: called with timer not "
			 "on the heap");
	}

	if (t->index > st->num_timers) {
		iv_fatal("iv_timer_unregister: timer index %d > %d",
			 t->index, st->num_timers);
	}

	p = get_node(st, t->index);
	if (*p != t) {
		iv_fatal("iv_timer_unregister: unregistered timer "
			 "index belonging to other timer");
	}

	st->numobjs--;

	m = get_node(st, st->num_timers);
	st->num_timers--;

	*p = *m;
	(*p)->index = t->index;
	*m = NULL;
	if (p != m) {
		pull_up(st, (*p)->index, p);
		push_down(st, (*p)->index, p);
	}

	t->index = -1;
}
コード例 #14
0
ファイル: iv_timer.c プロジェクト: kostas1/ivykis
void iv_timer_register(struct iv_timer *_t)
{
	struct iv_state *st = iv_get_state();
	struct iv_timer_ *t = (struct iv_timer_ *)_t;
	struct iv_timer_ **p;
	int index;

	if (t->index != -1) {
		iv_fatal("iv_timer_register: called with timer still "
			 "on the heap");
	}

	st->numobjs++;

	index = ++st->num_timers;
	p = get_node(st, index);
	if (p == NULL)
		iv_fatal("iv_timer_register: timer list overflow");

	*p = t;
	t->index = index;

	pull_up(st, index, p);
}
コード例 #15
0
ファイル: iv_fd.c プロジェクト: pexip/os-syslog-ng
static void iv_fd_register_prologue(struct iv_state *st, struct iv_fd_ *fd)
{
	if (fd->registered) {
		iv_fatal("iv_fd_register: called with fd which is "
			 "still registered");
	}

	if (fd->fd < 0 || fd->fd >= maxfd) {
		iv_fatal("iv_fd_register: called with invalid fd %d "
			 "(maxfd=%d)", fd->fd, maxfd);
	}

	fd->registered = 1;
	INIT_IV_LIST_HEAD(&fd->list_active);
	fd->ready_bands = 0;
	fd->registered_bands = 0;
#if defined(HAVE_SYS_DEVPOLL_H) || defined(HAVE_EPOLL_CREATE) ||	\
    defined(HAVE_KQUEUE) || defined(HAVE_PORT_CREATE)
	INIT_IV_LIST_HEAD(&fd->list_notify);
#endif

	if (method->register_fd != NULL)
		method->register_fd(st, fd);
}
コード例 #16
0
ファイル: iv_fd_port.c プロジェクト: buytenh/ivykis
static void iv_fd_port_clear_poll_timeout(struct iv_state *st)
{
    struct itimerspec val;
    int ret;

    val.it_interval.tv_sec = 0;
    val.it_interval.tv_nsec = 0;
    val.it_value.tv_sec = 0;
    val.it_value.tv_nsec = 0;

    ret = timer_settime(st->u.port.timer_id, TIMER_ABSTIME, &val, NULL);
    if (ret < 0) {
        iv_fatal("iv_fd_port_clear_poll_timeout: got error %d[%s]",
                 errno, strerror(errno));
    }
}
コード例 #17
0
ファイル: iv_event_bench.c プロジェクト: RustinCohle/ivykis
static void got_ev_parent(void *_dummy)
{
	ev_received++;

	if (die == 0) {
		iv_event_post(&ev_child);
	} else if (die == 1) {
		die = 2;
		iv_event_post(&ev_child);
	} else if (die == 2) {
		iv_fatal("iv_event_bench: entered invalid state");
	} else if (die == 3) {
		iv_validate_now();
		tim_end = iv_now;
		iv_event_unregister(&ev_parent);
	}
}
コード例 #18
0
ファイル: log.c プロジェクト: viktor-sls/iface_informer
int log_open(char *file_path)
{
	if (!file_path) {
		file_path = log_file_path_default;
		printf("Log file is not defined. Using default file: %s\n", file_path);
	}

	if( access(file_path, F_OK) == 0)
		unlink(file_path);

	log_file = fopen(file_path, "a");
	if(log_file == NULL) {
		iv_fatal("%s, fopen failed: %s\n", __func__, strerror(errno));
	}

	return 0;
}
コード例 #19
0
ファイル: iv_main_win32.c プロジェクト: RustinCohle/ivykis
void iv_init(void)
{
	struct iv_state *st;

	if (iv_state_index == -1) {
		iv_state_index = TlsAlloc();
		if (iv_state_index == TLS_OUT_OF_INDEXES)
			iv_fatal("iv_init: failed to allocate TLS key");
	}

	st = calloc(1, iv_tls_total_state_size());
	TlsSetValue(iv_state_index, st);

	iv_handle_init(st);
	iv_task_init(st);
	iv_time_init(st);
	iv_timer_init(st);

	iv_tls_thread_init(st);
}
コード例 #20
0
ファイル: iv_main_posix.c プロジェクト: buytenh/ivykis
void iv_init(void)
{
	struct iv_state *st;

	if (!iv_state_key_allocated) {
		if (pthr_key_create(&iv_state_key, iv_state_destructor))
			iv_fatal("iv_init: failed to allocate TLS key");
		iv_state_key_allocated = 1;
	}

	st = calloc(1, iv_tls_total_state_size());

	pthr_setspecific(&iv_state_key, st);

	iv_fd_init(st);
	iv_task_init(st);
	iv_timer_init(st);

	iv_event_init(st);

	iv_tls_thread_init(st);
}
コード例 #21
0
ファイル: iv_fd.c プロジェクト: pexip/os-syslog-ng
void iv_fd_unregister(struct iv_fd *_fd)
{
	struct iv_state *st = iv_get_state();
	struct iv_fd_ *fd = (struct iv_fd_ *)_fd;

	if (!fd->registered) {
		iv_fatal("iv_fd_unregister: called with fd which is "
			 "not registered");
	}
	fd->registered = 0;

	iv_list_del(&fd->list_active);

	notify_fd(st, fd);
	if (method->unregister_fd != NULL)
		method->unregister_fd(st, fd);

	st->numobjs--;
	st->numfds--;

	if (st->handled_fd == fd)
		st->handled_fd = NULL;
}
コード例 #22
0
ファイル: iv_fd_port.c プロジェクト: buytenh/ivykis
static int
iv_fd_port_set_poll_timeout(struct iv_state *st, const struct timespec *abs)
{
    struct itimerspec val;
    int ret;

    if (st->u.port.timer_id == -1 && !iv_fd_port_timer_create(st)) {
        method = &iv_fd_poll_method_port;
        return 0;
    }

    val.it_interval.tv_sec = 0;
    val.it_interval.tv_nsec = 0;
    val.it_value = *abs;

    ret = timer_settime(st->u.port.timer_id, TIMER_ABSTIME, &val, NULL);
    if (ret < 0) {
        iv_fatal("iv_fd_port_set_poll_timeout: got error %d[%s]",
                 errno, strerror(errno));
    }

    return 1;
}
コード例 #23
0
ファイル: iv_main_posix.c プロジェクト: kostas1/ivykis
void iv_init(void)
{
	struct iv_state *st;

	if (!iv_state_key_allocated) {
		if (pthread_key_create(&iv_state_key, iv_state_destructor))
			iv_fatal("iv_init: failed to allocate TLS key");
		iv_state_key_allocated = 1;
	}

	st = calloc(1, iv_tls_total_state_size());

	pthread_setspecific(iv_state_key, st);
#ifdef HAVE_THREAD
	__st = st;
#endif

	st->numobjs = 0;

	iv_fd_init(st);
	iv_task_init(st);
	iv_timer_init(st);
	iv_tls_thread_init(st);
}
コード例 #24
0
ファイル: iv_timer.c プロジェクト: kostas1/ivykis
void iv_timer_init(struct iv_state *st)
{
	if (get_node(st, 1) == NULL)
		iv_fatal("iv_timer_init: can't alloc memory for root ratnode");
}
コード例 #25
0
ファイル: iv_fd_kqueue.c プロジェクト: RustinCohle/ivykis
static void kevent_retry(char *name, struct iv_state *st,
			 const struct kevent *changelist, int nchanges)
{
	if (__kevent_retry(st->u.kqueue.kqueue_fd, changelist, nchanges) < 0)
		iv_fatal("%s: got error %d[%s]", name, errno, strerror(errno));
}
コード例 #26
0
ファイル: iv_fd_port.c プロジェクト: buytenh/ivykis
static int iv_fd_port_poll(struct iv_state *st,
                           struct iv_list_head *active,
                           const struct timespec *abs)
{
    struct timespec _rel;
    struct timespec *rel;
    int run_timers;
    int run_events;
    unsigned int nget;
    port_event_t pe[PORTEV_NUM];
    int ret;
    int i;

    iv_fd_port_upload(st);

    rel = to_relative(st, &_rel, abs);

    run_timers = 0;
    if (rel != NULL && rel->tv_sec == 0 && rel->tv_nsec == 0)
        run_timers = 1;

    run_events = 0;

poll_more:
    nget = 1;

    /*
     * If we get EINTR from port_getn(), no events are returned
     * and nget will not have been updated, but if we get ETIME,
     * events may be returned, and nget will be set to the number
     * of events in the array, and we need to process those
     * events as usual.
     */
    ret = port_getn(st->u.port.port_fd, pe, PORTEV_NUM, &nget, rel);

    __iv_invalidate_now(st);

    if (ret < 0 && errno != ETIME) {
        if (errno == EINTR)
            return run_timers;

        iv_fatal("iv_fd_port_poll: got error %d[%s]", errno,
                 strerror(errno));
    }

    if (ret < 0 && errno == ETIME)
        run_timers = 1;

    for (i = 0; i < nget; i++) {
        int source;

        source = pe[i].portev_source;
        if (source == PORT_SOURCE_FD) {
            int revents;
            struct iv_fd_ *fd;

            revents = pe[i].portev_events;
            fd = pe[i].portev_user;

            if (revents & (POLLIN | POLLERR | POLLHUP))
                iv_fd_make_ready(active, fd, MASKIN);

            if (revents & (POLLOUT | POLLERR | POLLHUP))
                iv_fd_make_ready(active, fd, MASKOUT);

            if (revents & (POLLERR | POLLHUP))
                iv_fd_make_ready(active, fd, MASKERR);

            fd->registered_bands = 0;

            iv_list_del_init(&fd->list_notify);
            if (fd->wanted_bands) {
                iv_list_add_tail(&fd->list_notify,
                                 &st->u.port.notify);
            }
        } else if (source == PORT_SOURCE_TIMER) {
            run_timers = 1;
        } else if (source == PORT_SOURCE_USER) {
            run_events = 1;
        } else {
            iv_fatal("iv_fd_port_poll: received event "
                     "from unknown source %d", source);
        }
    }

    if (nget == PORTEV_NUM) {
        run_timers = 1;
        rel = &_rel;
        rel->tv_sec = 0;
        rel->tv_nsec = 0;
        goto poll_more;
    }

    if (run_events)
        iv_event_run_pending_events();

    return run_timers;
}