Unix Programming - Why is data lost when got SIGUSR1 during recv() ?

This is Interesting: Free IT Magazines  
Home > Archive > Unix Programming > June 2004 > Why is data lost when got SIGUSR1 during recv() ?





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 Why is data lost when got SIGUSR1 during recv() ?
Pavel

2004-06-17, 5:55 pm

Hello,

I have an application which recv() data
from a network.
There is second application which sends
SIGUSR1 to the first one a few times per minute.
When the first application got SIGUSR1, it would
automatically call function which do something.
recv() returns -1, and errno is EINTR.

There is loop around recv():
do {
n = recv(...); // blocking recv()
} while ((n == -1) && (errno == EINTR));


The problem is that I loose data !

I send 1 MB file. When the second application
doesn`t send SIGUSR1, the first application
receives all the data. When the second application
sends SIGUSR1, the first application looses data
(more data is lost, when frequency of sending SIGUSR1
is bigger).

There is written in "man" that EINTR means that
signal is received before any data is read.
So, why is data lost ?

Thanks in advance,
Pavel.


Fletcher Glenn

2004-06-17, 5:55 pm



Pavel wrote:
> Hello,
>
> I have an application which recv() data
> from a network.
> There is second application which sends
> SIGUSR1 to the first one a few times per minute.
> When the first application got SIGUSR1, it would
> automatically call function which do something.
> recv() returns -1, and errno is EINTR.
>
> There is loop around recv():
> do {
> n = recv(...); // blocking recv()
> } while ((n == -1) && (errno == EINTR));
>
>
> The problem is that I loose data !
>
> I send 1 MB file. When the second application
> doesn`t send SIGUSR1, the first application
> receives all the data. When the second application
> sends SIGUSR1, the first application looses data
> (more data is lost, when frequency of sending SIGUSR1
> is bigger).
>
> There is written in "man" that EINTR means that
> signal is received before any data is read.
> So, why is data lost ?
>
> Thanks in advance,
> Pavel.
>
>


Is the socket involved SOCK_STREAM or SOCK_DGRAM?

--

Fletcher Glenn

Fabien R

2004-06-17, 5:55 pm

>
> There is loop around recv():
> do {
> n = recv(...); // blocking recv()
> } while ((n == -1) && (errno == EINTR));
>

Didn't you mean:
while ((n == -1) || (errno == EINTR)); ?

How many times is recv called ?

You look like exploring how sockets work...

--
Fabien
Pavel

2004-06-17, 5:55 pm

> Is the socket involved SOCK_STREAM or SOCK_DGRAM?
>

SOCK_STREAM.

Pavel.


Paulo PEREIRA

2004-06-17, 5:55 pm

On 2004-06-17, Pavel <pavel@polbox.com> wrote:
> SOCK_STREAM.
>
> Pavel.
>
>


Is n checked at the end of the while ?
I was wondering if you are not catching a SIGPIPE after being interrupted by
SIGUSR1.
what box are you playing with plz ? Are you using a small connection, LAN, WAN
etc. ?

--
"Computers are useless. They can only give you answers"
- Pablo Picasso

paulo-pereira[dot]perso[at]wanadoo[dot]fr
Villy Kruse

2004-06-17, 5:55 pm

On 17 Jun 2004 00:26:46 -0700,
Fabien R <the_edge123.nospam@club-internet.fr> wrote:


> Didn't you mean:
> while ((n == -1) || (errno == EINTR)); ?
>


Both of the conditions needs to be fulfilled before repeating the recv call.
If n is not -1 then the value of errno should be ignored.


Villy



Nils O. Selåsdal

2004-06-17, 5:55 pm

Villy Kruse wrote:
> On 17 Jun 2004 00:26:46 -0700,
> Fabien R <the_edge123.nospam@club-internet.fr> wrote:
>
>
>
>
>
> Both of the conditions needs to be fulfilled before repeating the recv call.
> If n is not -1 then the value of errno should be ignored.

That will be error prone. If recv succeeds it shouldn't set errno
and you might test against an errno set earlier/elsewhere.
I'm assuming he has an outer loop somewhere reading everything,
but that was not the loop shown here.

joe durusau

2004-06-17, 5:55 pm



"Nils O. Selåsdal" wrote:

> Villy Kruse wrote:
> That will be error prone. If recv succeeds it shouldn't set errno
> and you might test against an errno set earlier/elsewhere.
> I'm assuming he has an outer loop somewhere reading everything,
> but that was not the loop shown here.


You can get into trouble if you look at errno in situations like this.
It is true you might be looking for an error from some earlier situation,
but you would need something to tell you that an error actually existed.
Many times errno can be non-zero after a function call when in fact
no error has been encountered. I don't say anything to indicate that
some flag is being passed in to indicate that errno needs to be checked.

Speaking only for myself,

Joe Durusau


joe@invalid.address

2004-06-17, 5:55 pm

"Nils O. Selåsdal" <NOS@Utel.no> writes:

> Villy Kruse wrote:
[vbcol=seagreen]
> That will be error prone. If recv succeeds it shouldn't set errno
> and you might test against an errno set earlier/elsewhere.


If recv succeeds it won't return -1, so using && will ensure that
errno doesn't get looked at in that case.

Joe
--
Folks who don't know why America is the Land of Promise should be here
during an election campaign.
-- Milton Berle
David Schwartz

2004-06-17, 5:55 pm

Pavel wrote:

> There is loop around recv():
> do {
> n = recv(...); // blocking recv()
> } while ((n == -1) && (errno == EINTR));
>
>
> The problem is that I loose data !


> I send 1 MB file. When the second application
> doesn`t send SIGUSR1, the first application
> receives all the data. When the second application
> sends SIGUSR1, the first application looses data
> (more data is lost, when frequency of sending SIGUSR1
> is bigger).


How did you establish that data was lost? Be as precise as possible in
your description. Do you, for example, add the number of bytes received in
each successful call to 'recv' to some variable and output the variable when
the connection closes? Or what?

DS


David Schwartz

2004-06-17, 5:55 pm

Fabien R wrote:

[vbcol=seagreen]
> Didn't you mean:
> while ((n == -1) || (errno == EINTR)); ?


That would loop forever if the first call to 'recv' results in an EINTR.

DS


Michael Kerrisk

2004-06-20, 10:32 pm

On Thu, 17 Jun 2004 15:41:55 +0200, "Nils O. Selåsdal" <NOS@Utel.no>
wrote:

>Villy Kruse wrote:
>That will be error prone. If recv succeeds it shouldn't set errno


This is wrong. POSIX/SUSv3 says that when a function is successful,
the treatment of errno is unspecified -- in other words it is
permitted for a successful function call to set errno. And there are
functions / system calls (though only a few) on various
implementations that do just this.

>and you might test against an errno set earlier/elsewhere.


No. BOTH conditions must be checked.

Cheers,

Michael
Sponsored Links






Free braindumps | Software forum | Database administration forum

Copyright 2003 - 2008 webservertalk.com