• C

interrupted system call EINTR handling?

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
rahul_miloAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Sys_ProgCommented:
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

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Sys_ProgCommented:
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
mtmikeCommented:
> 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
ceroCommented:
can you give more details about "many system calls which behave similarly "
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.