mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Fix threads stop and join
This commit is contained in:
@@ -1,10 +1,10 @@
|
||||
import time
|
||||
from pydevd_concurrency_analyser.pydevd_thread_wrappers import ObjectWrapper
|
||||
from pydevd_concurrency_analyser.pydevd_thread_wrappers import ObjectWrapper, wrap_attr
|
||||
|
||||
import pydevd_file_utils
|
||||
import pydevd_vars
|
||||
from _pydev_filesystem_encoding import getfilesystemencoding
|
||||
from pydevd_constants import DictContains, GetThreadId
|
||||
from pydevd_constants import DictContains, GetThreadId, IS_PY3K
|
||||
|
||||
file_system_encoding = getfilesystemencoding()
|
||||
|
||||
@@ -86,8 +86,6 @@ def get_text_list_for_frame(frame):
|
||||
return cmdTextList
|
||||
|
||||
|
||||
|
||||
|
||||
def send_message(event_class, time, name, thread_id, type, event, file, line, frame, lock_id=0, parent=None):
|
||||
dbg = GlobalDebuggerHolder.globalDbg
|
||||
cmdTextList = ['<xml>']
|
||||
@@ -135,7 +133,13 @@ class ThreadingLogger:
|
||||
self_obj = frame.f_locals["self"]
|
||||
if isinstance(self_obj, threading.Thread) or self_obj.__class__ == ObjectWrapper:
|
||||
write_log = True
|
||||
|
||||
if hasattr(frame, "f_back") and frame.f_back is not None:
|
||||
back = frame.f_back
|
||||
if hasattr(back, "f_back") and back.f_back is not None:
|
||||
back = back.f_back
|
||||
if DictContains(back.f_locals, "self"):
|
||||
if isinstance(back.f_locals["self"], threading.Thread):
|
||||
write_log = True
|
||||
try:
|
||||
if write_log:
|
||||
t = threadingCurrentThread()
|
||||
@@ -146,31 +150,55 @@ class ThreadingLogger:
|
||||
event_time = cur_time() - self.start_time
|
||||
method_name = frame.f_code.co_name
|
||||
|
||||
if isinstance(self_obj, threading.Thread) and method_name in THREAD_METHODS:
|
||||
if back_base not in DONT_TRACE_THREADING or \
|
||||
(method_name in INNER_METHODS and back_base in INNER_FILES):
|
||||
if isinstance(self_obj, threading.Thread):
|
||||
if not hasattr(self_obj, "_pydev_run_patched"):
|
||||
wrap_attr(self_obj, "run")
|
||||
if (method_name in THREAD_METHODS) and (back_base not in DONT_TRACE_THREADING or \
|
||||
(method_name in INNER_METHODS and back_base in INNER_FILES)):
|
||||
thread_id = GetThreadId(self_obj)
|
||||
name = self_obj.getName()
|
||||
real_method = frame.f_code.co_name
|
||||
parent = None
|
||||
if real_method == "_stop":
|
||||
# TODO: Python 2
|
||||
if back_base in INNER_FILES and \
|
||||
back.f_code.co_name == "_wait_for_tstate_lock":
|
||||
back = back.f_back.f_back
|
||||
real_method = "stop"
|
||||
if hasattr(self_obj, "_pydev_join_called"):
|
||||
parent = GetThreadId(t)
|
||||
elif real_method == "join":
|
||||
# join called in the current thread, not in self object
|
||||
if not self_obj.is_alive():
|
||||
return
|
||||
thread_id = GetThreadId(t)
|
||||
name = t.getName()
|
||||
setattr(self_obj, "_pydev_join_called", True)
|
||||
|
||||
parent = None
|
||||
if real_method in ("start", "stop"):
|
||||
if real_method == "start":
|
||||
parent = GetThreadId(t)
|
||||
send_message("threading_event", event_time, name, thread_id, "thread",
|
||||
real_method, back.f_code.co_filename, back.f_lineno, back, parent=parent)
|
||||
# print(event_time, self_obj.getName(), thread_id, "thread",
|
||||
# real_method, back.f_code.co_filename, back.f_lineno)
|
||||
|
||||
if method_name == "pydev_after_run_call":
|
||||
if hasattr(frame, "f_back") and frame.f_back is not None:
|
||||
back = frame.f_back
|
||||
if hasattr(back, "f_back") and back.f_back is not None:
|
||||
back = back.f_back
|
||||
if DictContains(back.f_locals, "self"):
|
||||
if isinstance(back.f_locals["self"], threading.Thread):
|
||||
my_self_obj = frame.f_back.f_back.f_locals["self"]
|
||||
my_back = frame.f_back.f_back
|
||||
my_thread_id = GetThreadId(my_self_obj)
|
||||
send_massage = True
|
||||
if IS_PY3K and hasattr(my_self_obj, "_pydev_join_called"):
|
||||
send_massage = False
|
||||
# we can't detect stop after join in Python 2 yet
|
||||
if send_massage:
|
||||
send_message("threading_event", event_time, "Thread", my_thread_id, "thread",
|
||||
"stop", my_back.f_code.co_filename, my_back.f_lineno, my_back, parent=None)
|
||||
|
||||
if self_obj.__class__ == ObjectWrapper:
|
||||
if back_base in DONT_TRACE_THREADING:
|
||||
# do not trace methods called from threading
|
||||
@@ -206,6 +234,7 @@ class ThreadingLogger:
|
||||
# print(event_time, t.getName(), GetThreadId(t), "lock",
|
||||
# real_method, back.f_code.co_filename, back.f_lineno)
|
||||
|
||||
|
||||
except Exception:
|
||||
traceback.print_exc()
|
||||
|
||||
|
||||
@@ -3,14 +3,21 @@ import _pydev_threading as threading
|
||||
|
||||
|
||||
def wrapper(fun):
|
||||
def pydev_after_run_call():
|
||||
pass
|
||||
|
||||
def inner(*args, **kwargs):
|
||||
print("start_new_thread called with params", args, kwargs)
|
||||
thread = threading.currentThread()
|
||||
thread.additionalInfo.save = True
|
||||
return fun(*args, **kwargs)
|
||||
fun(*args, **kwargs)
|
||||
pydev_after_run_call()
|
||||
return inner
|
||||
|
||||
|
||||
def wrap_attr(obj, attr):
|
||||
t_save_start = getattr(obj, attr)
|
||||
setattr(obj, attr, wrapper(t_save_start))
|
||||
setattr(obj, "_pydev_run_patched", True)
|
||||
|
||||
|
||||
class ObjectWrapper(object):
|
||||
def __init__(self, object):
|
||||
self.wrapped_object = object
|
||||
|
||||
Reference in New Issue
Block a user