Question

I'm trying to debug a code that is using a libevent library. In that library, there is a function event_new that is suppose to create an event_cb. Somehow after I dispatch the event base, the event_cb cannot be called or accessed. This problem only happens on hpux itanium. This code works on hpux pa-risc, Redhat, AIX, and Solaris. Is there any certain thing that need to be set?

This is part of the code

int ttypread (int fd, Header *h, char **buf)
{

    int c,k;
    struct user_data user_data;
    struct bufferevent *in_buffer;
    struct event_config *evconfig;

    log_debug("inside ttypread");

    in_buffer = NULL;
    user_data.fd = fd;
    user_data.h = h;
    user_data.buf = buf;

    log_debug("from user_data, fd = %d",user_data.fd);  //the log_debug is a debugging function for me to check the value sent by the system. I use it to compare between each platform
    log_debug("from user_data, buf = %s",user_data.buf);
    log_debug("from user_data, h.len = %d",user_data.h->len);
    log_debug("from user_data, h.type = %d",user_data.h->type);

    evconfig = event_config_new();
    if (evconfig == NULL) {
            log_error("event_config_new failed");
            return -1;
    }

    if (event_config_require_features(evconfig, EV_FEATURE_FDS)!=0) {
            log_error("event_config_require_features failed");
            return -1;
    }

    base = event_base_new_with_config(evconfig);
    if (!base) {
            log_error("ttypread:event_base_new failed");
            return -1;
    }

    const char* method;              //these 3 lines are the new line edited
    method = event_base_get_method(base);
    log_debug("ttyread is using method = %s",method);

    ev = event_new(base, fd, EV_READ|EV_PERSIST, ttypread_event_cb, &user_data);
    c = event_add(ev, NULL);
    log_debug("ttypread passed event_add with c value is %d",c);

    in_buffer = bufferevent_socket_new(base, STDIN_FILENO, BEV_OPT_CLOSE_ON_FREE);
    log_debug("ttypread passed bufferevent_socket_new");
    if(in_buffer == NULL){
            log_debug("problem with bufferevent_socket_new");
    }
    bufferevent_setcb(in_buffer, in_read_cb, NULL, in_event_cb, NULL);
    bufferevent_disable(in_buffer, EV_WRITE);
    bufferevent_enable(in_buffer, EV_READ);

    k =event_base_dispatch(base);
    log_debug("event_base have been dispatched"); //when looking at the debugging file, the other plaform will go to ttypread_event_cb function. But for hpux itanium, it stays here.

    if (k == 0){
            log_debug("event_base_dispatch returned 0");
    } else if (k == -1){
            log_debug("event_base_dispatch returned -1");
    } else  {
            log_debug("event_base_dispatch returned 1");
    }
    event_base_free(base);
    event_free(ev);

    log_debug("finish ttypread");
    log_debug("ttypread_ret will return [%d]",ttypread_ret);
    return ttypread_ret;
}

void ttypread_event_cb(evutil_socket_t fd, short events, void *arg)
{
    int nread;
    struct timeval  t;
    struct user_data *user_data;

    user_data = (struct user_data*)arg;
    nread = 0;

    log_debug("inside ttypread_event_cb");
    if (events & EV_READ) {
            log_debug("got events & EV_READ");
            nread = ttyread(fd, user_data->h, user_data->buf);
            if (nread == -1) {
                    ttypread_ret = -1;
                    event_del(ev);
                    event_base_loopexit(base, NULL);
            } else if (nread == 0) {
                    if (access(input_filename, F_OK)!=0) {
                            log_debug("cannot access [%s]",input_filename);
                            tcsetattr(0, TCSANOW, &old);  /* Return terminal state */
                            exit(EXIT_SUCCESS);
                    }
                    t.tv_sec = 0;
                    t.tv_usec = 250000;
                    select(0, 0, 0, 0, &t);
            } else {
                    ttypread_ret = 1;
                    event_del(ev);
                    event_base_loopexit(base, NULL);
            }
    }
    else if (events & EV_WRITE) {
    log_debug("got events & EV_WRITE");
    }
}

Not sure if this help. But just some info on the hpux itanium

uname -a = HP-UX hpux-ita B.11.23 U ia64

If you need any additional info or other declaration on function, just leave a comment and I will edit the question.

EDIT : i've added a function inside ttypread. Somehow for hpux itanium its returning devpoll while other platform are returning poll. Im not sure if this is the problem. But if that is so, is there any way for me to change it?

Was it helpful?

Solution

After checking the result from event_base_get_method, I found out that only on my hpux-itanium used devpoll method. This is how I solve it.

    char string[8] = "devpoll";
    struct user_data user_data;
    struct bufferevent *in_buffer;
    struct event_config *evconfig;
    const char *method;
    const char *devpoll;

    devpoll = string;
    in_buffer = NULL;
    user_data.fd = fd;
    user_data.h = h;
    user_data.buf = buf;

    evconfig = event_config_new();
    if (evconfig == NULL) {
            log_error("event_config_new failed");
            return -1;
    }

    if (event_config_require_features(evconfig, EV_FEATURE_FDS)!=0) {
            log_error("event_config_require_features failed");
            return -1;
    }

    if (event_config_avoid_method(evconfig,devpoll) != 0)
    {
            log_error("Failed to ignore devpoll method");
    }

Force the libevent to ignore using devpoll and use poll instead.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top