I have a small X11 application which has two threads.
In one thread, I am listening to X11 events using XGrabKey() and then in a loop XNextEvent(). The other thread is doing other stuff and is not related to X11.
Here's the code of the relevant thread:
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/XF86keysym.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
volatile bool loop = true;
void keyGrab(void)
{
Display *display = XOpenDisplay(0);
Window root = DefaultRootWindow(display);
int keycode = XKeysymToKeycode(display, XF86XK_AudioPlay);
XGrabKey(display, keycode, AnyModifier, root, False, GrabModeAsync, GrabModeAsync);
XSelectInput(display, root, KeyPressMask);
while (loop) {
XEvent event;
XNextEvent(display, &event);
switch (event.type) {
case KeyPress: puts("Play key pressed"); break;
}
}
XUngrabKey(display, keycode, AnyModifier, root);
XCloseDisplay(display);
}
The goal is that the other thread can tell this thread to stop.
Now the problem is that setting loop = false in the other thread will of course not terminate this thread, at least not immediately. This thread is stuck in XNextEvent() because that's a blocking call. So here's my question: What is the standard pattern how to get XNextEvent() to return?
I guess I need the other Thread to use XSendEvent(), but I couldn't find any hints on how to do that. I wouldn't even know which message type would be appropriate. Would it be ClientMessage? Something else? I actually tried sending a ClientMessage from the other thread, but I got the following error message:
X Error of failed request: BadValue (integer parameter out of range for operation)
Major opcode of failed request: 25 (X_SendEvent)
Value in failed request: 0x0
Serial number of failed request: 12
Current serial number in output stream: 12
Here's the relevant code snippet from the other thread that I tried and triggered the error (display and root are initialized by the first thread):
XEvent event;
memset(&event, 0, sizeof(event));
event.type = ClientMessage;
XSendEvent(display, root, False, 0, &event);
Note that the other thread doesn't need any X11 code by itself. The only purpose why the other thread would use X11 is to tell this thread to terminate.
Please keep in mind that there is no window in context. The root window of course does not count, as this is only for globally catching keys. So, destroying the window is not a solution.
According to these pages
how to quit the blocking of xlib's XNextEvent
http://www.linuxquestions.org/questions/programming-9/xnextevent-select-409355/#post2431460
The best solution would be perform a select on the X event queue socket
getting the socket is achieved by
#include <stdio.h>
#include <stdlib.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
Display *dis;
Window win;
int x11_fd;
fd_set in_fds;
struct timeval tv;
XEvent ev;
int main() {
dis = XOpenDisplay(NULL);
win = XCreateSimpleWindow(dis, RootWindow(dis, 0), 1, 1, 256, 256,\
0, BlackPixel (dis, 0), BlackPixel(dis, 0));
// You don't need all of these. Make the mask as you normally would.
XSelectInput(dis, win,
ExposureMask | KeyPressMask | KeyReleaseMask | PointerMotionMask |
ButtonPressMask | ButtonReleaseMask | StructureNotifyMask
);
XMapWindow(dis, win);
XFlush(dis);
// This returns the FD of the X11 display (or something like that)
x11_fd = ConnectionNumber(dis);
// Main loop
while(1) {
// Create a File Description Set containing x11_fd
FD_ZERO(&in_fds);
FD_SET(x11_fd, &in_fds);
// Set our timer. One second sounds good.
tv.tv_usec = 0;
tv.tv_sec = 1;
// Wait for X Event or a Timer
if (select(x11_fd+1, &in_fds, 0, 0, &tv))
printf("Event Received!\n");
else
// Handle timer here
printf("Timer Fired!\n");
// Handle XEvents and flush the input
while(XPending(dis))
XNextEvent(dis, &ev);
}
return(0);
}
Use XCheckWindowEvent in your message loop to see if there are any messages (followed by XNextEvent if one exists), and since this is non-blocking you can proceed to use pthread_cond_timedwait or whatever equivalent may exist in the threading library you are using. That way the blocking is in your hands rather than xlib's. If it times out it will check for another event, and then resume to waiting for your thread.
Related
I want to simulate Java's behavior of waiting until all threads in the process finish before the main exits in C/Windows API.
The behavior I want to simulate is one of the sample code below(it spams [second thread] active threads: 2., and does not terminate even when main returns):
public final class Test1
{
// | prints current thread count and queues the next iteration.
static void step() {
System.out.println (
"[second thread] active threads: " +
Thread.activeCount() +
"."
);
new Thread(() -> step()).start();
}
public static void main(String[] args) throws Exception
{
// | queue the first iteration.
new Thread(() -> step()).start();
}
}
My initial idea was to completely take over the main of my program, and instead do all the work in another function, eg main2 and if it finishes early, I will wait until the rest of the threads finish.
My problem is that my main has no idea what other threads exist, and even if it did know what other threads existed, after they all finish, it is still possible that they have spawned more threads, that we are again not aware of.
My approach to tackle this looks something as follows:
main.c would contain the actual main, and the actual main logic would be moved out to main2(or something with a better name). main would potentially resort to using CreateToolhelp32Snapshot to discover threads that do not match its own GetThreadId and wait for them(potentially aggregating existing threads to avoid only fetching one existing thread at a time, to take advantage of WaitForMultipleObjects).
/**
* #file main.c
*/
#include <Windows.h>
// | This function will can start threads without worrying about them
// | ending as soon as it finishes.
extern int main2(int argc, char **argv);
// | NOT IMPLEMENTED: I have no idea if such a service exists, but it can probably be
// | implemented using CreateToolhelp32Snapshot.
// | If it did exist, it would return a single thread from the process
// | not matching the current thread id.
extern HANDLE WINAPI SorceryToDiscoverASingleOtherThreadThatExists();
int main(int argc, char **argv)
{
int returnValue;
// | main2 will do the actual main's work.
returnValue = main2(argc, argv);
// | Do not finish before other threads finish.
for (;;) {
HANDLE hThread;
// | Find a single thread handle whose thread id is
// | not the same as the current thread's.
hThread = SorceryToDiscoverASingleOtherThreadThatExists();
// | If there are no more threads,
// | we can finally break out of this infinite loop.
if (hThread == 0) {
break;
}
WaitForSingleObject(hThread, INFINITE);
}
return 0;
}
And main2.c which would behave as our java program would:
/**
* #file main2.c
*/
#include <Windows.h>
#include <stdio.h>
DWORD CALLBACK ThreadProc0001(LPVOID unused) {
puts("Hello, World!");
CreateThread(0, 0, ThreadProc0001, 0, 0, 0);
return 0;
}
int main2(int argc, char **argv)
{
CreateThread(0, 0, ThreadProc0001, 0, 0, 0);
return 0;
}
With proof of concept to make sure the above code works(deep_thread_nesting.c):
/**
* #file deep_thread_nesting.c
*/
#include <Windows.h>
#include <stdio.h>
DWORD CALLBACK ThreadProc0001(LPVOID unused) {
puts("Hello, World!");
CreateThread(0, 0, ThreadProc0001, 0, 0, 0);
return 0;
}
int main(int argc, char **argv)
{
CreateThread(0, 0, ThreadProc0001, 0, 0, 0);
// | Do not exit until user presses ctrl c.
for (;;) {
// | Reduce strain on the CPU from the infinite loop.
Sleep(1000);
}
return 0;
}
My problem is that I feel forced to use one of three incredibly ugly solutions:
The first involving the mystical CreateToolhelp32Snapshot function as this tutorial describes, in order to fetch one(or potentially be optimized further to return more than one thread that does not match our active thread id) thread handle(s) that we can use to wait on.
The second involving keeping a global registry of all the handles and having each thread lock the world, add the handle to the registry, remove its own handle, and unlock the world, possibly writing my own CreateThread wrapper that takes care of this for me.
The third being a rough idea, as I have no idea if this even works the way I think it does, hooking the CreateThread function to make all threads implement the second solution.
Question
Is there a way to make C or Windows API wait for all my threads to finish
before terminating the program without effectively writing my own runtime?
Not really an answer, but, as mentioned by IInspectable, ExitProcess is called by the CRT. So getting rid of the CRT the behaviour that you are looking for is restored.
Compile with /NODEFAULTLIB, include libraries using the command line and not #pragma comment(lib, ...).
#include <Windows.h>
DWORD WINAPI other_thread(LPVOID lpThreadParameter)
{
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
if ((hOut == INVALID_HANDLE_VALUE) ||
(!hOut))
{
if (IsDebuggerPresent()) __debugbreak();
return -1;
}
constexpr char string[] = "I am writing!\r\n";
for (;;)
{
WriteFile(hOut, string, sizeof(string), 0, 0);
}
return 0;
}
int mainCRTStartup()
{
HANDLE hThread = CreateThread(0, 0, other_thread, 0, 0, 0);
return 1;
}
The other_thread continues writing, even after the mainCRTStartup exits.
An answer that is closer to what the OP intended:
#include <windows.h>
#pragma comment(lib, "synchronization.lib")
// the program will not (usually) exit, until this counter is at 0
long long deployed_threads_counter;
// we need a place to store the user's function pointer,
// as the lpStartAddress parameter of CreateThread is already used
struct ThreadParameters
{
LPTHREAD_START_ROUTINE lpStartAddress;
LPVOID lpParameter;
};
// a wrapper around the user provided LPTHREAD_START_ROUTINE
DWORD WINAPI my_thread_start(LPVOID lpThreadParameter)
{
// dereferenced! my_create_thread can now exit
ThreadParameters thread_parameters = *(ThreadParameters*)lpThreadParameter;
WakeByAddressSingle(lpThreadParameter);
// actually do the work
BOOL result = thread_parameters.lpStartAddress(thread_parameters.lpParameter);
// signal that the thread has finished executing
InterlockedDecrement64(&deployed_threads_counter);
WakeByAddressSingle(&deployed_threads_counter);
return result;
}
// CreateThread substitude incurs the desired behaviour
HANDLE my_create_thread(
LPSECURITY_ATTRIBUTES lpThreadAttributes,
SIZE_T dwStackSize,
LPTHREAD_START_ROUTINE lpStartAddress,
LPVOID lpParameter,
DWORD dwCreationFlags,
LPDWORD lpThreadId)
{
InterlockedIncrement64(&deployed_threads_counter);
ThreadParameters thread_parameters =
{
lpStartAddress,
lpParameter,
};
// call my_thread_start instead, so that the thread exit is signaled
HANDLE hThread = CreateThread(
lpThreadAttributes,
dwStackSize,
my_thread_start,
&thread_parameters,
dwCreationFlags,
lpThreadId);
// do not destroy thread_parameters, until my_thread_start has finished using them
WaitOnAddress(&thread_parameters, &lpStartAddress, sizeof(LPTHREAD_START_ROUTINE), INFINITE);
return hThread;
}
// optionally set this behaviour to be the default
#define CreateThread my_create_thread
int use_this_main();
int main()
{
// execute user code
int result = use_this_main();
// wait for all threads to finish
while (auto temp = deployed_threads_counter)
{
WaitOnAddress(&deployed_threads_counter, &temp, sizeof(temp), INFINITE);
}
// fallthrough return
return result;
}
int use_this_main()
{
// your code here...
return 0;
}
Currently there is actually a race condition, if InterlockedIncrement64 is called after the main's WaitOnAddress. This can be prevented, with something like a double gate system, but the answer is already complicated enough.
Registering a level triggered eventfd on epoll_ctl only fires once, when not decrementing the eventfd counter. To summarize the problem, I have observed that the epoll flags (EPOLLET, EPOLLONESHOT or None for level triggered behaviour) behave similar. Or in other words: Does not have an effect.
Could you confirm this bug?
I have an application with multiple threads. Each thread waits for new events with epoll_wait with the same epollfd. If you want to terminate the application gracefully, all threads have to be woken up. My thought was that you use the eventfd counter (EFD_SEMAPHORE|EFD_NONBLOCK) for this (with level triggered epoll behavior) to wake up all together. (Regardless of the thundering herd problem for a small number of filedescriptors.)
E.g. for 4 threads you write 4 to the eventfd. I was expecting epoll_wait returns immediately and again and again until the counter is decremented (read) 4 times. epoll_wait only returns once for every write.
Yep, I read all related manuals carefully ;)
#include <sys/epoll.h>
#include <sys/eventfd.h>
#include <sys/types.h>
#include <unistd.h>
#include <pthread.h>
static int event_fd = -1;
static int epoll_fd = -1;
void *thread(void *arg)
{
(void) arg;
for(;;) {
struct epoll_event event;
epoll_wait(epoll_fd, &event, 1, -1);
/* handle events */
if(event.data.fd == event_fd && event.events & EPOLLIN) {
uint64_t val = 0;
eventfd_read(event_fd, &val);
break;
}
}
return NULL;
}
int main(void)
{
epoll_fd = epoll_create1(0);
event_fd = eventfd(0, EFD_SEMAPHORE| EFD_NONBLOCK);
struct epoll_event event;
event.events = EPOLLIN;
event.data.fd = event_fd;
epoll_ctl(epoll_fd, EPOLL_CTL_ADD, event_fd, &event);
enum { THREADS = 4 };
pthread_t thrd[THREADS];
for (int i = 0; i < THREADS; i++)
pthread_create(&thrd[i], NULL, &thread, NULL);
/* let threads park internally (kernel does readiness check before sleeping) */
usleep(100000);
eventfd_write(event_fd, THREADS);
for (int i = 0; i < THREADS; i++)
pthread_join(thrd[i], NULL);
}
When you write to an eventfd, a function eventfd_signal is called. It contains the following line which does the wake up:
wake_up_locked_poll(&ctx->wqh, EPOLLIN);
With wake_up_locked_poll being a macro:
#define wake_up_locked_poll(x, m) \
__wake_up_locked_key((x), TASK_NORMAL, poll_to_key(m))
With __wake_up_locked_key being defined as:
void __wake_up_locked_key(struct wait_queue_head *wq_head, unsigned int mode, void *key)
{
__wake_up_common(wq_head, mode, 1, 0, key, NULL);
}
And finally, __wake_up_common is being declared as:
/*
* The core wakeup function. Non-exclusive wakeups (nr_exclusive == 0) just
* wake everything up. If it's an exclusive wakeup (nr_exclusive == small +ve
* number) then we wake all the non-exclusive tasks and one exclusive task.
*
* There are circumstances in which we can try to wake a task which has already
* started to run but is not in state TASK_RUNNING. try_to_wake_up() returns
* zero in this (rare) case, and we handle it by continuing to scan the queue.
*/
static int __wake_up_common(struct wait_queue_head *wq_head, unsigned int mode,
int nr_exclusive, int wake_flags, void *key,
wait_queue_entry_t *bookmark)
Note the nr_exclusive argument and you will see that writing to an eventfd wakes only one exclusive waiter.
What does exclusive mean? Reading epoll_ctl man page gives us some insight:
EPOLLEXCLUSIVE (since Linux 4.5):
Sets an exclusive wakeup mode for the epoll file descriptor that is being attached to the target file descriptor, fd. When a wakeup event occurs and multiple epoll file descriptors are attached to the same target file using EPOLLEXCLUSIVE, one or more of the epoll file descriptors will receive an event with epoll_wait(2).
You do not use EPOLLEXCLUSIVE when adding your event, but to wait with epoll_wait every thread has to put itself to a wait queue. Function do_epoll_wait performs the wait by calling ep_poll. By following the code you can see that it adds the current thread to a wait queue at line #1903:
__add_wait_queue_exclusive(&ep->wq, &wait);
Which is the explanation for what is going on - epoll waiters are exclusive, so only a single thread is woken up. This behavior has been introduced in v2.6.22-rc1 and the relevant change has been discussed here.
To me this looks like a bug in the eventfd_signal function: in semaphore mode it should perform a wake-up with nr_exclusive equal to the value written.
So your options are:
Create a separate epoll descriptor for each thread (might not work with your design - scaling problems)
Put a mutex around it (scaling problems)
Use poll, probably on both eventfd and epoll
Wake each thread separately by writing 1 with evenfd_write 4 times (probably the best you can do).
Upon closely scouring through resources, I'm still not entirely sure how to write a proper and usable timer function in C. I am not working with threads (or parallelizable code). I simply want to write a stopwatch function that I can use to trigger a bit of code after a small amount of time has passed.
This is a very common use of a timer, in the situation of "time-out", where I have a client-server set up where the client is sending some data (UDP style with sendto(...) and recvfrom(...)). I have written my system so that the client sends a chunk of data in a packet struct I have defined, and the server processes it via CRC then sends back an acknowledgement packet (ACK) that the msg was received uncorrupted. However, I want to implement a time-out, where if the client does not receive an ACK in a certain period of time, the client resends the data chunk (of course the server is rigged to check for duplicates). I want to nest this bit of timer code in the client, and for some reason do not think this should be so difficult.
I have dug up old signal handling code from work I had done long ago, as this seems to be the only way I commonly see mentioned as a solution, can someone please guide me as to how I can use the following signal handling code to not just receive a timed signal but trigger an action of some sort. Conceptually, I feel it would be: "send data, start timer, after timer expires execute a resend, reset timer...repeat until that ACK received". Better yet, would be an easier way of writing a timer function, but it doesn't look like there's much hope for that given C is a low-level language....
#include <sys/time.h>
#include <errno.h>
#include <stdio.h>
#include <signal.h>
extern char *strsignal(int sig);
void timer_handler(int a)
{
// handle signal
printf(">>>> signal caught\n");
printf(">>>> int parameter = %s\n", (char*) strsignal(a));
}
int main(int argc, char* argv[])
{
int retval;
struct itimerval timerValue;
struct itimerval oldTimerValue;
struct sigaction action;
action.sa_handler = &timer_handler;
action.sa_flags = SA_NODEFER;
// initialize timer parameters: expires in 5 seconds
timerValue.it_interval.tv_sec = 5;
timerValue.it_interval.tv_usec = 0;
timerValue.it_value.tv_sec = 5;
timerValue.it_value.tv_usec = 0;
// install signal handler to catch SIGALRM
//signal(SIGALRM, timer_handler);
sigaction(SIGALRM, &action, NULL);
retval = setitimer(ITIMER_REAL, &timerValue, &oldTimerValue);
if (-1 == retval)
perror("Could not set timer");
while(1);
return 0;
}
Xymostech provided the exact function I needed and after consulting the API for "select", which includes a small usage example, I modified the code there to fit what I needed and wrote a socket timer (for reads, those it's pretty simple to extend towards writes and such, as "select" has parameters for enabling this kind of check). Make sure you've included the following libraries as specified by the "select" API:
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <stdio.h>
The following is the waittoread(...) function I created from the API example and works pretty well. This works well in the domain of my specific problem, however, if one is looking for a more generalized timer (i.e. not just for timing socket read and writes, or file descriptors) please consult signal handling (somewhat in the spirit of the code I posted in my initial question).
#define S1READY 0x01 // necessary for the function's bitwise OR operation
int waittoread(int s1, int timeout_value){
fd_set fds; // create set of sockets to be waited on
struct timeval timeout; // the time-out value
int rc; // # of sockets that are ready before timer expires
int result;
/* Set time limit. */
timeout.tv_sec = timeout_value;
timeout.tv_usec = 0;
/* Create a descriptor set containing the socket. */
FD_ZERO(&fds); // MACRO to reset the socket storage set so new ones can be added
FD_SET(s1, &fds); // add the socket descriptor into the socket set to wait on
rc = select(sizeof(fds)*4, &fds, NULL, NULL, &timeout); // build the socket-wait system
// another way of calling select that would be a better approach:
// rc = select(s1 + 1), &fds, NULL, NULL, &timeout);
if (rc==-1) {
perror("Error: Call to select failed.");
return -1;
}
result = 0;
if (rc > 0){
if (FD_ISSET(s1, &fds)) result |= S1READY; // if the result is non-zero, perform a BIT-wise OR to extract the true socket count #
}
return result;
}
The main function is based on libevent, but there is a long run task in the function. So start N treads to run the tasks. Is is this idea OK? And how to use libevent and pthread together in C?
Bumping an old question, may have already been solved. But posting the answer just in case someone else needs it.
Yes, it is okay to do threading in this case. I recently used libevent in pthreads, and it seems to be working just fine. Here's the code :
#include <stdint.h>
#include <pthread.h>
#include <event.h>
void * thread_func (void *);
int main(void)
{
int32_t tid = 0, ret = -1;
struct event_base *evbase;
struct event *timer;
int32_t *t_ret = &ret;
struct timeval tv;
// 1. initialize libevent for pthreads
evthread_use_pthreads();
ret = pthread_create(&tid, NULL, thread_func, NULL);
// check ret for error
// 2. allocate event base
evbase = event_base_new();
// 3. allocate event object
timer = event_new(evbase, -1, EV_PERSIST, callback_func, NULL);
// 4. add event
tv.tv_sec = 0;
tv.tv_usec = 1000;
evtimer_add(timer, &tv);
// 5. start the event loop
event_base_dispatch(evbase); // event loop
// join pthread...
// 6. free resources
event_free(timer);
event_base_free(evbase);
return 0;
}
void * thread_func(void *arg)
{
struct event *ev;
struct event_base *base;
base = event_base_new();
ev = event_new(base, -1, EV_PERSIST, thread_callback, NULL);
event_add(ev, NULL); // wait forever
event_base_dispatch(base); // start event loop
event_free(ev);
event_base_free(base);
pthread_exit(0);
}
As you can see, in my case, the event for the main thread is timer. The base logic followed is as below :
call evthread_use_pthreads() to initialize libevent for pthreads on Linux (my case). For windows evthread_use_window_threads(). Check out the documentation given in event.h itself.
Allocate an event_base structure on global heap as instructed in documentation. Make sure to check return value for errors.
Same as above, but allocate event structure itself. In my case, I am not waiting on any file descriptor, so -1 is passed as argument. Also, I want my event to persist, hence EV_PERSIST . The code for callback functions is omitted.
Schedule the event for execution
Start the event loop
free the resources when done.
Libevent version used in my case is libevent2 5.1.9 , and you will also need libevent_pthreads.so library for linking.
cheers.
That would work.
In the I/O callback function delegates time consuming job to another thread of a thread pool. The exact mechanics depend on the interface of the worker thread or the thread pool.
To communicate the result back from the worker thread to the I/O thread use a pipe. The worker thread writes the pointer to the result object to the pipe and the I/O thread
wakes up and read the pointer from the pipe.
There is a multithreaded libevent example in this blog post:
http://www.roncemer.com/multi-threaded-libevent-server-example
His solution is, to quote:
The solution is to create one libevent event queue (AKA event_base) per active connection, each with its own event pump thread. This project does exactly that, giving you everything you need to write high-performance, multi-threaded, libevent-based socket servers.
NOTE This is for libev not libevent but the idea may apply.
Here I present an example for the community. Please comment and let me know if there are any noticable bugs. This example could include a signal handler for thread termination and graceful exit in the future.
//This program is demo for using pthreads with libev.
//Try using Timeout values as large as 1.0 and as small as 0.000001
//and notice the difference in the output
//(c) 2009 debuguo
//(c) 2013 enthusiasticgeek for stack overflow
//Free to distribute and improve the code. Leave credits intact
//compile using: gcc -g test.c -o test -lpthread -lev
#include <ev.h>
#include <stdio.h> // for puts
#include <stdlib.h>
#include <pthread.h>
pthread_mutex_t lock;
double timeout = 0.00001;
ev_timer timeout_watcher;
int timeout_count = 0;
ev_async async_watcher;
int async_count = 0;
struct ev_loop* loop2;
void* loop2thread(void* args)
{
// now wait for events to arrive on the inner loop
ev_loop(loop2, 0);
return NULL;
}
static void async_cb (EV_P_ ev_async *w, int revents)
{
//puts ("async ready");
pthread_mutex_lock(&lock); //Don't forget locking
++async_count;
printf("async = %d, timeout = %d \n", async_count, timeout_count);
pthread_mutex_unlock(&lock); //Don't forget unlocking
}
static void timeout_cb (EV_P_ ev_timer *w, int revents) // Timer callback function
{
//puts ("timeout");
if(ev_async_pending(&async_watcher)==false){ //the event has not yet been processed (or even noted) by the event loop? (i.e. Is it serviced? If yes then proceed to)
ev_async_send(loop2, &async_watcher); //Sends/signals/activates the given ev_async watcher, that is, feeds an EV_ASYNC event on the watcher into the event loop.
}
pthread_mutex_lock(&lock); //Don't forget locking
++timeout_count;
pthread_mutex_unlock(&lock); //Don't forget unlocking
w->repeat = timeout;
ev_timer_again(loop, &timeout_watcher); //Start the timer again.
}
int main (int argc, char** argv)
{
if (argc < 2) {
puts("Timeout value missing.\n./demo <timeout>");
return -1;
}
timeout = atof(argv[1]);
struct ev_loop *loop = EV_DEFAULT; //or ev_default_loop (0);
//Initialize pthread
pthread_mutex_init(&lock, NULL);
pthread_t thread;
// This loop sits in the pthread
loop2 = ev_loop_new(0);
//This block is specifically used pre-empting thread (i.e. temporary interruption and suspension of a task, without asking for its cooperation, with the intention to resume that task later.)
//This takes into account thread safety
ev_async_init(&async_watcher, async_cb);
ev_async_start(loop2, &async_watcher);
pthread_create(&thread, NULL, loop2thread, NULL);
ev_timer_init (&timeout_watcher, timeout_cb, timeout, 0.); // Non repeating timer. The timer starts repeating in the timeout callback function
ev_timer_start (loop, &timeout_watcher);
// now wait for events to arrive on the main loop
ev_loop(loop, 0);
//Wait on threads for execution
pthread_join(thread, NULL);
pthread_mutex_destroy(&lock);
return 0;
}
I have created a timer which can expire, in 5 seconds using timerfd_create, but i can see that it is waiting indefinitely.
Can someone help me?
Thanks in advance.
Here is my code:
enter code here
#include <sys/timerfd.h>
#include <sys/time.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/epoll.h>
#include <time.h>
int main()
{
struct itimerspec its;
struct epoll_event event, revent;
int timer_fd, efd;
/* Setting timer interval */
its.it_interval.tv_sec=1;
its.it_interval.tv_nsec=0;
/* Setting timer expiration */
its.it_value.tv_sec=5;
its.it_value.tv_nsec=0;
efd=epoll_create(2);
event.data.fd=timer_fd;
event.events=EPOLLIN;
epoll_ctl(efd, EPOLL_CTL_ADD, timer_fd, &event);
timer_fd=timerfd_create(CLOCK_REALTIME, 0);
if(timer_fd==-1)
{
perror("timerfd:");
}
if(timerfd_settime(timer_fd, TFD_TIMER_ABSTIME, &its, NULL)==-1)
{
perror("timerfd_settime error:");
}
printf("Starting the timer...");
while(1) {
epoll_wait(efd, &revent, 1, -1);
}
}
Reverse the order of calls to epoll_ctl and timerfd_create. Right now you are adding some random integer value to the event set.
Edit 0:
Several points:
timerfd_create(2) produces a file descriptor, just like open(2) or socket(2). You have to assign the return value to the timer_fd variable before giving it to the epoll_ctl(2), otherwise it's just a random integer value from the stack.
Don't use TFD_TIMER_ABSTIME - you are asking the kernel to start a timer that expires one second after the Epoch (which is not that big of a deal - it'll just expire immediately).
When the timer expires epoll_wait(2) returns the number of ready file descriptors, 1 in your example, and you are expected to handle that. You, on the other hand, just ignore that return value and spin around in a tight loop, so you don't even know the timer is expiring.
You need to read from timer file descriptor to consume the expiration event. Otherwise all subsequent calls to epoll_wait(2) will just return immediately since the descriptor remains in the "signaled" state.
Always check the return values of the system calls and handle error conditions based on the value of errno(3) - manual page for each call gives you possible error values.
Edit 1:
You do want a loop around the epoll_wait(2) (or select(2). or poll(2)), but you need:
handle the IO events being signaled (that's the whole point of these multiplexing APIs - being able to wait on multiple descriptors and dispatch the events), and
be able to break out of that loop (on a signal, on input from a dedicated file descriptor ala self-pipe trick, or on some application event).
Hope this helps.