5

I have a thread that continuously reads a serial port for data. If the main program receives a SIGINT it calls g_thread_join() on the serial port thread.

However, since the read is blocking the serial port thread won't return and program stalls untill i get a byte on the serial line and then it can exit.

Is there a way to pass the SIGINT on to read() so that it can be forced to return when the main thread demands it?

evading
  • 3,032
  • 6
  • 37
  • 57
  • 1
    Would this help? http://stackoverflow.com/questions/10522277/how-can-i-implement-timeout-for-read-when-reading-from-a-serial-port-c-c -- it shows you how to read with a timeout, so the SIGINT will eventually be acted upon – michel-slm Feb 21 '14 at 15:46
  • You should have some event loop and use [poll(2)](http://man7.org/linux/man-pages/man2/poll.2.html). – Basile Starynkevitch Feb 21 '14 at 16:17
  • No, you can't pass a signal to a thread. Instead use timed read (above), or use eventfd() or similar to poll on two descriptors and use one of them to wake up. – Valeri Atamaniouk Feb 21 '14 at 16:29
  • With `pthread_kill` you can pass a signal to a thread. This can indeed be used to interrupt a `read`. – lanoxx Jan 20 '20 at 15:07

2 Answers2

5

To have read() return EINTR, unset SA_RESTART in the member sa_flags of the struct sigaction passed into the call to sigaction() when installing the signal handler for SIGINT.


An alternative approach woud be to avoid a blocking read() at all. Please see the answers to this question: how to avoid blocking from the read function?

Community
  • 1
  • 1
alk
  • 69,737
  • 10
  • 105
  • 255
  • I did not get it to work when just clearing SA_RESTART. Are there any pitfalls to watch out for in using that method, do you know? Thanks! – evading Feb 24 '14 at 08:18
  • @evading: Seeing the source you implemented your solution with would help a lot. – alk Feb 24 '14 at 12:05
4

The accepted answer for this previous question on implementing timeout for read() when reading from a serial port shows how to use select(2) to perform reading with timeout. The SIGINT signal you send will thus be eventually acted upon.

Community
  • 1
  • 1
michel-slm
  • 9,438
  • 3
  • 32
  • 31