views:

234

answers:

1

Hi all.

I'm esperiencing a SIGIO-related problem in a C++ program I'm working on.

  • Platform: Linux 2.6.30, x86 Arch
  • Scenario: async serial communication.

I followed this async-communication example from the Linux Serial Programming HowTo and it worked flawlessy.

Then I removed the "sleep+check wait_flag" thing and now I handle the read() part directly in signal_handler_IO(). That is, when some input is available, the signal handler is called and it forces a read on the serial port (*).

My code seems to work but unfortunately when new input is available the SIGIO signal is raised several times so I get spurious/incomplete reads (each SIGIO received forces a read).

I changed VMIN and VTIME serial options to control the read buffer (i.e. VMIN=255/VTIME=15, VMIN=50/VTIME=0, ...). I tried setting SA_SIGINFO flag (as suggested by some), but no success.

So:

  • what am I missing about SIGIO raising/handling?
  • is there a way to avoid this "SIGIO storm"?
  • is there any way to control SIGIO raising policies?

Thanks in advance.

Bye.

(*): actually I'm following this C++ FAQ Lite hint so the signal handler calls a member function of an object that encapsulates all my serial handling stuff. Unfortunately the problem still happens, even if I invoke read() in the signal handler itself.

+2  A: 

You are calling read while in a signal handler? This is bad. Very few functions are async-signal safe. The SIGIO storm might be caused by read sending SIGIO recursively. Your signal handler should just set a flag and return immediately.

Tobu
No, the signal handler (as suggested by C++ FAQ Lite) calls a member function of a non-static object that does the actual read().Anyway I found a simple solution: I've added a buffer (with thread-safe access) for the read bytes. Each time the signal handler is called, I do the read() on serial port and the read bytes are appended to that buffer.Then the "SIGIO storm" problem is solved because I can extract what I need by reading that buffer when I want.PS: thanks for your reply.
Gian Paolo Ghilardi
I'm glad you found a way. To clarify my point about signal-safety: It doesn't matter that you were calling a member function; the top of your stack was still the signal handler.
Tobu
You can't call read() in the signal handling context. That is, the signal handler can not call read() nor can anything the signal handler calls.
sharth