Hello, I hope this message finds you well.
The following issue is likely self-inflicted but it is not clear how at this point. The attached test code is a program that runs with two threads (the main thread and a child pthread). The main thread: 1. Initializes the child event watchers (one async, one timer) 2. Calls pthread_create() which results in the ev_run() executing in the child thread 3. calls ev_timer_start() with a value of 0.5 seconds 4. sleeps for several seconds, to ensure that the child thread will get called Note: I typically use pthread conditionals to ensure that an event on another thread gets executed. The child thread: 1. After the ev_timer_start() is called it *should* wake up 0.5 seconds later, printing out a message showing that the callback has occurred What I see happening, instead of waking up 0.5 seconds later, is it takes roughly 60 seconds for the timer to start going off. I put some debug in the ev.c code and determined that within the ev_run() function, the waittime getting passed to backend_poll was 59.793 seconds. It appears as though ev_timer_start() does not cause the backend_poll to wake up. Is this the expected behavior or am I doing something wrong? I have also attached the config.log file so you can see the architecture where I am having problems. Note that I also tried the same program on a x64 system with the same results. Thanks very much for your time. Regards, Chris Zahka
config.log
Description: Binary data
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#include <ev.h>
#include <unistd.h>
#include <pthread.h>
static ev_async m_HaltChildWatcher;
static ev_timer m_PeriodicTimerWatcher;
static struct ev_loop *m_ChildLoop;
static void* DoChildProcessingInThread(void* args)
{
ev_run(m_ChildLoop, 0);
pthread_exit(NULL);
return NULL;
}
static void PeriodicTimerCallback(struct ev_loop *loop, ev_timer *watcher,
int revents)
{
printf("PeriodicTimerCallback()\n");
}
static void HaltChildCallback(struct ev_loop *loop, ev_async *watcher,
int revents)
{
ev_async_stop(loop, watcher);
ev_timer_stop(loop, &m_PeriodicTimerWatcher);
ev_break(loop, EVBREAK_ALL);
}
static int InitializeChild(const float timeout)
{
m_ChildLoop = ev_loop_new(0);
ev_async_init(&m_HaltChildWatcher, HaltChildCallback);
ev_async_start(m_ChildLoop, &m_HaltChildWatcher);
ev_timer_init(&m_PeriodicTimerWatcher, PeriodicTimerCallback, timeout,
timeout);
return 0;
}
static void StartTimer()
{
if (!ev_is_active(&m_PeriodicTimerWatcher)) {
ev_timer_start(m_ChildLoop,
&m_PeriodicTimerWatcher);
}
}
static int StartChild(pthread_t *thread, const pthread_attr_t *attr)
{
const int status = pthread_create(thread, attr, DoChildProcessingInThread,
NULL);
if (0 != status) {
printf("Thread failed to create. errno = %s\n", strerror(status));
return -1;
}
return 0;
}
static void StopChild()
{
if (!(ev_async_pending(&m_HaltChildWatcher))) {
ev_async_send(m_ChildLoop, &m_HaltChildWatcher);
}
}
static void CleanupChild()
{
ev_loop_destroy(m_ChildLoop);
}
int main(int argc, char **argv)
{
if (argc != 2) {
printf("must specify a 0 or 1\n");
return -1;
}
const int beforeOrAfter = atoi(argv[1]);
if (0 == beforeOrAfter) {
printf("Starting timer before event loop starts running\n");
} else if (1 == beforeOrAfter) {
printf("Starting timer after event loop starts running\n");
} else {
printf("invalid argument\n");
return -1;
}
pthread_t thread;
pthread_attr_t attr;
pthread_attr_init(&attr);
int result = InitializeChild(0.5);
if (0 != result) {
printf("InitializeChild() failed. exiting\n");
return -1;
}
if (0 == beforeOrAfter) {
StartTimer();
}
result = StartChild(&thread, &attr);
if (0 != result) {
printf("StartChild() failed. exiting\n");
return -1;
}
sleep(1); // attempting to ensure that ev_run() has started in the child
// thread before proceeding
if (1 == beforeOrAfter) {
StartTimer();
}
sleep(65); // currently sleeping for 65 seconds since the default time
// epoll_poll() will sleep is MAX_BLOCKTIME (~60 seconds)
StopChild();
result = pthread_join(thread, NULL);
if (0 != result) {
printf("pthread_join() failed. exiting\n");
return -1;
}
CleanupChild();
return (1);
}
Makefile
Description: Binary data
_______________________________________________ libev mailing list [email protected] http://lists.schmorp.de/cgi-bin/mailman/listinfo/libev
