PYTHON-307 Replace select with poll on platforms that support it.

This commit is contained in:
aherlihy 2015-06-30 12:40:29 -04:00 committed by Bernie Hackett
parent a88940506b
commit 1fefda2e00
2 changed files with 25 additions and 1 deletions

View File

@ -17,6 +17,17 @@
import select
import struct
_HAS_POLL = True
_poller = None
_EVENT_MASK = 0
try:
from select import poll
_poller = poll()
_EVENT_MASK = (select.POLLIN | select.POLLPRI | select.POLLERR |
select.POLLHUP | select.POLLNVAL)
except ImportError:
_HAS_POLL = False
from pymongo import helpers, message
from pymongo.errors import AutoReconnect
@ -93,7 +104,12 @@ def socket_closed(sock):
"""Return True if we know socket has been closed, False otherwise.
"""
try:
rd, _, _ = select.select([sock], [], [], 0)
if _HAS_POLL:
_poller.register(sock, _EVENT_MASK)
rd = _poller.poll(0)
_poller.unregister(sock)
else:
rd, _, _ = select.select([sock], [], [], 0)
# Any exception here is equally bad (select.error, ValueError, etc.).
except:
return True

View File

@ -241,6 +241,14 @@ class TestPooling(_TestPoolingBase):
with cx_pool.get_socket({}):
pass
def test_socket_closed(self):
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('localhost', 27017))
self.assertFalse(socket_closed(s))
s.close()
self.assertTrue(socket_closed(s))
def test_return_socket_after_reset(self):
pool = self.create_pool()
with pool.get_socket({}) as sock: