Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

asyncore does not react properly on close() #55087

Closed
tgeorgiev mannequin opened this issue Jan 10, 2011 · 10 comments
Closed

asyncore does not react properly on close() #55087

tgeorgiev mannequin opened this issue Jan 10, 2011 · 10 comments
Labels
stdlib Python modules in the Lib dir type-bug An unexpected behavior, bug, or error

Comments

@tgeorgiev
Copy link
Mannequin

tgeorgiev mannequin commented Jan 10, 2011

BPO 10878
Nosy @terryjreedy, @giampaolo

Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

Show more details

GitHub fields:

assignee = None
closed_at = <Date 2013-07-31.18:54:34.969>
created_at = <Date 2011-01-10.06:40:22.724>
labels = ['invalid', 'type-bug', 'library']
title = 'asyncore does not react properly on close()'
updated_at = <Date 2013-07-31.18:54:34.957>
user = 'https://bugs.python.org/tgeorgiev'

bugs.python.org fields:

activity = <Date 2013-07-31.18:54:34.957>
actor = 'terry.reedy'
assignee = 'none'
closed = True
closed_date = <Date 2013-07-31.18:54:34.969>
closer = 'terry.reedy'
components = ['Library (Lib)']
creation = <Date 2011-01-10.06:40:22.724>
creator = 'tgeorgiev'
dependencies = []
files = []
hgrepos = []
issue_num = 10878
keywords = []
message_count = 10.0
messages = ['125882', '125883', '125894', '125895', '125897', '127149', '127150', '183760', '183761', '194007']
nosy_count = 4.0
nosy_names = ['terry.reedy', 'giampaolo.rodola', 'tgeorgiev', 'Gavin M. Roy']
pr_nums = []
priority = 'normal'
resolution = 'not a bug'
stage = 'resolved'
status = 'closed'
superseder = None
type = 'behavior'
url = 'https://bugs.python.org/issue10878'
versions = ['Python 2.7']

@tgeorgiev
Copy link
Mannequin Author

tgeorgiev mannequin commented Jan 10, 2011

I am trying to add a simple timer to each created socket and destroy it
once the timer expires:

class client(asyncore.dispatcher):
    def __init__(self,host):
    ...
    self.timeout = time.time() + 5

    def readable(self):
        if time.time() >= self.timeout:
            self.close()
        return True

When running that code, it raises an exception:

asyncore.loop(timeout=0.8)
  File "/usr/lib/python2.6/asyncore.py", line 211, in loop
    poll_fun(timeout)
  File "/usr/lib/python2.6/asyncore.py", line 144, in poll
    raise
  File "/usr/lib/python2.6/asyncore.py", line 141, in poll
    r, w, e = select.select(r, w, e, timeout)
select.error: (9, 'Bad file descriptor')

Although del_channel is executed properly and the socket is removed from the map, the poll function is not updated with that info and continues to keep the socket into the r,w,e.

@tgeorgiev tgeorgiev mannequin added the stdlib Python modules in the Lib dir label Jan 10, 2011
@giampaolo
Copy link
Contributor

Problem is you have to return False right after close().
There's an open issue to add a scheduler to asyncore:
http://bugs.python.org/issue1641
Closing this out as invalid.

@tgeorgiev
Copy link
Mannequin Author

tgeorgiev mannequin commented Jan 10, 2011

Sorry, I forgot to mention - I have already tried to return False, but there was no difference.

def readable(self):
        if time.time() >= self.timeout:
            self.close()
            return False
         else:
            return True

@tgeorgiev tgeorgiev mannequin reopened this Jan 10, 2011
@tgeorgiev tgeorgiev mannequin removed the invalid label Jan 10, 2011
@giampaolo
Copy link
Contributor

What if you return False also in writable method?

@tgeorgiev
Copy link
Mannequin Author

tgeorgiev mannequin commented Jan 10, 2011

Precisely, I traced down the problem by putting a simple "breakpoint"
in asyncore.py:

def poll(timeout=0.0, map=None):
    if map is None:
        map = socket_map
    if map:
        r = []; w = []; e = []
        for fd, obj in map.items():
            is_r = obj.readable()
            print "Readable??? -->" , is_r
            is_w = obj.writable()
            if is_r:
                r.append(fd)
            if is_w:
                w.append(fd)
            if is_r or is_w:
                e.append(fd)
        if [] == r == w == e:
            time.sleep(timeout)
            return
    print r,w,e

try:
r, w, e = select.select(r, w, e, timeout)
except select.error, err:
if err.args[0] != EINTR:
raise
else:
return

And here it comes:

[5] [5] [5]
Readable??? --> True
[5] [5] [5]
Readable??? --> True
[5] [5] [5]
Readable??? --> False
[] [5] [5]

Traceback (most recent call last):
  File "./dlms_client.py", line 136, in <module>
    asyncore.loop(timeout=0.8)
  File "/usr/lib/python2.6/asyncore.py", line 213, in loop
    poll_fun(timeout)
  File "/usr/lib/python2.6/asyncore.py", line 146, in poll
    raise
  File "/usr/lib/python2.6/asyncore.py", line 143, in poll
    r, w, e = select.select(r, w, e, timeout)
select.error: (9, 'Bad file descriptor')

So, in order this to work, on first sight all r,w,e must not point to
a socket that has been already closed. Now I am going to think for a workaround at least.

@GavinMRoy
Copy link
Mannequin

GavinMRoy mannequin commented Jan 26, 2011

What I noticed in tracing through the code is that it's getting stuck in a loop because it depends on grabbing asyncore.socket_map if map is null when passed into asyncore.loop. I got around this by appending:

asyncore.loop(0.1, map=[], count=1)

After my close(). I believe this bypasses the grab of socket_map from asyncore.socket_map and allows the while loop in asyncore.loop to exit cleanly.

@GavinMRoy
Copy link
Mannequin

GavinMRoy mannequin commented Jan 26, 2011

For more clarity, I am passing in a list because it will evaluate as False in the while loop on 209 and 213. The fix is to add len(map) to the while loops on those lines.

@terryjreedy
Copy link
Member

Teodor or Gavin: is the (mis)behavior the same in 3.3?

Giampaolo: has the OP identified a fixable misbehavior relative to the documented behavior, making this a valid behavior issue?
Or is this instead an enhancement request, possibly superseded by bpo-1641?

@giampaolo
Copy link
Contributor

I'm not sure what the OP and Gavin are complaining about in their last messages. Could you guys be more clear and/or provide a code sample which reproduces the problem?

@terryjreedy
Copy link
Member

I am re-closing as there is no defined bug to fix, and 2.7 is closed to enhancements.

@terryjreedy terryjreedy added invalid type-bug An unexpected behavior, bug, or error labels Jul 31, 2013
@ezio-melotti ezio-melotti transferred this issue from another repository Apr 10, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
stdlib Python modules in the Lib dir type-bug An unexpected behavior, bug, or error
Projects
None yet
Development

No branches or pull requests

2 participants