Solved

interrupted system call EINTR handling?

Posted on 2003-10-31
7
1,383 Views
Last Modified: 2012-05-04
I m getting EINTR when attempting pthread_create. A solution that i found was that if pthread_create fails and errno is EINTR then pthread_create can be retried. This works for me. But now the problem is that there are many system calls which behave similarly and i cannot go ahead and putin a wrapper for each one those. Is there any centralized way of handling this thing? I heard setting SA_RESTART flag for some signal. But how should the exact implementation for the same should go? Is there any example signal handling code someone can give? Or is there any other proper way of handling this issue?

Thanks,
rahul
0
Comment
Question by:rahul_milo
  • 2
7 Comments
 
LVL 10

Accepted Solution

by:
Sys_Prog earned 250 total points
ID: 9656994
Approach1

The GNU library provides a convenient way to retry a call after a temporary failure, with the macro TEMP_FAILURE_RETRY:

Macro: TEMP_FAILURE_RETRY (expression)

This macro evaluates expression once.  If it fails and reports error code EINTR, TEMP_FAILURE_RETRY evaluates it again, and over and over until the result is not a temporary failure.

The value returned by TEMP_FAILURE_RETRY is whatever value expression produced.



Approach2

 If you use sigaction to establish a signal handler, you can specify how that handler should behave.  If you specify the SA_RESTART flag, return from that handler will resume a primitive; otherwise, return from that handler will cause EINTR.


Another way to specify the choice is with the siginterrupt function


When you don't specify with sigaction or siginterrupt what a particular handler should do, it uses a default choice.  The default choice in the GNU library depends on the feature test macros you have defined.  If you define _BSD_SOURCE or _GNU_SOURCE before calling signal, the default is to resume primitives; otherwise, the default is to make them fail with EINTR.  


There is one situation where resumption never happens no matter which choice you make: when a data-transfer function such as read or write is interrupted by a signal after transferring part of the data.  In this case, the function returns the number of bytes already transferred, indicating partial success.


0
 
LVL 10

Expert Comment

by:Sys_Prog
ID: 9657031
The sigaction function has the same basic effect as signal: to specify how a signal should be handled by the process.  However, sigaction offers more control, at the expense of more complexity.  In particular, sigaction allows you to specify additional flags to control when the signal is generated and how the handler is invoked.

The sigaction function is declared in signal.h.  

Data Type: struct sigaction
==================
Structures of type struct sigaction are used in the sigaction function to specify all the information about how to handle a particular signal.  This structure contains at least the following members:

sighandler_t sa_handler

This is used in the same way as the action argument to the signal function.  The value can be SIG_DFL, SIG_IGN, or a function pointer.  


sigset_t sa_mask

This specifies a set of signals to be blocked while the handler runs.  Note that the signal that was delivered is automatically blocked by default before its handler is started; this is true regardless of the value in sa_mask.  If you want that signal not to be blocked within its handler, you must write code in the handler to unblock it.


int sa_flags

This specifies various flags which can affect the behavior of the signal.  


Function: int sigaction (int signum, const struct sigaction *restrict action, struct sigaction *restrict old-action)

The action argument is used to set up a new action for the signal signum, while the old-action argument is used to return information about the action previously associated with this symbol.  (In other words, old-action has the same purpose as the signal function's return value--you can check to see what the old action in effect for the signal was, and restore it later if you want.)




=============
Flags for sigaction
=============


The sa_flags member of the sigaction structure is a catch-all for special features.  Most of the time, SA_RESTART is a good value to use for this field.

The value of sa_flags is interpreted as a bit mask.  Thus, you should choose the flags you want to set, OR those flags together, and store the result in the sa_flags member of your sigaction structure.

Each signal number has its own set of flags.  Each call to sigaction affects one particular signal number, and the flags that you specify apply only to that particular signal.

In the GNU C library, establishing a handler with signal sets all the flags to zero except for SA_RESTART, whose value depends on the settings you have made with siginterrupt.  

These macros are defined in the header file signal.h.

Macro: int SA_NOCLDSTOP

This flag is meaningful only for the SIGCHLD signal.  When the flag is set, the system delivers the signal for a terminated child process but not for one that is stopped.  By default, SIGCHLD is delivered for both terminated children and stopped children.

Setting this flag for a signal other than SIGCHLD has no effect.

Macro: int SA_ONSTACK

If this flag is set for a particular signal number, the system uses the signal stack when delivering that kind of signal.  If a signal with this flag arrives and you have not set a signal stack, the system terminates the program with SIGILL.

Macro: int SA_RESTART

This flag controls what happens when a signal is delivered during certain primitives (such as open, read or write), and the signal handler returns normally.  There are two alternatives: the library function can resume, or it can return failure with error code EINTR.

The choice is controlled by the SA_RESTART flag for the particular kind of signal that was delivered.  If the flag is set, returning from a handler resumes the library function.  If the flag is clear, returning from a handler makes the function fail.  

0
 
LVL 5

Assisted Solution

by:mtmike
mtmike earned 250 total points
ID: 9658910
> I m getting EINTR when attempting pthread_create.

http://www.opengroup.org/onlinepubs/009696799/functions/pthread_create.html

"The pthread_create() function shall not return an error code of [EINTR]"

Which non-conforming pthread implementation are you using?
0
 
LVL 2

Expert Comment

by:cero
ID: 9661030
can you give more details about "many system calls which behave similarly "
0

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

Suggested Solutions

An Outlet in Cocoa is a persistent reference to a GUI control; it connects a property (a variable) to a control.  For example, it is common to create an Outlet for the text field GUI control and change the text that appears in this field via that Ou…
This tutorial is posted by Aaron Wojnowski, administrator at SDKExpert.net.  To view more iPhone tutorials, visit www.sdkexpert.net. This is a very simple tutorial on finding the user's current location easily. In this tutorial, you will learn ho…
The goal of this video is to provide viewers with basic examples to understand opening and writing to files in the C programming language.
Video by: Grant
The goal of this video is to provide viewers with basic examples to understand and use for-loops in the C programming language.

708 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

12 Experts available now in Live!

Get 1:1 Help Now