| OLD | NEW |
| 1 // Copyright (c) Corporation for National Research Initiatives | 1 // Copyright (c) Corporation for National Research Initiatives |
| 2 package org.python.modules.thread; | 2 package org.python.modules.thread; |
| 3 | 3 |
| 4 import org.python.core.ClassDictInit; | 4 import org.python.core.ClassDictInit; |
| 5 import org.python.core.FunctionThread; | 5 import org.python.core.FunctionThread; |
| 6 import org.python.core.Py; | 6 import org.python.core.Py; |
| 7 import org.python.core.PyException; | 7 import org.python.core.PyException; |
| 8 import org.python.core.PyInteger; | 8 import org.python.core.PyInteger; |
| 9 import org.python.core.PyObject; | 9 import org.python.core.PyObject; |
| 10 import org.python.core.PyString; | 10 import org.python.core.PyString; |
| 11 import org.python.core.PyTableCode; |
| 11 import org.python.core.PyType; | 12 import org.python.core.PyType; |
| 12 import org.python.core.PyTuple; | 13 import org.python.core.PyTuple; |
| 13 | 14 |
| 14 public class thread implements ClassDictInit { | 15 public class thread implements ClassDictInit { |
| 15 | 16 |
| 16 private static volatile long stack_size = 0; // XXX - can we figure out the
current stack size? | 17 private static volatile long stack_size = 0; // XXX - can we figure out the
current stack size? |
| 18 private static ThreadGroup group = new ThreadGroup("jython-threads"); |
| 17 | 19 |
| 20 |
| 18 public static PyString __doc__ = new PyString( | 21 public static PyString __doc__ = new PyString( |
| 19 "This module provides primitive operations to write multi-threaded "+ | 22 "This module provides primitive operations to write multi-threaded "+ |
| 20 "programs.\n" + | 23 "programs.\n" + |
| 21 "The 'threading' module provides a more convenient interface." | 24 "The 'threading' module provides a more convenient interface." |
| 22 ); | 25 ); |
| 23 | 26 |
| 24 public static void classDictInit(PyObject dict) { | 27 public static void classDictInit(PyObject dict) { |
| 25 dict.__setitem__("LockType", PyType.fromClass(PyLock.class)); | 28 dict.__setitem__("LockType", PyType.fromClass(PyLock.class)); |
| 26 dict.__setitem__("_local", PyLocal.TYPE); | 29 dict.__setitem__("_local", PyLocal.TYPE); |
| 30 dict.__setitem__("interruptAllThreads", null); |
| 27 } | 31 } |
| 28 | 32 |
| 29 public static PyObject error = new PyString("thread.error"); | 33 public static PyObject error = new PyString("thread.error"); |
| 30 | 34 |
| 31 public static void start_new_thread(PyObject func, PyTuple args) { | 35 public static void start_new_thread(PyObject func, PyTuple args) { |
| 32 Thread pt = new FunctionThread(func, args.getArray(), stack_size); | 36 Thread pt = new FunctionThread(func, args.getArray(), stack_size, group)
; |
| 33 PyObject currentThread = func.__findattr__("im_self"); | 37 PyObject currentThread = func.__findattr__("im_self"); |
| 34 if (currentThread != null) { | 38 if (currentThread != null) { |
| 35 PyObject isDaemon = currentThread.__findattr__("isDaemon"); | 39 PyObject isDaemon = currentThread.__findattr__("isDaemon"); |
| 36 if (isDaemon != null && isDaemon.isCallable()) { | 40 if (isDaemon != null && isDaemon.isCallable()) { |
| 37 PyObject po = isDaemon.__call__(); | 41 PyObject po = isDaemon.__call__(); |
| 38 pt.setDaemon(po.__nonzero__()); | 42 pt.setDaemon(po.__nonzero__()); |
| 39 } | 43 } |
| 40 PyObject getName = currentThread.__findattr__("getName"); | 44 PyObject getName = currentThread.__findattr__("getName"); |
| 41 if (getName != null && getName.isCallable()) { | 45 if (getName != null && getName.isCallable()) { |
| 42 PyObject pname = getName.__call__(); | 46 PyObject pname = getName.__call__(); |
| 43 pt.setName(String.valueOf(pname)); | 47 pt.setName(String.valueOf(pname)); |
| 44 } | 48 } |
| 45 } | 49 } |
| 46 pt.start(); | 50 pt.start(); |
| 47 } | 51 } |
| 52 |
| 53 /** |
| 54 * Interrupts all running threads spawned by the thread module. |
| 55 * |
| 56 * This works in conjuntion with:<ul> |
| 57 * <li>{@link PyTableCode#call(org.python.core.PyFrame, PyObject)}: |
| 58 * checks for the interrupted status of the current thread and raise |
| 59 * a SystemRestart exception if a interruption is detected.</li> |
| 60 * <li>{@link FunctionThread#run()}: exits the current thread when a |
| 61 * SystemRestart exception is not caught.</li> |
| 62 * |
| 63 * Thus, it is possible that this doesn't make all running threads to stop, |
| 64 * if SystemRestart exception is caught. |
| 65 */ |
| 66 public static void interruptAllThreads() { |
| 67 group.interrupt(); |
| 68 } |
| 48 | 69 |
| 49 public static PyLock allocate_lock() { | 70 public static PyLock allocate_lock() { |
| 50 return new PyLock(); | 71 return new PyLock(); |
| 51 } | 72 } |
| 52 | 73 |
| 53 public static void exit() { | 74 public static void exit() { |
| 54 exit_thread(); | 75 exit_thread(); |
| 55 } | 76 } |
| 56 | 77 |
| 57 public static void exit_thread() { | 78 public static void exit_thread() { |
| (...skipping 16 matching lines...) Expand all Loading... |
| 74 // as specified by Python, Java quietly ignores what | 95 // as specified by Python, Java quietly ignores what |
| 75 // it considers are too small | 96 // it considers are too small |
| 76 throw Py.ValueError("size not valid: " + proposed_stack_size
+ " bytes"); | 97 throw Py.ValueError("size not valid: " + proposed_stack_size
+ " bytes"); |
| 77 } | 98 } |
| 78 stack_size = proposed_stack_size; | 99 stack_size = proposed_stack_size; |
| 79 return old_stack_size; | 100 return old_stack_size; |
| 80 default: | 101 default: |
| 81 throw Py.TypeError("stack_size() takes at most 1 argument (" + a
rgs.length + "given)"); | 102 throw Py.TypeError("stack_size() takes at most 1 argument (" + a
rgs.length + "given)"); |
| 82 } | 103 } |
| 83 } | 104 } |
| 84 } | 105 } |
| OLD | NEW |