summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2013-02-13 14:17:08 +0100
committerBram Moolenaar <Bram@vim.org>2013-02-13 14:17:08 +0100
commit76d711c3b5397b749a67d229150d3c1ff3f33add (patch)
treeca5c0745ab1f3995faacee77be1bf4369ae4765d
parent51971b33988e590901b9f6ad14a5a36f276afd0b (diff)
downloadvim-76d711c3b5397b749a67d229150d3c1ff3f33add.zip
updated for version 7.3.808
Problem: Python threads still do not work properly. Solution: Fix both Python 2 and 3. Add tests. (Ken Takata)
-rw-r--r--src/if_python.c15
-rw-r--r--src/if_python3.c25
-rw-r--r--src/testdir/test86.in48
-rw-r--r--src/testdir/test86.ok2
-rw-r--r--src/testdir/test87.in48
-rw-r--r--src/testdir/test87.ok2
-rw-r--r--src/version.c2
7 files changed, 123 insertions, 19 deletions
diff --git a/src/if_python.c b/src/if_python.c
index 1bf737fc4..d0314e2f5 100644
--- a/src/if_python.c
+++ b/src/if_python.c
@@ -741,7 +741,7 @@ Python_Init(void)
PyMac_Initialize();
#endif
/* Initialise threads, and below save the state using
- * PyGILState_Ensure. Without the call to PyGILState_Ensure, thread
+ * PyEval_SaveThread. Without the call to PyEval_SaveThread, thread
* specific state (such as the system trace hook), will be lost
* between invocations of Python code. */
PyEval_InitThreads();
@@ -755,10 +755,6 @@ Python_Init(void)
if (PythonMod_Init())
goto fail;
- /* The first python thread is vim's, release the lock. */
- Python_SaveThread();
- pygilstate = PyGILState_Ensure();
-
globals = PyModule_GetDict(PyImport_AddModule("__main__"));
/* Remove the element from sys.path that was added because of our
@@ -767,7 +763,14 @@ Python_Init(void)
* the current directory in sys.path. */
PyRun_SimpleString("import sys; sys.path = filter(lambda x: x != '/must>not&exist', sys.path)");
- PyGILState_Release(pygilstate);
+ /* lock is created and acquired in PyEval_InitThreads() and thread
+ * state is created in Py_Initialize()
+ * there _PyGILState_NoteThreadState() also sets gilcounter to 1
+ * (python must have threads enabled!)
+ * so the following does both: unlock GIL and save thread state in TLS
+ * without deleting thread state
+ */
+ PyEval_SaveThread();
initialised = 1;
}
diff --git a/src/if_python3.c b/src/if_python3.c
index 4067517ac..5311483dd 100644
--- a/src/if_python3.c
+++ b/src/if_python3.c
@@ -729,13 +729,11 @@ Python3_Init(void)
#else
PyMac_Initialize();
#endif
- /* Initialise threads, and save the state using PyGILState_Ensure.
- * Without the call to PyGILState_Ensure, thread specific state (such
- * as the system trace hook), will be lost between invocations of
- * Python code. */
+ /* Initialise threads, and below save the state using
+ * PyEval_SaveThread. Without the call to PyEval_SaveThread, thread
+ * specific state (such as the system trace hook), will be lost
+ * between invocations of Python code. */
PyEval_InitThreads();
- pygilstate = PyGILState_Ensure();
-
#ifdef DYNAMIC_PYTHON3
get_py3_exceptions();
#endif
@@ -754,13 +752,14 @@ Python3_Init(void)
*/
PyRun_SimpleString("import vim; import sys; sys.path = list(filter(lambda x: not x.endswith('must>not&exist'), sys.path))");
- // lock is created and acquired in PyEval_InitThreads() and thread
- // state is created in Py_Initialize()
- // there _PyGILState_NoteThreadState() also sets gilcounter to 1
- // (python must have threads enabled!)
- // so the following does both: unlock GIL and save thread state in TLS
- // without deleting thread state
- PyGILState_Release(pygilstate);
+ /* lock is created and acquired in PyEval_InitThreads() and thread
+ * state is created in Py_Initialize()
+ * there _PyGILState_NoteThreadState() also sets gilcounter to 1
+ * (python must have threads enabled!)
+ * so the following does both: unlock GIL and save thread state in TLS
+ * without deleting thread state
+ */
+ PyEval_SaveThread();
py3initialised = 1;
}
diff --git a/src/testdir/test86.in b/src/testdir/test86.in
index 1309643d8..71635bda2 100644
--- a/src/testdir/test86.in
+++ b/src/testdir/test86.in
@@ -267,6 +267,54 @@ EOF
: $put =toput
: endtry
:endfor
+:"
+:" threading
+:let l = [0]
+:py l=vim.bindeval('l')
+:py <<EOF
+import threading
+import time
+
+class T(threading.Thread):
+ def __init__(self):
+ threading.Thread.__init__(self)
+ self.t = 0
+ self.running = True
+
+ def run(self):
+ while self.running:
+ self.t += 1
+ time.sleep(0.1)
+
+t = T()
+t.start()
+EOF
+:sleep 1
+:py t.running = False
+:py t.join()
+:py l[0] = t.t > 8 # check if the background thread is working
+:$put =string(l)
+:"
+:" settrace
+:let l = []
+:py l=vim.bindeval('l')
+:py <<EOF
+import sys
+
+def traceit(frame, event, arg):
+ global l
+ if event == "line":
+ l.extend([frame.f_lineno])
+ return traceit
+
+def trace_main():
+ for i in range(5):
+ pass
+EOF
+:py sys.settrace(traceit)
+:py trace_main()
+:py sys.settrace(None)
+:$put =string(l)
:endfun
:"
:call Test()
diff --git a/src/testdir/test86.ok b/src/testdir/test86.ok
index 5ef8689a2..3dd8d7994 100644
--- a/src/testdir/test86.ok
+++ b/src/testdir/test86.ok
@@ -63,3 +63,5 @@ ll:[1]
{"\0": 1}: Vim(let):E859:
undefined_name: Vim(let):E858:
vim: Vim(let):E859:
+[1]
+[1, 10, 11, 10, 11, 10, 11, 10, 11, 10, 11, 10, 1]
diff --git a/src/testdir/test87.in b/src/testdir/test87.in
index 1d7ccedd5..5115e5be7 100644
--- a/src/testdir/test87.in
+++ b/src/testdir/test87.in
@@ -267,6 +267,54 @@ EOF
: $put =toput
: endtry
:endfor
+:"
+:" threading
+:let l = [0]
+:py3 l=vim.bindeval('l')
+:py3 <<EOF
+import threading
+import time
+
+class T(threading.Thread):
+ def __init__(self):
+ threading.Thread.__init__(self)
+ self.t = 0
+ self.running = True
+
+ def run(self):
+ while self.running:
+ self.t += 1
+ time.sleep(0.1)
+
+t = T()
+t.start()
+EOF
+:sleep 1
+:py3 t.running = False
+:py3 t.join()
+:py3 l[0] = t.t > 8 # check if the background thread is working
+:$put =string(l)
+:"
+:" settrace
+:let l = []
+:py3 l=vim.bindeval('l')
+:py3 <<EOF
+import sys
+
+def traceit(frame, event, arg):
+ global l
+ if event == "line":
+ l += [frame.f_lineno]
+ return traceit
+
+def trace_main():
+ for i in range(5):
+ pass
+EOF
+:py3 sys.settrace(traceit)
+:py3 trace_main()
+:py3 sys.settrace(None)
+:$put =string(l)
:endfun
:"
:call Test()
diff --git a/src/testdir/test87.ok b/src/testdir/test87.ok
index 4c0bb799d..3dffa26d4 100644
--- a/src/testdir/test87.ok
+++ b/src/testdir/test87.ok
@@ -63,3 +63,5 @@ ll:[1]
{"\0": 1}: Vim(let):E861:
undefined_name: Vim(let):E860:
vim: Vim(let):E861:
+[1]
+[1, 10, 11, 10, 11, 10, 11, 10, 11, 10, 11, 10, 1]
diff --git a/src/version.c b/src/version.c
index 1c23a5e87..c716154e2 100644
--- a/src/version.c
+++ b/src/version.c
@@ -726,6 +726,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 808,
+/**/
807,
/**/
806,