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