|
From: <zy...@us...> - 2010-07-14 05:12:26
|
Revision: 7078
http://jython.svn.sourceforge.net/jython/?rev=7078&view=rev
Author: zyasoft
Date: 2010-07-14 05:12:19 +0000 (Wed, 14 Jul 2010)
Log Message:
-----------
Added specific support of threading.Thread.__tojava__, which enables
the underlying Java thread to be accessed. Also restored concurrency
of the canonical maps by switching to Google Guava to support them
with MapMaker. Fixes #1630.
Modified Paths:
--------------
trunk/jython/Lib/test/test_threading_jy.py
trunk/jython/Lib/threading.py
trunk/jython/NEWS
trunk/jython/src/org/python/modules/_threading/_threading.java
Modified: trunk/jython/Lib/test/test_threading_jy.py
===================================================================
--- trunk/jython/Lib/test/test_threading_jy.py 2010-07-14 04:18:08 UTC (rev 7077)
+++ trunk/jython/Lib/test/test_threading_jy.py 2010-07-14 05:12:19 UTC (rev 7078)
@@ -2,13 +2,17 @@
Made for Jython.
"""
+from __future__ import with_statement
+
import unittest
from test import test_support
import threading
import time
import random
-from threading import Thread
+from threading import Condition, Lock, Thread
+from java.lang import Thread as JThread, InterruptedException
+
class ThreadingTestCase(unittest.TestCase):
def test_str_name(self):
@@ -42,8 +46,46 @@
self.assertEqual(threading.Lock, threading._Lock)
self.assertEqual(threading.RLock, threading._RLock)
+
+class JavaIntegrationTestCase(unittest.TestCase):
+ """Verifies that Thread.__tojava__ correctly gets the underlying Java thread"""
+
+ def test_interruptible(self):
+
+ def wait_until_interrupted(cv):
+ name = threading.currentThread().getName()
+ with cv:
+ while not JThread.currentThread().isInterrupted():
+ try:
+ cv.wait()
+ except InterruptedException, e:
+ break
+
+ num_threads = 5
+ unfair_condition = Condition()
+ threads = [
+ Thread(
+ name="thread #%d" % i,
+ target=wait_until_interrupted,
+ args=(unfair_condition,))
+ for i in xrange(num_threads)]
+
+ for thread in threads:
+ thread.start()
+ time.sleep(0.1)
+
+ for thread in threads:
+ JThread.interrupt(thread)
+
+ joined_threads = 0
+ for thread in threads:
+ thread.join(1.) # timeout just in case so we don't stall regrtest
+ joined_threads += 1
+ self.assertEqual(joined_threads, num_threads)
+
+
def test_main():
- test_support.run_unittest(ThreadingTestCase, TwistedTestCase)
+ test_support.run_unittest(JavaIntegrationTestCase, ThreadingTestCase, TwistedTestCase)
if __name__ == "__main__":
Modified: trunk/jython/Lib/threading.py
===================================================================
--- trunk/jython/Lib/threading.py 2010-07-14 04:18:08 UTC (rev 7077)
+++ trunk/jython/Lib/threading.py 2010-07-14 05:12:19 UTC (rev 7078)
@@ -3,12 +3,11 @@
from java.util.concurrent import Semaphore, CyclicBarrier
from java.util.concurrent.locks import ReentrantLock
from org.python.util import jython
+from org.python.core import Py
from thread import _newFunctionThread
from thread import _local as local
-from _threading import Lock, RLock, Condition, _Lock, _RLock
+from _threading import Lock, RLock, Condition, _Lock, _RLock, _threads, _active, _jthread_to_pythread, _register_thread, _unregister_thread
import java.lang.Thread
-import weakref
-
import sys as _sys
from traceback import print_exc as _print_exc
@@ -93,8 +92,7 @@
class JavaThread(object):
def __init__(self, thread):
self._thread = thread
- _jthread_to_pythread[thread] = self
- _threads[thread.getId()] = self
+ _register_thread(thread, self)
def __repr__(self):
_thread = self._thread
@@ -141,11 +139,14 @@
def setDaemon(self, daemonic):
self._thread.setDaemon(bool(daemonic))
-# relies on the fact that this is a CHM
-_threads = weakref.WeakValueDictionary()
-_active = _threads
-_jthread_to_pythread = Collections.synchronizedMap(WeakHashMap())
+ def __tojava__(self, c):
+ if isinstance(self._thread, c):
+ return self._thread
+ if isinstance(self, c):
+ return self
+ return Py.NoConversion
+
class Thread(JavaThread):
def __init__(self, group=None, target=None, name=None, args=None, kwargs=None):
assert group is None, "group argument must be None for now"
@@ -225,7 +226,7 @@
pass
def __delete(self):
- del _threads[self._thread.getId()]
+ _unregister_thread(self._thread)
class _MainThread(Thread):
@@ -241,7 +242,7 @@
return False
def __exitfunc(self):
- del _threads[self._thread.getId()]
+ _unregister_thread(self._thread)
t = _pickSomeNonDaemonThread()
while t:
t.join()
Modified: trunk/jython/NEWS
===================================================================
--- trunk/jython/NEWS 2010-07-14 04:18:08 UTC (rev 7077)
+++ trunk/jython/NEWS 2010-07-14 05:12:19 UTC (rev 7078)
@@ -1,8 +1,8 @@
Jython NEWS
-Jython 2.5.2a1
+Jython 2.5.2b2
Bugs Fixed
- - [ ]
+ - [ 1630 ] threading.Thread lacks __tojava__ method
Jython 2.5.2b1
Bugs Fixed
Modified: trunk/jython/src/org/python/modules/_threading/_threading.java
===================================================================
--- trunk/jython/src/org/python/modules/_threading/_threading.java 2010-07-14 04:18:08 UTC (rev 7077)
+++ trunk/jython/src/org/python/modules/_threading/_threading.java 2010-07-14 05:12:19 UTC (rev 7078)
@@ -3,6 +3,8 @@
import org.python.core.ClassDictInit;
import org.python.core.Py;
import org.python.core.PyObject;
+import com.google.common.collect.MapMaker;
+import java.util.Map;
public class _threading implements ClassDictInit {
@@ -13,5 +15,21 @@
dict.__setitem__("_Lock", Lock.TYPE);
dict.__setitem__("_RLock", Lock.TYPE);
dict.__setitem__("Condition", Condition.TYPE);
+// dict.__setitem__("JavaThread", JavaThread.TYPE);
}
+
+ // internals to support threading.py, test_threading.py
+ public static Map<Long, PyObject> _threads = new MapMaker().weakValues().makeMap();
+ public static Map<Thread, PyObject> _jthread_to_pythread = new MapMaker().weakKeys().makeMap();
+ public static Map<Long, PyObject> _active = _threads;
+
+ public static void _register_thread(Thread jthread, PyObject pythread) {
+ _threads.put(jthread.getId(), pythread);
+ _jthread_to_pythread.put(jthread, pythread);
+ }
+
+ public static void _unregister_thread(Thread jthread) {
+ _threads.remove(jthread.getId());
+ }
+
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|