3

How can I pass arguments (e.g. a pointer to a struct) to a signal handler? I'm writing a multithread application, so I cannot use global variables

I associate a timer to each thread. When timer expires I have to update a struct (each thread has a different struct).

How can I do?

WindowsEFI
  • 31
  • 1
  • 5
  • How about using a thread-local variable then? – Kerrek SB Jul 24 '16 at 14:24
  • How can I pass a thread-local variable to signal handler? – WindowsEFI Jul 24 '16 at 14:44
  • Can you be more clear? Tell us what is the type of signal? And what is the format of output you desire! – kiner_shah Jul 24 '16 at 15:02
  • I'm writing a client server application. I use UDP socket, so I have to handle packet loss and retransmission. Server is multithreaded. Each thread has a timer associated to packet transmitted. I create timer by using timer_create() and timer_settime() and I use SIGUSR1. When timer expires I have to retransimit, so I need to pass thread specific data to the signal handler to retransmit and restart timer. – WindowsEFI Jul 24 '16 at 15:14
  • Use timerfd and stick the alarming FD in the same poll loop as the I/O FD? – Kerrek SB Jul 24 '16 at 17:58

2 Answers2

1

The way the signal handler is called by the system is fixed -- there's no way to change it and add an additional user pointer. So if you want to get additional data into the signal handler, the only way to do it is with a global variable (which could be thread-local).

However, if you are trying to use timer_create with threads, you are much better off using SIGEV_THREAD rather than SIGEV_SIGNAL. The latter sends the signal to the process rather than the thread, so it might be caught by any thread in the process.

Chris Dodd
  • 119,907
  • 13
  • 134
  • 226
  • glibc appears to allocate _Thread_local variables lazily and dynamically (with succeed-or-die malloc calls, which I don't like very much), so it seems at least the first access to a _Thread_local could be AS-unsafe. I couldn't find more info,on this, though. – Petr Skocik Nov 15 '17 at 15:55
1

POSIX timers allow to specify the details of how your process will be notified of an expiration using the struct sigevent structure documented in sigevent(7).

To pass context info to the siggnal handler for the generated signal, you can set the .sigev_value.sival_ptr member, which your signal handler will then be able to retrieve (you'll need to set the signal handler via the .sa_sigaction member of struct sigaction, while making sure the structure's .sa_flags is ORred with SA_SIGINFO).

Petr Skocik
  • 58,047
  • 6
  • 95
  • 142