Unix Programming - Realtime SIGIO signals questions (linux)

This is Interesting: Free IT Magazines  
Home > Archive > Unix Programming > July 2004 > Realtime SIGIO signals questions (linux)





You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

Author Realtime SIGIO signals questions (linux)
Mike Richer

2004-07-23, 5:53 pm

I'm building a network/socket based application and thought I'd give
realtime signals a go. I've gotten the application working so far on a linux
2.4 based system, but there are a few mysteries left uncovered, and I'm
severly lacking in documentation. If anyone can answer a few of the
following, that would definetly be appreciated.

1) Anyone know of any good coding examples / good documentation surrounding
POSIX.4 real time signals / real world implementations, specifically around
SIGIO would be great. I've scoured google with not too much luck.

Ok, now for the nitty gritty... Typically when coding non-realtime signals,
specifically the SIGIO signal, in the handler you poll to see which file
descriptors are ready and perform some form of action. You typically have
to "read" on these descriptors until there's nothing left to read since
signals won't queue and then you return. In real-time signals however, the
behaviour is a bit different. For one, in my current implementation I'm
setting SA_SIGINFO so that I'm notified which file descriptor the signal is
referring to. So here's the questions:

2) If multiple blocks of data are received on the socket, causing multiple
SIGIOs to be queued, when in the handler, how much will I "read"? In other
words, if 2 "blocks" of data are available on the socket before the first
SIGIO is caught and processed, and I were to read SSIZE_MAX worth of data
(assuming the data is smaller than that) in the first instance of the
handler, will I get both blocks of data in the first instance, and then
read -1/EGAIN when the queued SIGIO fired?

Since I somewhat ported my non-realtime version to the realtime version of
SIGIO, my current implementation reads everything there is before return by
issuing multiple "read"s until nothing is left, and then simply not caring
when "read" returns -1/EGAIN on successive queued SIGIOs on the same
descriptor, so again, it works fine, I'm just wondering if I have to, and if
I don't, will read only return the amount of data which originally triggered
the signal, however multiple reads will pull it all out?

3) 3rd and my most important question is, how to properly handle closed
sockets. I've noticed that after closing a socket, specifially from within
the signal handler, it is possible that there are still pending signals for
that descriptor, so after closing the socket, I still sometimes receive one
or two signals with si_fd pointing to the closed descriptor, and my read
will return EBADF. My worry is the following scenario...

I receive a packet causing a SIGIO. While in the handler, more data arrives,
causing a SIGIO to be queued. While in the first instance of the signal, I
decide to close the socket and open a new one. The new decriptor uses the
same descriptor as the one I just closed. When the queued signal fires, how
does one determine whether or not I'm reading stale data, or data from the
new socket.

4) So... when closing a socket, is there a way to flush any pending queued
signals for that descriptor?

Thanks in advance!
Mike



sean larsson

2004-07-23, 5:53 pm

On Fri, 23 Jul 2004 16:38:38 -0400
"Mike Richer" <nospam@notachance.com> wrote:

> I'm building a network/socket based application and thought I'd give
> realtime signals a go. I've gotten the application working so far on a linux
> 2.4 based system, but there are a few mysteries left uncovered, and I'm
> severly lacking in documentation. If anyone can answer a few of the
> following, that would definetly be appreciated.
>
> 1) Anyone know of any good coding examples / good documentation surrounding
> POSIX.4 real time signals / real world implementations, specifically around
> SIGIO would be great. I've scoured google with not too much luck.
>

http://www.kohala.com/start/unpv22e/unpv22e.html there is a directory in the source code examples with real time signals.

> Ok, now for the nitty gritty... Typically when coding non-realtime signals,
> specifically the SIGIO signal, in the handler you poll to see which file
> descriptors are ready and perform some form of action. You typically have
> to "read" on these descriptors until there's nothing left to read since
> signals won't queue and then you return. In real-time signals however, the
> behaviour is a bit different. For one, in my current implementation I'm
> setting SA_SIGINFO so that I'm notified which file descriptor the signal is
> referring to. So here's the questions:
>
> 2) If multiple blocks of data are received on the socket, causing multiple
> SIGIOs to be queued, when in the handler, how much will I "read"? In other
> words, if 2 "blocks" of data are available on the socket before the first
> SIGIO is caught and processed, and I were to read SSIZE_MAX worth of data
> (assuming the data is smaller than that) in the first instance of the
> handler, will I get both blocks of data in the first instance, and then
> read -1/EGAIN when the queued SIGIO fired?
>

depends on the protocol, with UDP you would read a record each read, and with tcp you would read as much as u could. but yes, once u read all available data you would get an EAGAIN or similar.

> Since I somewhat ported my non-realtime version to the realtime version of
> SIGIO, my current implementation reads everything there is before return by
> issuing multiple "read"s until nothing is left, and then simply not caring
> when "read" returns -1/EGAIN on successive queued SIGIOs on the same
> descriptor, so again, it works fine, I'm just wondering if I have to, and if
> I don't, will read only return the amount of data which originally triggered
> the signal, however multiple reads will pull it all out?
>

no, there is no relation between the amount of data available when you call read and the amount of data available when the signal is delivered. in linux, the sending of async i/o signals works like this:
+ a process registers for async i/o, in the driver/kernel code a flag is set to mark that file descriptor for async i/o
+ in the kernel, when data arrives for that device, it goes thru the list of processes waiting on async i/o and sends a signal to each one

so as long as your process is registered, it gets sent a signal each time data arrives to the underlying device. well, not device in this case, but rather the socket layer.

> 3) 3rd and my most important question is, how to properly handle closed
> sockets. I've noticed that after closing a socket, specifially from within
> the signal handler, it is possible that there are still pending signals for
> that descriptor, so after closing the socket, I still sometimes receive one
> or two signals with si_fd pointing to the closed descriptor, and my read
> will return EBADF. My worry is the following scenario...
>
> I receive a packet causing a SIGIO. While in the handler, more data arrives,
> causing a SIGIO to be queued. While in the first instance of the signal, I
> decide to close the socket and open a new one. The new decriptor uses the
> same descriptor as the one I just closed. When the queued signal fires, how
> does one determine whether or not I'm reading stale data, or data from the
> new socket.
>
> 4) So... when closing a socket, is there a way to flush any pending queued
> signals for that descriptor?
>

continuing, in most driver code i have looked at, once the descriptor is closed, the process is removed from the async i/o list and should NOT be sent any more signals. perhaps someone else knows if something is different with sockets??

> Thanks in advance!
> Mike
>
>
>



--
-sean
sean larsson

2004-07-23, 5:53 pm

i checked the socket code, and it does remove the process from the list when close is called, so that's not something u should be worried about. but also,


you won't ever get "stale" data. when the socket is closed, pending data is discarded.

On Fri, 23 Jul 2004 21:32:55 GMT
sean larsson <infamous42md@ERASEMEhotpop.com> wrote:
[vbcol=seagreen]
> On Fri, 23 Jul 2004 16:38:38 -0400
> "Mike Richer" <nospam@notachance.com> wrote:
>
> http://www.kohala.com/start/unpv22e/unpv22e.html there is a directory in the source code examples with real time signals.
>
> depends on the protocol, with UDP you would read a record each read, and with tcp you would read as much as u could. but yes, once u read all available data you would get an EAGAIN or similar.
>
> no, there is no relation between the amount of data available when you call read and the amount of data available when the signal is delivered. in linux, the sending of async i/o signals works like this:
> + a process registers for async i/o, in the driver/kernel code a flag is set to mark that file descriptor for async i/o
> + in the kernel, when data arrives for that device, it goes thru the list of processes waiting on async i/o and sends a signal to each one
>
> so as long as your process is registered, it gets sent a signal each time data arrives to the underlying device. well, not device in this case, but rather the socket layer.
>
> continuing, in most driver code i have looked at, once the descriptor is closed, the process is removed from the async i/o list and should NOT be sent any more signals. perhaps someone else knows if something is different with sockets??
>
>
>
> --
> -sean



--
-sean
Mike Richer

2004-07-23, 8:47 pm

Thanks a lot, you've been a great help.

In regards to the last piece, indeed when I close the sock the process it is
removed from the list, however I was concerned about already pending signals
when I perform the close. As in the example I provided, if i were in the
handler and decided to close the socket, and there was a pending signal for
that descriptor already, and I reopened a new sock from the same handler
before the pending signal is process, and that new socket re-uses the same
descriptor, when the handler gets invoced for the pending signal, I don't
know if I have stale data or new data. Is there no way to flush the pending
signals?

Mike


"sean larsson" <infamous42md@ERASEMEhotpop.com> wrote in message
news:20040723174223.1ec7ac41.infamous42md@ERASEMEhotpop.com...
> i checked the socket code, and it does remove the process from the list

when close is called, so that's not something u should be worried about.
but also,
>
arrives,[vbcol=seagreen]
signal, I[vbcol=seagreen]
the[vbcol=seagreen]
fires, how[vbcol=seagreen]
the[vbcol=seagreen]
>
> you won't ever get "stale" data. when the socket is closed, pending data

is discarded.
>
> On Fri, 23 Jul 2004 21:32:55 GMT
> sean larsson <infamous42md@ERASEMEhotpop.com> wrote:
>
linux[vbcol=seagreen]
I'm[vbcol=seagreen]
surrounding[vbcol=seagreen]
around[vbcol=seagreen]
in the source code examples with real time signals.[vbcol=seagreen]
signals,[vbcol=seagreen]
file[vbcol=seagreen]
have[vbcol=seagreen]
since[vbcol=seagreen]
the[vbcol=seagreen]
I'm[vbcol=seagreen]
signal is[vbcol=seagreen]
multiple[vbcol=seagreen]
other[vbcol=seagreen]
first[vbcol=seagreen]
data[vbcol=seagreen]
then[vbcol=seagreen]
with tcp you would read as much as u could. but yes, once u read all
available data you would get an EAGAIN or similar.[vbcol=seagreen]
version of[vbcol=seagreen]
return by[vbcol=seagreen]
caring[vbcol=seagreen]
and if[vbcol=seagreen]
triggered[vbcol=seagreen]
call read and the amount of data available when the signal is delivered. in
linux, the sending of async i/o signals works like this:[vbcol=seagreen]
set to mark that file descriptor for async i/o[vbcol=seagreen]
list of processes waiting on async i/o and sends a signal to each one[vbcol=seagreen]
time data arrives to the underlying device. well, not device in this case,
but rather the socket layer.[vbcol=seagreen]
closed[vbcol=seagreen]
within[vbcol=seagreen]
signals for[vbcol=seagreen]
receive one[vbcol=seagreen]
read[vbcol=seagreen]
arrives,[vbcol=seagreen]
signal, I[vbcol=seagreen]
the[vbcol=seagreen]
fires, how[vbcol=seagreen]
the[vbcol=seagreen]
queued[vbcol=seagreen]
closed, the process is removed from the async i/o list and should NOT be
sent any more signals. perhaps someone else knows if something is different
with sockets??[vbcol=seagreen]
>
>
> --
> -sean



sean larsson

2004-07-23, 8:47 pm

no, u can't clear pending signals. what do you mean stale data? each time the signal handler gets invoked, you are going to poll the descriptors to see which one caused the signal, and then read from it. if a signal arrived and was queued when you clos
ed the socket, then next time in the handler, when u polled the fds you wouldn't have any return ready and you could just exit the handler. unless im missing something else..

On Fri, 23 Jul 2004 19:49:55 -0400
"Mike Richer" <nospam@notachance.com> wrote:

> Thanks a lot, you've been a great help.
>
> In regards to the last piece, indeed when I close the sock the process it is
> removed from the list, however I was concerned about already pending signals
> when I perform the close. As in the example I provided, if i were in the
> handler and decided to close the socket, and there was a pending signal for
> that descriptor already, and I reopened a new sock from the same handler
> before the pending signal is process, and that new socket re-uses the same
> descriptor, when the handler gets invoced for the pending signal, I don't
> know if I have stale data or new data. Is there no way to flush the pending
> signals?
>
> Mike
>
>
> "sean larsson" <infamous42md@ERASEMEhotpop.com> wrote in message
> news:20040723174223.1ec7ac41.infamous42md@ERASEMEhotpop.com...
> when close is called, so that's not something u should be worried about.
> but also,
> arrives,
> signal, I
> the
> fires, how
> the
> is discarded.
> linux
> I'm
> surrounding
> around
> in the source code examples with real time signals.
> signals,
> file
> have
> since
> the
> I'm
> signal is
> multiple
> other
> first
> data
> then
> with tcp you would read as much as u could. but yes, once u read all
> available data you would get an EAGAIN or similar.
> version of
> return by
> caring
> and if
> triggered
> call read and the amount of data available when the signal is delivered. in
> linux, the sending of async i/o signals works like this:
> set to mark that file descriptor for async i/o
> list of processes waiting on async i/o and sends a signal to each one
> time data arrives to the underlying device. well, not device in this case,
> but rather the socket layer.
> closed
> within
> signals for
> receive one
> read
> arrives,
> signal, I
> the
> fires, how
> the
> queued
> closed, the process is removed from the async i/o list and should NOT be
> sent any more signals. perhaps someone else knows if something is different
> with sockets??
>
>



--
-sean
Mike Richer

2004-07-23, 8:47 pm

I think I got it. Here's what I was thinking... After closing the sock, I
open a new one (within the same handler). The new sock happens to be using
the same descriptor as the old one. When the queued signal fires, the
desciptor would be valid. For some reason my brain was thinking that the
data which caused the queued SIGIO would still be available on that socket.
However the "close" would have flushed the data, correct? And therefore,
unless my new sock has some newly arrived data, I'm just going to
read -1/EGAIN.

Mike

"sean larsson" <infamous42md@ERASEMEhotpop.com> wrote in message
news:20040723205624.6fda83e9.infamous42md@ERASEMEhotpop.com...
> no, u can't clear pending signals. what do you mean stale data? each

time the signal handler gets invoked, you are going to poll the descriptors
to see which one caused the signal, and then read from it. if a signal
arrived and was queued when you closed the socket, then next time in the
handler, when u polled the fds you wouldn't have any return ready and you
could just exit the handler. unless im missing something else..
>
> On Fri, 23 Jul 2004 19:49:55 -0400
> "Mike Richer" <nospam@notachance.com> wrote:
>
it is[vbcol=seagreen]
signals[vbcol=seagreen]
for[vbcol=seagreen]
same[vbcol=seagreen]
don't[vbcol=seagreen]
pending[vbcol=seagreen]
list[vbcol=seagreen]
data[vbcol=seagreen]
uses[vbcol=seagreen]
from[vbcol=seagreen]
data[vbcol=seagreen]
give[vbcol=seagreen]
on a[vbcol=seagreen]
and[vbcol=seagreen]
the[vbcol=seagreen]
specifically[vbcol=seagreen]
directory[vbcol=seagreen]
which[vbcol=seagreen]
typically[vbcol=seagreen]
however,[vbcol=seagreen]
implementation[vbcol=seagreen]
In[vbcol=seagreen]
the[vbcol=seagreen]
of[vbcol=seagreen]
the[vbcol=seagreen]
and[vbcol=seagreen]
not[vbcol=seagreen]
same[vbcol=seagreen]
to,[vbcol=seagreen]
you[vbcol=seagreen]
in[vbcol=seagreen]
flag is[vbcol=seagreen]
case,[vbcol=seagreen]
from[vbcol=seagreen]
my[vbcol=seagreen]
data[vbcol=seagreen]
uses[vbcol=seagreen]
from[vbcol=seagreen]
pending[vbcol=seagreen]
descriptor is[vbcol=seagreen]
different[vbcol=seagreen]
>
>
> --
> -sean



sean larsson

2004-07-23, 8:47 pm

exactly. the close discards any data in the socket buffer.

On Fri, 23 Jul 2004 21:20:30 -0400
"Mike Richer" <nospam@notachance.com> wrote:

> I think I got it. Here's what I was thinking... After closing the sock, I
> open a new one (within the same handler). The new sock happens to be using
> the same descriptor as the old one. When the queued signal fires, the
> desciptor would be valid. For some reason my brain was thinking that the
> data which caused the queued SIGIO would still be available on that socket.
> However the "close" would have flushed the data, correct? And therefore,
> unless my new sock has some newly arrived data, I'm just going to
> read -1/EGAIN.
>
> Mike
>
> "sean larsson" <infamous42md@ERASEMEhotpop.com> wrote in message
> news:20040723205624.6fda83e9.infamous42md@ERASEMEhotpop.com...
> time the signal handler gets invoked, you are going to poll the descriptors
> to see which one caused the signal, and then read from it. if a signal
> arrived and was queued when you closed the socket, then next time in the
> handler, when u polled the fds you wouldn't have any return ready and you
> could just exit the handler. unless im missing something else..
> it is
> signals
> for
> same
> don't
> pending
> list
> data
> uses
> from
> data
> give
> on a
> and
> the
> specifically
> directory
> which
> typically
> however,
> implementation
> In
> the
> of
> the
> and
> not
> same
> to,
> you
> in
> flag is
> case,
> from
> my
> data
> uses
> from
> pending
> descriptor is
> different
>
>



--
-sean
Sponsored Links






Free braindumps | Software forum | Database administration forum

Copyright 2003 - 2008 webservertalk.com