|
85 | 85 | WAIT_WRITE_TIMEOUT_SEC = 10
|
86 | 86 | WAIT_READ_TIMEOUT_SEC = 10
|
87 | 87 | WRITE_RETRY = 3
|
| 88 | +WAIT_READ = 1 |
| 89 | +WAIT_WRITE = 2 |
88 | 90 |
|
89 | 91 | ER_STATUS = 'status'
|
90 | 92 | ER_IDENTIFER = 'identifier'
|
91 | 93 |
|
| 94 | + |
| 95 | +def _wait_for_socket(sock, direction, timeout=None): |
| 96 | + try: |
| 97 | + poll = select.poll() |
| 98 | + poll.register(sock, select.POLLIN if direction == WAIT_READ else select.POLLOUT) |
| 99 | + if timeout: |
| 100 | + timeout *= 1000 |
| 101 | + events = poll.poll(timeout) |
| 102 | + return bool(events) |
| 103 | + except AttributeError: # fallback for systems not supporting poll() |
| 104 | + rlist = [sock] if direction == WAIT_READ else [] |
| 105 | + wlist = [sock] if direction == WAIT_WRITE else [] |
| 106 | + rlist, wlist, _ = select.select(rlist, wlist, [], timeout) |
| 107 | + return bool(rlist or wlist) |
| 108 | + |
| 109 | + |
92 | 110 | class APNs(object):
|
93 | 111 | """A class representing an Apple Push Notification service connection"""
|
94 | 112 |
|
@@ -211,9 +229,9 @@ def _connect(self):
|
211 | 229 | break
|
212 | 230 | except ssl.SSLError as err:
|
213 | 231 | if ssl.SSL_ERROR_WANT_READ == err.args[0]:
|
214 |
| - select.select([self._ssl], [], []) |
| 232 | + _wait_for_socket(self._ssl, WAIT_READ) |
215 | 233 | elif ssl.SSL_ERROR_WANT_WRITE == err.args[0]:
|
216 |
| - select.select([], [self._ssl], []) |
| 234 | + _wait_for_socket(self._ssl, WAIT_WRITE) |
217 | 235 | else:
|
218 | 236 | raise
|
219 | 237 |
|
@@ -254,9 +272,9 @@ def read(self, n=None):
|
254 | 272 | def write(self, string):
|
255 | 273 | if self.enhanced: # nonblocking socket
|
256 | 274 | self._last_activity_time = time.time()
|
257 |
| - _, wlist, _ = select.select([], [self._connection()], [], WAIT_WRITE_TIMEOUT_SEC) |
| 275 | + writeable = _wait_for_socket(self._connection(), WAIT_WRITE, WAIT_WRITE_TIMEOUT_SEC) |
258 | 276 |
|
259 |
| - if len(wlist) > 0: |
| 277 | + if writeable: |
260 | 278 | length = self._connection().sendall(string)
|
261 | 279 | if length == 0:
|
262 | 280 | _logger.debug("sent length: %d" % length) #DEBUG
|
@@ -603,9 +621,9 @@ def run(self):
|
603 | 621 | continue
|
604 | 622 |
|
605 | 623 | try:
|
606 |
| - rlist, _, _ = select.select([self._apns_connection._connection()], [], [], WAIT_READ_TIMEOUT_SEC) |
| 624 | + readable = _wait_for_socket(self._apns_connection._connection(), WAIT_READ, WAIT_READ_TIMEOUT_SEC) |
607 | 625 |
|
608 |
| - if len(rlist) > 0: # there's some data from APNs |
| 626 | + if readable: # there's some data from APNs |
609 | 627 | with self._apns_connection._send_lock:
|
610 | 628 | buff = self._apns_connection.read(ERROR_RESPONSE_LENGTH)
|
611 | 629 | if len(buff) == ERROR_RESPONSE_LENGTH:
|
|
0 commit comments