Revision: 6208
http://jython.svn.sourceforge.net/jython/?rev=6208&view=rev
Author: amak
Date: 2009-04-10 15:36:58 +0000 (Fri, 10 Apr 2009)
Log Message:
-----------
Creating a poll object cache for MS Windows, because of a problem on that platform with creating too many Selectors.
http://bugs.jython.org/issue1291
Modified Paths:
--------------
trunk/jython/Lib/select.py
Modified: trunk/jython/Lib/select.py
===================================================================
--- trunk/jython/Lib/select.py 2009-04-10 13:45:27 UTC (rev 6207)
+++ trunk/jython/Lib/select.py 2009-04-10 15:36:58 UTC (rev 6208)
@@ -7,10 +7,11 @@
import java.nio.channels.Selector
from java.nio.channels.SelectionKey import OP_ACCEPT, OP_CONNECT, OP_WRITE, OP_READ
+import errno
+import os
+import Queue
import socket
-import errno
-
class error(Exception): pass
ALL = None
@@ -144,10 +145,18 @@
except java.lang.Exception, jlx:
raise _map_exception(jlx)
- def close(self):
+ def _deregister_all(self):
try:
for k in self.selector.keys():
k.cancel()
+ # Keys are not actually removed from the selector until the next select operation.
+ self.selector.selectNow()
+ except java.lang.Exception, jlx:
+ raise _map_exception(jlx)
+
+ def close(self):
+ try:
+ self._deregister_all()
self.selector.close()
except java.lang.Exception, jlx:
raise _map_exception(jlx)
@@ -165,10 +174,48 @@
return 0
return int(floatvalue * 1000) # Convert to milliseconds
+# This cache for poll objects is required because of a bug in java on MS Windows
+# http://bugs.jython.org/issue1291
+
+class poll_object_cache:
+
+ def __init__(self):
+ self.is_windows = os.get_os_type() == 'nt'
+ if self.is_windows:
+ self.poll_object_queue = Queue.Queue()
+ import atexit
+ atexit.register(self.finalize)
+
+ def get_poll_object(self):
+ if not self.is_windows:
+ return poll()
+ try:
+ return self.poll_object_queue.get(False)
+ except Queue.Empty:
+ return poll()
+
+ def release_poll_object(self, pobj):
+ if self.is_windows:
+ pobj._deregister_all()
+ self.poll_object_queue.put(pobj)
+ else:
+ pobj.close()
+
+ def finalize(self):
+ if self.is_windows:
+ while True:
+ try:
+ p = self.poll_object_queue.get(False)
+ p.close()
+ except Queue.Empty:
+ return
+
+_poll_object_cache = poll_object_cache()
+
def native_select(read_fd_list, write_fd_list, outofband_fd_list, timeout=None):
timeout = _calcselecttimeoutvalue(timeout)
# First create a poll object to do the actual watching.
- pobj = poll()
+ pobj = _poll_object_cache.get_poll_object()
try:
registered_for_read = {}
# Check the read list
@@ -192,10 +239,7 @@
write_ready_list.append(fd)
return read_ready_list, write_ready_list, oob_ready_list
finally:
- # Need to close the poll object no matter what happened
- # If it is left open, it may still have references to sockets
- # That were registered before any exceptions occurred
- pobj.close()
+ _poll_object_cache.release_poll_object(pobj)
select = native_select
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|