 |
|
 |
|
|
 |
Function: int recv (Socket, Buffer,Length, Flags) is returning with the error number 4 |
 |
 |
|
|
07-18-07 12:23 PM
Hi All,
I am facing a problem when a call made to the socket function recv. It
is returning with the error number 4(EINTR).
When I further analyzed i came to know it is because of the "A signal
interrupted the recv subroutine before any data was available ".
It's not like that every time i am facing this proble. I will
take you through a scenario which will give you a brief idea to
understand the problem:
It's like two servers are running and communicating on a TCP
connection. When a sever send a request to another; a connection will
be opened for that request untill the request is processed.
Server one is firing so many requests in parallel. All is going
fine till here when the parallel requests were around 1200 . Now the
number of parallel requests have got crossed to 1500. And i am getting
the above error only for some requests and not for all .
Even i have handled the error for the error EINTR through a signal
handler thread.
For you information, I am working on AIX 5.3 OS and the application is
written in C++.
Please let me know if you require more information to understand the
problem.
What could be reason for interruption of signal while we are reading
from socket?? or Is it because of some configuration parameter of OS??
or anything else......
Please help me.....
[ Post a follow-up to this message ]
|
|
|
 |
|
 |
|
 |
|
|
 |
Re: Function: int recv (Socket, Buffer,Length, Flags) is returning with the error numb |
 |
 |
|
|
07-18-07 12:23 PM
monty wrote:
> I am facing a problem when a call made to the socket function recv. It
> is returning with the error number 4(EINTR).
> When I further analyzed i came to know it is because of the "A signal
> interrupted the recv subroutine before any data was available ".
If I remember correctly, this just means that while the system call was
under way, your program received (and possibly handled) a signal and
therefore the syscall was aborted without anything being done. Just retry
the recv() and you should be fine.
I'd be interested in the rationale to behave like that, i.e. why EINTR is
provided/used at all, in this context or others.
Uli
[ Post a follow-up to this message ]
|
|
|
 |
|
 |
|
 |
|
|
 |
Re: Function: int recv (Socket, Buffer,Length, Flags) is returning with the error numb |
 |
 |
|
|
07-19-07 06:22 AM
In article <5g5vu7F3ef7jtU1@mid.uni-berlin.de>,
Ulrich Eckhardt <doomster@knuut.de> wrote:
> monty wrote:
>
> If I remember correctly, this just means that while the system call was
> under way, your program received (and possibly handled) a signal and
> therefore the syscall was aborted without anything being done. Just retry
> the recv() and you should be fine.
>
> I'd be interested in the rationale to behave like that, i.e. why EINTR is
> provided/used at all, in this context or others.
Because the Unix designers didn't want to preserve the kernel state of
an in-progress system call while going back to user mode to invoke the
signal handler.
--
Barry Margolin, barmar@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
*** PLEASE don't copy me on replies, I'll read them in the group ***
[ Post a follow-up to this message ]
|
|
|
 |
|
 |
|
 |
|
|
 |
Re: Function: int recv (Socket, Buffer,Length, Flags) is returning with the error numb |
 |
 |
|
|
07-19-07 12:20 PM
Barry Margolin <barmar@alum.mit.edu> writes:
> In article <5g5vu7F3ef7jtU1@mid.uni-berlin.de>,
> Ulrich Eckhardt <doomster@knuut.de> wrote:
>
> Because the Unix designers didn't want to preserve the kernel state of
> an in-progress system call while going back to user mode to invoke the
> signal handler.
That's a nice speculation by someone with little clue in kernel
programming. The first thing to note here is that not all system calls
are supposed to be interuptible, but only those who can wait for an
indeterminate amount of time until some external event to happens (eg
read on a file descriptor associated with a regular file is not
interruptible, read on a network socket is). Even those system
calls are only ever interrupted if the application has registered a
handler for the particular signal that 'happened'[*]. If the call
should be interrupted or restarted can be specified by adding
SA_RESTART to the sa_flags member of the struct sigaction used
to establish the handler[**]. If the system call returns with errno
set to EINTR after the handler was run, there was no 'kernel state' to
restore, because the process was blocked waiting for something[***].
The assumption behind this is that if the process handled a signal
while being blocked in the kernel, obviously, 'something of interest'
has happened and the process should be able to react to this something
instead of continuing to block in the kernel.
[*] Unfortunately, libraries handle signals, too. Especially,
the various pthread-implementations distributed with glibc for
Linxu do, meaning, when linking with libpthread on Linux,
EINTRs may start to appear in applications not handling
signals themselves, since the various I/O multiplexing
syscalls (poll, select, etc) are not restartable.
[**] 'signal' is a legacy interface with platform dependent
semantics and eventually, even different semantics on the same
platform, depending on macros being defined during compilation
(Linux/ glibc & _XOPEN_SOURCE).
[***] The exception is 'connect'. If a connect is interrupted
by a signal, it is generally necessary to poll for 'writable'
to wait until the connection has been established.
[ Post a follow-up to this message ]
|
|
|
 |
|
 |
|
 |
|
|
 |
Re: Function: int recv (Socket, Buffer,Length, Flags) is returning with the error numb |
 |
 |
|
|
07-19-07 12:20 PM
On Jul 18, 12:55 pm, Ulrich Eckhardt <dooms...@knuut.de> wrote:
> monty wrote:
>
> If I remember correctly, this just means that while the system call was
> under way, your program received (and possibly handled) a signal and
> therefore the syscall was aborted without anything being done. Just retry
> the recv() and you should be fine.
>
> I'd be interested in the rationale to behave like that, i.e. why EINTR is
> provided/used at all, in this context or others.
>
> Uli
hi,
Even after retrying same error i am getting.
[ Post a follow-up to this message ]
|
|
|
 |
|
 |
|
 |
|
|
 |
Re: Function: int recv (Socket, Buffer,Length, Flags) is returning with the error numb |
 |
 |
|
|
07-19-07 12:20 PM
monty wrote:
[recv() / EINTR ]
> Even after retrying same error i am getting.
Did you read Ralf's advise? Can you show how you're using recv()? Are you
sure about the input values? "Doesn't work!" is not a useful error
description.
BTW: don't multipost like you did in c.p.t. and it wasn't exactly on-topic
there anyway.
Uli
[ Post a follow-up to this message ]
|
|
|
 |
|
 |
|
 |
|
|
 |
Re: Function: int recv (Socket, Buffer,Length, Flags) is returning with the error numb |
 |
 |
|
|
07-25-07 12:21 AM
Rainer Weikusat <rweikusat@mssgmbh.com> writes:
>Barry Margolin <barmar@alum.mit.edu> writes:
>
>That's a nice speculation by someone with little clue in kernel
>programming. The first thing to note here is that not all system calls
May want to lay off the insults when you have really no clue about
Barry's prior computing experience.
He is correct.
> If the system call returns with errno
>set to EINTR after the handler was run, there was no 'kernel state' to
>restore, because the process was blocked waiting for something[***].
This is clearly incorrect, since the modifications to the struct proc
(et alia) in order to 'block waiting for something' are precisely the
state changes that Barry was referring to.
Note that signals are always delivered at the tail-end of the system
call process (just prior to returning to the application), thus to
deliver a signal prior to completion of the system call (e.g. on an
indefinite wait), one must roll-back the kernel state to that at the
time of the system call.
Having to remember this state while invoking a signal handler is
quite complicated by the fact that the signal handler itself can
make system calls, thus the roll-back and EINTR return.
Note that ERESTART came later than EINTR both from an implementation
and a standards perspective.
scott
[ Post a follow-up to this message ]
|
|
|
 |
|
 |
|
 |
|
|
 |
Re: Function: int recv (Socket, Buffer,Length, Flags) is returning with the error numb |
 |
 |
|
|
07-25-07 12:20 PM
scott@slp53.sl.home (Scott Lurndal) writes:
> Rainer Weikusat <rweikusat@mssgmbh.com> writes:
>
> May want to lay off the insults when you have really no clue about
> Barry's prior computing experience.
I was refering to the indirect 'worse is better'-quote. The reason
(some) UNIX(*) system calls are interruptible is because there could
be a reason to interrupt them. One would assume this to be even more
true on early UNIX(*), before 'synchronous I/O multiplexing' was
invented.
A characteristic of earlier Unix systems is that if a process
caught a signal while the process was blocked in a "slow"
system call, the system call was interrupted. The system call
returned an error and errno was set to EINTR. This was done
under the assumption that since a signal occurred and the
process caught it, there is a good chance that something has
happened that should wake up the blocked system call.
[APUE, 1st ed., p. 275]
[...]
>
> This is clearly incorrect, since the modifications to the struct proc
> (et alia) in order to 'block waiting for something' are precisely the
> state changes that Barry was referring to.
To return to user space, the process has to return to user
space.
> Note that signals are always delivered at the tail-end of the system
> call process (just prior to returning to the application),
#include <signal.h>
#include <stdio.h>
static void handler(int unused)
{
puts("something stopped me");
exit(0);
}
int main(void)
{
signal(SIGALRM, handler);
alarm(3);
while (1);
return 0;
}
It follows that this program can never stop, because the SIGALRM
cannot be delivered. It stops, though, at least on Linux 2.6.
> thus to deliver a signal prior to completion of the system call
> (e.g. on an indefinite wait), one must roll-back the kernel state to
> that at the time of the system call.
An example of the opposite (that I happen to have written ;-):
static int wcomplete_wait(struct file *file)
{
wait_queue_t wait;
volatile struct usblp *usblp;
int have_signal, complete, rc;
usblp = file->private_data;
if (!usblp_wcomplete((void *)usblp)) {
if (file->f_flags & O_NONBLOCK) return -EAGAIN;
init_waitqueue_entry(&wait, current);
add_wait_queue((wait_queue_head_t *)&usblp->wait, &wait);
goto check_status;
do {
schedule();
check_status:
set_current_state(TASK_INTERRUPTIBLE);
have_signal = signal_pending(current);
complete = usblp_wcomplete((void *)usblp);
} while (!(complete || have_signal));
set_current_state(TASK_RUNNING);
remove_wait_queue((wait_queue_head_t *)&usblp->wait, &wait);
if (!complete) return -EINTR;
}
rc = usblp->writeurb->status;
return rc;
}
[Linux 2.4 USB printer driver 'with some modifications', caller is
write/ writev]
For a blocking write, this is called after the URB (USB request
buffer) has been submitted to the host controller for transmission.
There isn't even a theoretical possibility of 'rolling this back' (see
OHCI spec).
> Note that ERESTART came later than EINTR both from an implementation
> and a standards perspective.
Quoting UNP again (p. 277): "One of the reasons 4.2BSD introduced the
automatic reastart feature is because sometimes we don't know that the
input or output device is slow".
[ Post a follow-up to this message ]
|
|
|
 |
|
 |
|
 |
|
|
 |
Re: Function: int recv (Socket, Buffer,Length, Flags) is returning with the error numb |
 |
 |
|
|
07-25-07 12:20 PM
scott@slp53.sl.home (Scott Lurndal) writes:
> Rainer Weikusat <rweikusat@mssgmbh.com> writes:
>
> May want to lay off the insults when you have really no clue about
> Barry's prior computing experience.
I was refering to the indirect 'worse is better'-quote. The reason
(some) UNIX(*) system calls are interruptible is because there could
be a reason to interrupt them. One would assume this to be even more
true on early UNIX(*), before 'synchronous I/O multiplexing' was
invented.
A characteristic of earlier Unix systems is that if a process
caught a signal while the process was blocked in a "slow"
system call, the system call was interrupted. The system call
returned an error and errno was set to EINTR. This was done
under the assumption that since a signal occurred and the
process caught it, there is a good chance that something has
happened that should wake up the blocked system call.
[APUE, 1st ed., p. 275]
[...]
>
> This is clearly incorrect, since the modifications to the struct proc
> (et alia) in order to 'block waiting for something' are precisely the
> state changes that Barry was referring to.
To return to user space, the process has to return to user
space.
> Note that signals are always delivered at the tail-end of the system
> call process (just prior to returning to the application),
#include <signal.h>
#include <stdio.h>
static void handler(int unused)
{
puts("something stopped me");
exit(0);
}
int main(void)
{
signal(SIGALRM, handler);
alarm(3);
while (1);
return 0;
}
It follows that this program can never stop, because the SIGALRM
cannot be delivered. It stops, though, at least on Linux 2.6.
> thus to deliver a signal prior to completion of the system call
> (e.g. on an indefinite wait), one must roll-back the kernel state to
> that at the time of the system call.
An example of the opposite (that I happen to have written ;-):
static int wcomplete_wait(struct file *file)
{
wait_queue_t wait;
volatile struct usblp *usblp;
int have_signal, complete, rc;
usblp = file->private_data;
if (!usblp_wcomplete((void *)usblp)) {
if (file->f_flags & O_NONBLOCK) return -EAGAIN;
init_waitqueue_entry(&wait, current);
add_wait_queue((wait_queue_head_t *)&usblp->wait, &wait);
goto check_status;
do {
schedule();
check_status:
set_current_state(TASK_INTERRUPTIBLE);
have_signal = signal_pending(current);
complete = usblp_wcomplete((void *)usblp);
} while (!(complete || have_signal));
set_current_state(TASK_RUNNING);
remove_wait_queue((wait_queue_head_t *)&usblp->wait, &wait);
if (!complete) return -EINTR;
}
rc = usblp->writeurb->status;
return rc;
}
[Linux 2.4 USB printer driver 'with some modifications', caller is
write/ writev]
For a blocking write, this is called after the URB (USB request
buffer) has been submitted to the host controller for transmission.
There isn't even a theoretical possibility of 'rolling this back' (see
OHCI spec).
> Note that ERESTART came later than EINTR both from an implementation
> and a standards perspective.
Quoting APUE again (p. 277): "One of the reasons 4.2BSD introduced the
automatic restart feature is because sometimes we don't know that the
input or output device is slow".
[ Post a follow-up to this message ]
|
|
|
 |
|
 |
|
 |
|
|
 |
Re: Function: int recv (Socket, Buffer,Length, Flags) is returning with the error numb |
 |
 |
|
|
07-25-07 06:21 PM
On Jul 25, 1:50 pm, Rainer Weikusat <rweiku...@mssgmbh.com> wrote:
> sc...@slp53.sl.home (Scott Lurndal) writes:
>
>
>
>
>
>
> I was refering to the indirect 'worse is better'-quote. The reason
> (some) UNIX(*) system calls are interruptible is because there could
> be a reason to interrupt them. One would assume this to be even more
> true on early UNIX(*), before 'synchronous I/O multiplexing' was
> invented.
>
> A characteristic of earlier Unix systems is that if a process
> caught a signal while the process was blocked in a "slow"
> system call, the system call was interrupted. The system call
> returned an error and errno was set to EINTR. This was done
> under the assumption that since a signal occurred and the
> process caught it, there is a good chance that something has
> happened that should wake up the blocked system call.
> [APUE, 1st ed., p. 275]
>
> [...]
>
>
>
> To return to user space, the process has to return to user
> space.
>
>
> #include <signal.h>
> #include <stdio.h>
>
> static void handler(int unused)
> {
> puts("something stopped me");
> exit(0);
>
> }
>
> int main(void)
> {
> signal(SIGALRM, handler);
> alarm(3);
> while (1);
> return 0;
>
> }
>
> It follows that this program can never stop, because the SIGALRM
> cannot be delivered. It stops, though, at least on Linux 2.6.
>
>
> An example of the opposite (that I happen to have written ;-):
>
> static int wcomplete_wait(struct file *file)
> {
> wait_queue_t wait;
> volatile struct usblp *usblp;
> int have_signal, complete, rc;
>
> usblp = file->private_data;
>
> if (!usblp_wcomplete((void *)usblp)) {
> if (file->f_flags & O_NONBLOCK) return -EAGAIN;
>
> init_waitqueue_entry(&wait, current);
> add_wait_queue((wait_queue_head_t *)&usblp->wait, &wait);
>
> goto check_status;
> do {
> schedule();
>
> check_status:
> set_current_state(TASK_INTERRUPTIBLE);
> have_signal = signal_pending(current);
> complete = usblp_wcomplete((void *)usblp);
> } while (!(complete || have_signal));
>
> set_current_state(TASK_RUNNING);
> remove_wait_queue((wait_queue_head_t *)&usblp->wait, &wait
);
>
> if (!complete) return -EINTR;
> }
>
> rc = usblp->writeurb->status;
> return rc;}
>
> [Linux 2.4 USB printer driver 'with some modifications', caller is
> write/ writev]
>
> For a blocking write, this is called after the URB (USB request
> buffer) has been submitted to the host controller for transmission.
> There isn't even a theoretical possibility of 'rolling this back' (see
> OHCI spec).
>
>
> Quoting APUE again (p. 277): "One of the reasons 4.2BSD introduced the
> automatic restart feature is because sometimes we don't know that the
> input or output device is slow".- Hide quoted text -
>
> - Show quoted text -
Hi Guys,
I am a new to the unix and thread programming and the discussion is
going above my understanding; apologies for this.
I have read suggestions from all. But I m unable to implement these
thing on my application.
I have tried recieving the message again $ again but it's going into
the infinte loop i.e. signal has occured at the start of the system
call I guess (like said by scott). He has suggested that "one must
roll-back the kernel state to that at the time of the system call";
Scott Can U please tell me how do i acheive this?
Guys i am in trouble right now and requesting all of you to provide me
a solution to the problem for now. Please tell me which are all the
functions I can use to supress the signal before calling the recv
function.
Thanks....looking forward to get help....
[ Post a follow-up to this message ]
|
|
|
 |
|
 |
|
 |
|
|
|
Sponsored Links |
 |
 |
|
|
 |
All times are GMT. The time now is 09:26 AM. |
 |
|
|
 |
|
 |
|
|
 |
|
Forum Rules:
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
|
HTML code is OFF
vB code is ON
Smilies are ON
[IMG] code is OFF
|
|
|
|
Medical and Health forum | Computer Games Reviews | Graphics design forum
|
 |
|
 |
|