Skip to content

Commit 1fefda2

Browse files
aherlihybehackett
authored andcommitted
PYTHON-307 Replace select with poll on platforms that support it.
1 parent a889405 commit 1fefda2

File tree

2 files changed

+25
-1
lines changed

2 files changed

+25
-1
lines changed

pymongo/network.py

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,17 @@
1717
import select
1818
import struct
1919

20+
_HAS_POLL = True
21+
_poller = None
22+
_EVENT_MASK = 0
23+
try:
24+
from select import poll
25+
_poller = poll()
26+
_EVENT_MASK = (select.POLLIN | select.POLLPRI | select.POLLERR |
27+
select.POLLHUP | select.POLLNVAL)
28+
except ImportError:
29+
_HAS_POLL = False
30+
2031
from pymongo import helpers, message
2132
from pymongo.errors import AutoReconnect
2233

@@ -93,7 +104,12 @@ def socket_closed(sock):
93104
"""Return True if we know socket has been closed, False otherwise.
94105
"""
95106
try:
96-
rd, _, _ = select.select([sock], [], [], 0)
107+
if _HAS_POLL:
108+
_poller.register(sock, _EVENT_MASK)
109+
rd = _poller.poll(0)
110+
_poller.unregister(sock)
111+
else:
112+
rd, _, _ = select.select([sock], [], [], 0)
97113
# Any exception here is equally bad (select.error, ValueError, etc.).
98114
except:
99115
return True

test/test_pooling.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,14 @@ def test_pool_removes_dead_socket(self):
241241
with cx_pool.get_socket({}):
242242
pass
243243

244+
def test_socket_closed(self):
245+
import socket
246+
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
247+
s.connect(('localhost', 27017))
248+
self.assertFalse(socket_closed(s))
249+
s.close()
250+
self.assertTrue(socket_closed(s))
251+
244252
def test_return_socket_after_reset(self):
245253
pool = self.create_pool()
246254
with pool.get_socket({}) as sock:

0 commit comments

Comments
 (0)