Esempio n. 1
0
void iochan_handler(struct iochan *i, int event)
{
    sel_thread_t p = iochan_getdata(i);

    if (event & EVENT_INPUT)
    {
        struct work *w = sel_thread_result(p);
        w->host->ipport = w->ipport;
        connect_resolver_host(w->host, w->iochan_man);
        xfree(w);
    }
}
Esempio n. 2
0
void iochan_handler(struct iochan *i, int event)
{
    static int number = 0;
    sel_thread_t p = iochan_getdata(i);

    if (event & EVENT_INPUT)
    {
        struct my_work_data *work;

        work = sel_thread_result(p);

        YAZ_CHECK(work);
        if (work)
        {
            YAZ_CHECK_EQ(work->x * 2, work->y);
            /* stop work after a couple of iterations */
            if (work->x > 10)
                iochan_destroy(i);

            xfree(work);
        }

    }
    if (event & EVENT_TIMEOUT)
    {
        struct my_work_data *work;

        work = xmalloc(sizeof(*work));
        work->x = number;
        sel_thread_add(p, work);

        work = xmalloc(sizeof(*work));
        work->x = number+1;
        sel_thread_add(p, work);

        number += 10;
    }
}
Esempio n. 3
0
static int event_loop(iochan_man_t man, IOCHAN *iochans) {
    do /* loop as long as there are active associations to process */
    {
        IOCHAN p, *nextp;
        IOCHAN start;
        IOCHAN inv_start;
        fd_set in, out, except;
        int res, max;
        static struct timeval to;
        struct timeval *timeout;

//        struct yaz_poll_fd *fds;
        int no_fds = 0;
        FD_ZERO(&in);
        FD_ZERO(&out);
        FD_ZERO(&except);
        timeout = &to; /* hang on select */
        to.tv_sec = 300;
        to.tv_usec = 0;

        // INV: start must no change through the loop

        yaz_mutex_enter(man->iochan_mutex);
        start = man->channel_list;
        yaz_mutex_leave(man->iochan_mutex);
        inv_start = start;
        for (p = start; p; p = p->next) {
            no_fds++;
        }
//        fds = (struct yaz_poll_fd *) xmalloc(no_fds * sizeof(*fds));

        max = 0;
        for (p = start; p; p = p->next) {
            if (p->thread_users > 0)
                continue;
            if (p->max_idle && p->max_idle < to.tv_sec)
                to.tv_sec = p->max_idle;
            if (p->fd < 0)
                continue;
            if (p->flags & EVENT_INPUT)
                FD_SET(p->fd, &in);
            if (p->flags & EVENT_OUTPUT)
                FD_SET(p->fd, &out);
            if (p->flags & EVENT_EXCEPT)
                FD_SET(p->fd, &except);
            if (p->fd > max)
                max = p->fd;
        }
        yaz_log(man->log_level, "max=%d sel_fd=%d", max, man->sel_fd);

        if (man->sel_fd != -1) {
            if (man->sel_fd > max)
                max = man->sel_fd;
            FD_SET(man->sel_fd, &in);
        }
        yaz_log(man->log_level, "select begin nofds=%d", max);
        res = select(max + 1, &in, &out, &except, timeout);
        yaz_log(man->log_level, "select returned res=%d", res);
        if (res < 0) {
            if (errno == EINTR)
                continue;
            else {
                yaz_log(YLOG_ERRNO | YLOG_WARN, "select");
                return 0;
            }
        }
        if (man->sel_fd != -1) {
            if (FD_ISSET(man->sel_fd, &in)) {
                IOCHAN chan;

                yaz_log(man->log_level, "eventl: sel input on sel_fd=%d",
                        man->sel_fd);
                while ((chan = sel_thread_result(man->sel_thread))) {
                    yaz_log(man->log_level,
                            "eventl: got thread result chan=%p name=%s", chan,
                            chan->name ? chan->name : "");
                    chan->thread_users--;
                }
            }
        }
        if (man->log_level) {
            int no = 0;
            for (p = start; p; p = p->next) {
                no++;
            }
            yaz_log(man->log_level, "%d channels", no);
        }
        for (p = start; p; p = p->next) {
            time_t now = time(0);

            if (p->destroyed) {
                yaz_log(man->log_level,
                        "eventl: skip destroyed chan=%p name=%s", p,
                        p->name ? p->name : "");
                continue;
            }
            if (p->thread_users > 0) {
                yaz_log(man->log_level,
                        "eventl: skip chan=%p name=%s users=%d", p,
                        p->name ? p->name : "", p->thread_users);
                continue;
            }
            p->this_event = 0;

            if (p->max_idle && now - p->last_event > p->max_idle) {
                p->last_event = now;
                p->this_event |= EVENT_TIMEOUT;
            }
            if (p->fd >= 0) {
                if (FD_ISSET(p->fd, &in)) {
                    p->last_event = now;
                    p->this_event |= EVENT_INPUT;
                }
                if (FD_ISSET(p->fd, &out)) {
                    p->last_event = now;
                    p->this_event |= EVENT_OUTPUT;
                }
                if (FD_ISSET(p->fd, &except)) {
                    p->last_event = now;
                    p->this_event |= EVENT_EXCEPT;
                }
            }
            run_fun(man, p);
        }
        assert(inv_start == start);
        yaz_mutex_enter(man->iochan_mutex);
        for (nextp = iochans; *nextp;) {
            IOCHAN p = *nextp;
            if (p->destroyed && p->thread_users == 0) {
                *nextp = iochan_destroy_real(p);
            } else
                nextp = &p->next;
        }
        yaz_mutex_leave(man->iochan_mutex);
    } while (*iochans);
    return 0;
}