UNIX/Linux signal handling: SIGEV_THREAD - c

I have put a simple signal handler in my code. I have initialised the sigevent structure, with a handler function to catch the signal.
Can someone please pin-point as to why the code is not working? Ideally if there is a signal, my handler should be called. But it is not.
Please help me,
Thanks
Kingsmasher1
enter code here
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <signal.h>
#include <time.h>
void my_handler(int sival_int, void* sival_ptr)
{
printf("my_handler caught\n");
signal(sig,my_handler);
}
int main()
{
struct sigevent sevp;
sevp.sigev_notify=SIGEV_THREAD;
sevp.sigev_signo=SIGRTMIN;
sevp.sigev_value.sival_ptr=NULL;
sevp.sigev_notify_function=(void*)my_handler;
kill(0,SIGRTMIN); // This should invoke the signal and call the function
}

struct sigevent is not about specifying how the process will handle a signal - struct sigaction and sigaction() are how you do that. Instead, struct sigevent is used to specify how your process will be informed of some asychronous event - like the completion of asychronous IO, or a timer expiring.
The sigev_notify field specifies how the event should be notified:
SIGEV_NONE - no notification at all. The remainder of the fields are ignored.
SIGEV_SIGNAL - a signal is sent to the process. The sigev_signo field specifies the signal, the sigev_value field contains supplementary data that is passed to the signal handling function, and the remainder of the fields are ignored.
SIGEV_THREAD - a function is called in a new thread. The sigev_notify_function field specifies the function that is called, sigev_value contains supplementary data that is passed to the function, and sigev_notify_attributes specifies thread attributes to use for the thread creation. The remainder of the fields are ignored.
Note in particular that if you set SIGEV_THREAD, the sigev_signo field is ignored - the struct sigevent is about specifying either a thread or a signal as a notification method, not about specifying a thread as the way that a signal should be handled.
The struct sigevent must also be passed to a function - like timer_create() - that sets up the asychronous event that will be notified. Simply creating a struct sigevent object does not do anything special.
If you wish to use a dedicated thread to handle a signal, create the thread up front and have it loop around, blocking on sigwaitinfo(). Use sigprocmask() to block the signal in every other thread.

I think you are mixing up your signal handling idioms here, you create a sigevent structure and then do nothing with it and then use signal() within the signal handler. The following code shows a very simple signal handling routine based on your code; note that I have changed the definition of my_handler. If you need more sophisticated handling then sigaction() is probably the system call you need to look into.
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <signal.h>
#include <time.h>
void my_handler(int sig)
{
printf("my_handler caught\n");
signal(sig,my_handler);
}
int main()
{
signal(SIGRTMIN,my_handler);
kill(0,SIGRTMIN); // This should invoke the signal and call the function
while(1) ; // Infinite loop in case the program ends before the signal gets caught!
}
This works under cygwin on my windows box (no access to a linux box at the minute).

I hope this works.
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <signal.h>
#include <time.h>
void
my_handler (int sig)
{
printf ("my_handler caught\n");
signal (sig, my_handler);
}
int
main ()
{
int signo;
struct sigevent sevp;
sigset_t set;
if (sigemptyset (&set) == -1)
perror ("sigemptyset");
if (sigaddset (&set, SIGRTMIN) == -1)
perror ("sigaddset");
if (sigprocmask (SIG_BLOCK, &set, NULL) == -1)
perror ("sigprocmask");
sevp.sigev_notify = SIGEV_THREAD;
sevp.sigev_signo = SIGRTMIN;
sevp.sigev_value.sival_ptr = NULL;
kill (0, SIGRTMIN);
if (sigwait (&set, &signo) == 0)
my_handler (signo);
else
perror ("sigwait");
}

Related

writing C program that goes off after 10 seconds

I want to write a C program that runs for a specified amount of seconds
say 10 seconds and then exits. The code should set up an interrupt to go
off after a specified amount of time has elapsed.
Here is my attempt. But I am not sure if SIGALRM is the correct way to do it.
Can SIGALRM be called an interrupt?
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#include <stdlib.h>
void handler()
{
_exit(0);
}
int main()
{
signal(SIGALRM, handler);
alarm(10);
for (;;); /* You can assume that for(;;); is just a dummy code. The main idea is to insert something into code. Whatever code it may be so that it stops after 10 seconds – */
return 0;
}
Any suggestions/alternatives/better way to achieve this?
The wording "signal" vs. "interrupt" is not fully clear. Signals can interrupt system calls, so a signal is an interrupt in this sense. But a signal is not a hardware interrupt. Whan you use an operating system, normal programs often don't have direct access to hardware interrupts.
Calling _exit from the signal handler might be problematic if your program needs to finish a task or to clean up something.
I suggest to implement a graceful end by setting a flag. Additionally I suggest to use sigaction instead of signal, because the semantics of signal and signal handlers set up with this function is implementation-dependent.
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#include <stdlib.h>
static volatile sig_atomic_t timeout = 0;
void handler(int sig)
{
(void) sig;
timeout = 1;
}
int main(void)
{
struct sigaction act;
memset(&act, 0, sizeof(act));
act.sa_handler = handler;
if(sigaction(SIGALRM, act, NULL) < 0)
{
// handle error
}
alarm(10);
while(!timeout /* and maybe other conditions */)
{
// do something, handle error return codes and errno (EINTR)
// check terminate flag as necessary
}
// clean up if necessary
return 0;
}
Explanation (as requested in a comment)
static volatile sig_atomic_t timeout = 0;
sig_atomic_t is a type that guarantees atomic access even in the presence of asynchronous interrupts made by signals. That means an access to the variable cannot be interrupted in between, i.e. the software will never see a partially modified value. (see https://en.cppreference.com/w/c/program/sig_atomic_t)
volatile informs the compiler not to optimize access to the variable. This is necessary because the signal handler may modify the value while the main function is running the loop that is intended to check the flag. Otherwise the compiler might optimize the access out of the loop condition and do it only once before the loop because the variable is never modified inside the loop. (see https://en.cppreference.com/w/c/language/volatile)

Setting settimer() and SIGALRM while condition variable is not signaled

I have some practical questions about the settimer() and SIGALRM and how they work .
Let's say that I have some threads created: (EDITED)
#define _POSIX_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <string.h>
#include <time.h>
#include <sys/time.h>
#include <signal.h>
pthread_mutex_t lock;
pthread_cond_t cond=PTHREAD_COND_INITIALIZER;
void timer_handler (int signum)
{
printf ("\n[WAITING LINE] All our assistants are busy at the moment,we apologize. Please wait on the line\n");
}
void* threadFunc(void* arg){
struct itimerval timer;
if (signal(SIGALRM, (void (*)(int)) timer_handler) == SIG_ERR) {
perror("Unable to catch SIGALRM");
exit(1);
}
timer.it_value.tv_sec =1;
timer.it_value.tv_usec = 0;
while(mycond){
if(setitimer (ITIMER_REAL, &timer, NULL)){
perror("error calling setitimer()");
exit(1);
}
pthread_cond_wait(&cond1,&lock);
//doing other things that take significant time
}
}
int main(){
//initializing mutex
....
//creating the threads
....
//waiting the threads to join
....
return 0;
}
I don't get the message I was supposed to see displayed every 20 msec.
In the example I followed a while(1) was implemented after the settimer but
I can't do that because I want this message displayed while my thread waits for the condition signal.
It doesn't really matter what is implemented in the rest code , let's assume it takes far more time than 20ms to finish and signal the condition.
What should I do to take the timer_handler message every 20ms while the condition is not signaled yet?
I am new to using both condition variables and settimer() so any help to understand them and solve any misunderstaning would be appreciated .
If all your threads are blocked, the virtual timer's clock will not be running.
You might need to switch to ITIMER_REAL. (Also beware that you shouldn't be using async-signal unsafe functions such as printf inside a signal handler.)

How can I resume execution of a function (not start it again) using swapcontext()?

I am building a pre-emptive userspace thread scheduler which uses a timer to interrupt threads and switch between them according to priority. However, once a thread is interrupted, I cannot seem to let it finish; only start it again. Is what I am asking for even possible using swapcontext? The result of this code, which should allow itake5seconds() to complete, just loops the "Hello" message over and over.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include <sys/time.h>
#include <ucontext.h>
static ucontext_t mainc, newthread;
void itake5seconds()
{
puts("Hello. I take 5 seconds to run.");
sleep(5);
puts("And I'm done! Wasn't that nice?");
}
void timer_handler(int signum)
{
puts("Doing some scheduler stuff.");
swapcontext(&mainc, &newthread);
}
int main(int argc, char* argv[])
{
struct sigaction sa;
memset(&sa, 0, sizeof(sa));
sa.sa_handler = &timer_handler;
sigaction(SIGALRM, &sa, NULL);
getcontext(&newthread);
newthread.uc_stack.ss_sp = malloc(5000);
newthread.uc_stack.ss_size = 5000;
newthread.uc_link = &mainc;
makecontext(&newthread, &itake5seconds, 0);
struct itimerval timer;
timer.it_value.tv_sec = 0;
timer.it_value.tv_usec = 500000;
timer.it_interval.tv_sec = 0;
timer.it_interval.tv_usec = 500000;
setitimer(ITIMER_REAL, &timer, NULL);
while(1);
return 0;
}
Your code is calling an "unsafe" function in the signal handler (swapcontext). Therefor, the behavior of your program is "undefined".
From man 7 signal:
A signal handler function must be very careful, since processing elsewhere may be interrupted at some arbitrary point in the execution of the program. POSIX has the concept of "safe function". If a signal interrupts the execution of an unsafe function, and handler calls an unsafe function, then the behavior of the program is undefined.
See the "Example for SVID Context Handling" section in Complete Context Control for an example of how you can work this with a signal handler. But basically you'd use a volatile int global variable to flag that your signal handler was called and instead do the swapcontext call from normal code (i.e. code that's not running from within the context of signal handling).
The problem was that I was not saving the current execution context that swapcontext() returns to its first parameter.

How to wait for time to expire

I would like to have a function run periodically, given a time step. What is the most efficient way to do this?
I know I could use a while look and just keep checking till the dt period has elapsed. But I'd like to know if there is a better, more efficient/elegant function to use.
I was looking into virtual timers and sigaction. Using this method, I would have the sigaction handler set a flag when the time has elapsed, but I would still need to sit in a while loop checking for that flag to be set in my main function. Alternatively I wonder if I could actually have the handler run the function, but then I would have to pass a lot of arguments, and as far as I have read, handlers don't take arguments, so I would have to use lots of global variables.
What would be the best way to tackled this?
On an *IX'ish system you could
install a handler for SIGALRM, which does nothing
set an alarm using alarm()
call blocking pause()
If the alarm signal is sent pause() will return and
you can run the function in question,
again set the alarm
start over calling pause()
#define _POSIX_SOURCE 1
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include <errno.h>
void handler_SIGALRM(int signo)
{
signo = 0; /* Get rid of warning "unused parameter ‘signo’" (in a portable way). */
/* Do nothing. */
}
int main()
{
/* Override SIGALRM's default handler, as the default handler might end the program. */
{
struct sigaction sa;
memset(&sa, 0, sizeof(sa));
sa.sa_handler = handler_SIGALRM;
if (-1 == sigaction(SIGALRM, &sa, NULL ))
{
perror("sigaction() failed");
exit(EXIT_FAILURE);
}
}
while (1)
{
alarm(2); /* Set alarm to occur in two seconds. */
pause(); /* The call blocks until a signal is received; in theis case typically SIGARLM. */
/* Do what is to be done every 2 seconds. */
}
return EXIT_SUCCESS;
}
The easiest way is to use sleep or usleep as defined in unistd.h.
If neither of those are available then a common workaround is to use a select with a timeout on no file descriptors.
Include time.h and use sleep function like
#include <time.h>
#include <stdio.h>
#include<windows.h>
#include <conio.h>
int main() {
printf("I am going to wait for 4 sec");
Sleep(4000); //sleep for 4000 microsecond= 4 second
printf("Finaaly the wait is over");
getch();
return 0;
}
It will give you a precise delay on microsecond level.
Hope it helped.

Indicating which thread set up timer handler?

Revisiting this question:
I have multiple threads running (pthreads api), each with it's own timer that calls a function handler(int signum) after a certain interval. As these threads call handler and within the function handler, how do I know which thread called it? Is thread-specific data required?
I notice that the thread that enters the handler function is a different thread from the one that set it up, so calling pthread_self() doesn't work. How do I get around this?
Here is a small example illustrating the problem
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <time.h>
#include <unistd.h>
void handler(int);
void call_alarm();
void *setup(void*);
pthread_t p;
void handler(int signum)
{
printf("handler thread %lu\n", pthread_self());
}
void call_alarm()
{
static struct itimerval timer;
static struct sigaction sa;
printf("call_alarm %lu\n", (unsigned long)pthread_self());
sa.sa_handler = handler;
sa.sa_flags = SA_RESETHAND;
timer.it_value.tv_usec = 500;
timer.it_value.tv_sec = 0;
timer.it_interval.tv_sec = 0;
timer.it_interval.tv_usec = 0;
sigaction(SIGALRM, &sa, 0);
setitimer(ITIMER_REAL, &timer, 0);
}
void *setup(void *param)
{
while(1)
{
printf("caller thread %lu\n", pthread_self());
call_alarm();
pause();
}
}
int main(void)
{
if(pthread_create(&p, NULL, setup, NULL));
while(1);
return 0;
}
Output:
caller thread 3086637968
call_alarm 3086637968
handler thread 3086640832
As you can see it prints out different values.
You can print the thread ID when the handler is called:
On Linux: gettid()
On Windows GetCurrentThreadId().
and if you can't, write a function wrapper around the handler and tell your code to call the wrapper function instead of calling the handler directly.
The POSIX chapter on Signal Generation and Delivery states:
At the time of generation, a determination shall be made whether the signal has been generated for the process or for a specific thread within the process. Signals which are generated by some action attributable to a particular thread, such as a hardware fault, shall be generated for the thread that caused the signal to be generated. Signals that are generated in association with a process ID or process group ID or an asynchronous event, such as terminal activity, shall be generated for the process.
I wonder if the SIGALRM signal you're catching is not considered a action attributable to a particular thread, such as a hardware fault. It sounds like your SIGALRM signal falls into the second category, and is being generated for the process.

Resources