[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

[Libevent-users] Trivial Example of Multi-Thread Issue



Hi guys,

  I’ve been trying to track down a bug with multi-thread use of libevent.   I’m only using the timeout feature of libevent (no fd’s).  I’ve dumbed down the issue to a simple example which is copied in below.    This code deadlocks waiting for the event to occur.

 

[ Psuedo Code ]

<thread 1: main>

* kicks of thread 2

* waits for other thread to alloc a base+event

* adds event

* waits for callback to occur (which never happens)

* exits

<thread 2>

* alloc’s event base + event

* dispatches

 

Any idea’s why this doesn’t work?   And yes I’ve called evthread_use_pthreads ;^)

 

I’ve tried this on a Fedora 15 and OSX box with the same results.  Although I tried with the package managed versions I also tried and got the same results with the trunk of the git tree, release-2.1.3-alpha-44-g197abd8 (on the Fedora box only).

 

Regards,

Dave

 

Build the following with “gcc -Wall -o event-test main.c -lrt -levent -levent_pthreads”

 

#include <stdio.h>

#include <event.h>

#include <pthread.h>

#include <errno.h>

#include <string.h>

#include <unistd.h>

#include <semaphore.h>

#include <event2/thread.h>

#include <fcntl.h>

 

struct event_base* eb = NULL;

struct event *ev = NULL;

sem_t *sem;

const struct timeval tv = {

    .tv_sec = 2,

    .tv_usec = 0

};

 

 

void cb_sem_post(evutil_socket_t fd, short val, void *arg)

{

    printf("Running %s\n", __func__);

    sem_post(sem);

}

 

 

void *new_thread(void *arg)

{

    printf("Running %s\n", __func__);

 

    /* initialize libevent */

    if(evthread_use_pthreads()) {

        fprintf(stderr, "evthread_use_pthreads failed: %s\n", strerror(errno));

        return 0;

    }

    eb = event_base_new();

    ev = evtimer_new(eb, cb_sem_post, 0);

    if(!ev)

        fprintf(stderr, "evtimer_new failed: %s\n", strerror(errno));

   

    sem_post(sem);    /* ok free to use ev & eb from other thread */

    event_base_dispatch(eb);

 

    return 0;

}

 

 

int main(int argc, const char * argv[])

{

    pthread_t thread;

   

    printf("Running %s\n", __func__);

       

    /* initialize a semaphore */

    sem = sem_open("my_sem", O_CREAT, 0777, 0);

    if(sem == SEM_FAILED) {

        fprintf(stderr, "sem_open failed: %s\n", strerror(errno));

        return 1;

    }

  

    if(pthread_create(&thread, NULL, new_thread, 0)) {

        fprintf(stderr, "%s\n", strerror(errno));

        return 1;

    }

   

    sem_wait(sem);     /* ev has been allocated */

    //usleep(3000000);   /* wait till other thread good and sleeping */

   

    /* add event that will never expire */

    if(event_add(ev, &tv))

        fprintf(stderr, "%s\n", strerror(errno));

   

    printf("waiting for callback that never occurs\n");

    sem_wait(sem);

  

    printf("Exiting\n");

   

    /* clean up */

    event_base_loopexit(eb, NULL);

    if(ev) event_free(ev);

    if(eb) event_base_free(eb);

    pthread_join(thread, NULL);

    sem_close(sem);

   

    return 0;

}

 

_______________________________________________

Program output:

 

Running main

Running new_thread

[debug] event_add: event: 0xb6f00618 (fd 7), EV_READ   call 0xb788a7d3

[debug] Epoll ADD(1) on fd 7 okay. [old events were 0; read change was 1; write change was 0]

[debug] event_base_loop: no events registered.

[debug] event_add: event: 0xb6f00908 (fd -1),   EV_TIMEOUT call 0x80489e0

[debug] event_add: event 0xb6f00908, timeout in 2 seconds 0 useconds, call 0x80489e0

waiting for callback that never occurs