Hi,

while testing how my application (which uses dnspython) behaves under a
simulated network outage, I think I found a dnspython bug. For my
testing I use the following pseudo-code:

    1. block remote port 53 using "iptables"
    2. register a function to SIGALRM that removes the block
    3. alarm(...)  # raise SIGALRM after x seconds
    4. dns.resolver.query(...)

The code should stall initially, but when the SIGALRM handler removes
the network block, it should continue and return However when I
implemented this I got the following exception (the traceback format is
slightly non-standard and is generated by py.test -- only the last part
is included here):

    def _wait_for(ir, iw, ix, expiration):
        if expiration is None:
            timeout = None
        else:
            timeout = expiration - time.time()
            if timeout <= 0.0:
                raise dns.exception.Timeout
        if timeout is None:
            (r, w, x) = select.select(ir, iw, ix)
        else:
E           (r, w, x) = select.select(ir, iw, ix, timeout)
>           error: (4, 'Interrupted system call')

[/usr/lib/python2.5/site-packages/dns/query.py:58]

Error #4 is EINTR and indicates that the select() system call has been
interrupted by a signal. This is the SIGALRM that was generated by
alarm(). In my view this is a bug. Dnspython should not interpret EINTR
as terminal. Instead it should restart the select() with an updated
timeout value that reflects how much time is still left.

For now I will use a thread to remove the block, but I think this may be
an area that needs to be looked into. Blocking system calls can always
return with errno = EINTR, so wherever a blocking system call is used in
dnspython, that should be taken into account.

Regards,
Geert Jansen
_______________________________________________
dnspython-bugs mailing list
[email protected]
http://woof.play-bow.org/mailman/listinfo/dnspython-bugs

Reply via email to