sig_atomic_t: from signal handler: set or access?

sig_atomic_t: from signal handler: set or access?

Post by Valentin Nechaye » Tue, 01 Jul 2003 15:45:05



Hi,

seeing in SUSv3:

1)
==={{{ functions/sigaction.html
     If the signal occurs other than as the result of calling abort(),
     kill(), or raise(), the behavior is undefined if the signal handler
     calls any function in the standard library other than one of the
     functions listed in the table above or refers to any object with
     static storage duration other than by assigning a value to a static
     storage duration variable of type volatile sig_atomic_t.
     Furthermore, if such a call fails, the value of errno is
     unspecified.
===}}}

Here, signal handler is allowed only to *set* variable of sig_atomic_t type.

2)
==={{{ basedefs/signal.h.html
   sig_atomic_t
          Possibly volatile-qualified integer type of an object that can
          be accessed as an atomic entity, even in the presence of
          asynchronous interrupts.
===}}}

Here, *access* is allowed (which means not only write, but read also).
What variant is true?
Or reading is prohibited for signal handler, but allowed for "normal" code?

-netch-

 
 
 

sig_atomic_t: from signal handler: set or access?

Post by Marc Rochkin » Wed, 02 Jul 2003 12:02:48


On Mon, 30 Jun 2003 09:45:05 +0300, Valentin Nechayev


> Hi,

> seeing in SUSv3:

> 1)
> ==={{{ functions/sigaction.html
> If the signal occurs other than as the result of calling abort(),
> kill(), or raise(), the behavior is undefined if the signal handler
> calls any function in the standard library other than one of the
> functions listed in the table above or refers to any object with
> static storage duration other than by assigning a value to a static
> storage duration variable of type volatile sig_atomic_t.
> Furthermore, if such a call fails, the value of errno is
> unspecified.
> ===}}}

> Here, signal handler is allowed only to *set* variable of sig_atomic_t
> type.

> 2)
> ==={{{ basedefs/signal.h.html
> sig_atomic_t
> Possibly volatile-qualified integer type of an object that can
> be accessed as an atomic entity, even in the presence of
> asynchronous interrupts.
> ===}}}

> Here, *access* is allowed (which means not only write, but read also).
> What variant is true?
> Or reading is prohibited for signal handler, but allowed for "normal"
> code?

> -netch-

I think the wording is rough. In addition to the problem you mention, the
restriction to kill applies only to kills from the same process. Kills from
another process are asynchronous.

--Marc

 
 
 

1. signal handlers, sig_atomic_t, and mutual exclusion

Given that Linux gives only one real timer per process, I've written a class
that creates a linked list of timer events stored as offsets from each other.
The way it works is that the first element in the list is the one for which the
timer is actually running, and each element stores a time offset from the
previous one.

The tricky bit comes in when you can manually add/remove/query entries in the
list, but at the same time the timer may fire for the first element in the list,
thus modifying any number of list elements.  What I've done is something like
this:

//these are both initialized to zero in the constructor
volatile sig_atomic_t signal_fired, manipulating_list;

//this is set up to handle SIGALRM
void Timer::signal_handler(const int sig)
{
  if (manipulating_list)
  {
    signal_fired = 1;
    return;
  }
  else
  {
    //call methods on a staticly declared event list class to
    //loop through all expired events to pull them off the event
    //list, reschedule them if appropriate, and run an event handler.
    //needless to say, this will change pointers around
    return;
  }

//this is an example of one of the other methods
int Timer::remove (int &timerNum)
{
  manipulating_list = 1;

  //remove the event from the timer queue
  Event tempEvent = timerList.remove(timerNum);

  manipulating_list = 0;

  if (signal_fired)
    timerSigHandler(SIGALRM);

  if (tempEvent.isValid())
  {
    timerNum = 0;
    return 0;
  }
  else
    return -1;

Now, given this sort of arrangement, am I guaranteed that both routines will
always see consistant data in the linked list?  If not, what do I need to do to
guarantee this?  Is this an implementation-dependent thing?  The language
standard seems to say that I'm not allowed to do anything in the signal handler
but set a sig_atomic_t variable...obviously I could potentially do a lot more
than that here.

Thanks for your responses.

Chris

2. LCD monitor does not use DPMS but DMPM

3. Signal handlers inside signal handlers

4. MCA and ISA

5. Setting a Signal handler to signal the input on a socket

6. Shared libs question

7. Threads performance - allow signal handler to not call handler

8. bandwidth requirement of exceed vs xfree86

9. accessing state from signal handler

10. Signal handler for unaligned access: emulate and continue?

11. How to set signal handler and mask in thread other than main ?