[Python-Dev] Problem with signals in a single threaded application

2007-01-23 Thread Ulisses Furquim
Hi,

I'm aware of the problems with signals in a multithreaded application,
but I was using signals in a single-threaded application and noticed
something that seemed wrong. Some signals were apparently being lost,
but when another signal came in the python handler for that "lost"
signal was being called.

The problem seems to be inside the signal module. The global variable
is_tripped is incremented every time a signal arrives. Then, inside
PyErr_CheckSignals() (the pending call that calls all python handlers
for signals that arrived) we can return immediately if is_tripped is
zero. If is_tripped is different than zero, we loop through all
signals calling the registered python handlers and after that we zero
is_tripped. This seems to be ok, but what happens if a signal arrives
after we've returned from its handler (or even after we've checked if
that signal arrived) and before we zero is_tripped? I guess we can
have a situation where is_tripped is zero but some Handlers[i].tripped
are not. In fact, I've inserted some debugging output and could see
that this actually happens and then I've written the following test
program to reproduce the problem.

#!/usr/bin/env python2.5

import sys
import os
import time
import signal

def alarm_handler(*args):
sys.stderr.write('alarmmm!\n')

def sigio_handler(*args):
sys.stderr.write('Entering SIGIO handler\n')
os.kill(os.getpid(), signal.SIGALRM)
sys.stderr.write('Leaving SIGIO handler\n')

signal.signal(signal.SIGIO, sigio_handler)
signal.signal(signal.SIGALRM, alarm_handler)

os.kill(os.getpid(), signal.SIGIO)

ini = time.time()
while True :
if time.time() - ini > 3.0:
sys.stderr.write('Loop!\n')
ini = time.time()

When we run this program, the handler for the SIGALRM isn't called
after we return from the  SIGIO handler. We return to our main loop
and print 'Loop!' every 3 seconds aprox. and the SIGALRM handler is
called only when another signal arrives (like when we hit Ctrl-C).

I've read some threads about signals in the archives and I was under
the impression signals should work reliably on single-threaded
applications. Am I right?  I've thought about a way to fix this, but I
don't know what is the current plan for signals support in python, so
what can be done?

Best regards,

-- Ulisses
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Problem with signals in a single threaded application

2007-01-24 Thread Ulisses Furquim
On 1/24/07, "Martin v. Löwis" <[EMAIL PROTECTED]> wrote:
> I agree it's a bug, and I agree with your proposed analysis. Please
> try to come up with a patch (e.g. by putting a while(is_tripped) loop
> around the for loop). Also make sure you include test case.

Ok. I was discussing this problem with a colleague of mine and he had
a nice idea on how to fix this. We couldn't think of anything wrong
with the solution, so I'm testing it right now and gonna write a test
case afterwards.

> Thanks for contributing,

No problem. :-)

Regards,

-- Ulisses
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Problem with signals in a single threaded application

2007-01-24 Thread Ulisses Furquim
On 1/24/07, Nick Maclaren <[EMAIL PROTECTED]> wrote:
> Obviously, Unix and Microsoft systems depend on signals, so you
> can't simply regard them as hopelessly broken, but you can't assume
> that they are RELIABLE.  All code should be designed to cope with
> the case of signals getting lost, if at all possible.  Defending
> yourself against the other failures is an almost hopeless task,
> but luckily they are extremely rare except on specialist systems.

I couldn't agree more. I might have misused the word "reliably". At
first glance I thought the signal was being lost but then I've
discovered what was really happening.

Regards,

-- Ulisses
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Problem with signals in a single threaded application

2007-01-24 Thread Ulisses Furquim
On 1/24/07, Ulisses Furquim <[EMAIL PROTECTED]> wrote:
> On 1/24/07, "Martin v. Löwis" <[EMAIL PROTECTED]> wrote:
> > I agree it's a bug, and I agree with your proposed analysis. Please
> > try to come up with a patch (e.g. by putting a while(is_tripped) loop
> > around the for loop). Also make sure you include test case.
>
> Ok. I was discussing this problem with a colleague of mine and he had
> a nice idea on how to fix this. We couldn't think of anything wrong
> with the solution, so I'm testing it right now and gonna write a test
> case afterwards.

Here is the link for the bug with both the test program and first
attempt to solve it.

http://www.python.org/sf/1643738

Regards,

-- Ulisses
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Problem with signals in a single threaded application

2007-01-27 Thread Ulisses Furquim
On 1/27/07, Greg Ewing <[EMAIL PROTECTED]> wrote:
> > Why not?
>
> Correct me if I'm wrong, but what I got from the OP
> was that the current method does
>
>if (is_tripped) {
>  for each signal {
>if the signal has occurred, call its handler
>  }
>  is_tripped = 0;
>}
>
> and the problem is that any setting of is_tripped that
> occurs in the midst of calling the handlers gets
> wiped out at the end.
>
> Changing this to
>
>while (is_tripped) {
>  for each signal {
>if the signal has occurred, call its handler
>  }
>  is_tripped = 0;
>}
>
> doesn't solve that, because is_tripped still gets
> set to 0 before it's tested again.

Agreed.

> Thinking about it more, probably it doesn't. What's
> important is to clear it *before* testing whether any
> handlers need to be called, i.e.
>
>if (is_tripped) {
> is_tripped = 0;
> for each signal {
>if the signal has occurred, call its handler
>  }
>}
>

That's exactly what my patch does as you can see here:

http://www.python.org/sf/1643738

Regards,

-- Ulisses
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com