| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| Add two new public functions to the public C-API, | ||
| :c:func:`PyEval_SetProfileAllThreads` and | ||
| :c:func:`PyEval_SetTraceAllThreads`, that allow to set tracking and | ||
| profiling functions in all running threads in addition to the calling one. | ||
| Also, add a new *running_threads* parameter to :func:`threading.setprofile` | ||
| and :func:`threading.settrace` that allows to do the same from Python. Patch | ||
| by Pablo Galindo |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| Expand Up | @@ -96,6 +96,10 @@ | |
| #define _Py_atomic_load_relaxed_int32(ATOMIC_VAL) _Py_atomic_load_relaxed(ATOMIC_VAL) | ||
| #endif | ||
|
|
||
| #define HEAD_LOCK(runtime) \ | ||
| PyThread_acquire_lock((runtime)->interpreters.mutex, WAIT_LOCK) | ||
| #define HEAD_UNLOCK(runtime) \ | ||
| PyThread_release_lock((runtime)->interpreters.mutex) | ||
|
|
||
| /* Forward declarations */ | ||
| static PyObject *trace_call_function( | ||
| Expand Down Expand Up | @@ -6455,6 +6459,27 @@ PyEval_SetProfile(Py_tracefunc func, PyObject *arg) | |
| } | ||
| } | ||
|
|
||
| void | ||
|
Comment thread
Copy link
Copy Markdown
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low QualityIt's not great that the function cannot report errors. While not returning -1 on error and pass the exception to the caller, rather than handling it with _PyErr_WriteUnraisableMsg()?
Sorry, something went wrong.
All reactions
Copy link
Copy Markdown
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low QualityI am mimicking what we do already in PyEval_SetProfile and to avoid surprises I think we should keep these two as synchronized as possible.
Sorry, something went wrong.
All reactions
Copy link
Copy Markdown
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low QualityWe cannot fix the API of old functions, but we can avoid past mistakes in newly added functions.
Sorry, something went wrong.
All reactions
Copy link
Copy Markdown
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low QualityIf you want to ignore exceptions on purpose, please mention it in the function documentation.
Sorry, something went wrong.
All reactions
Copy link
Copy Markdown
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality
Yeah, I want to do that because I don't want to stop setting the profile function on other threads if an exception in one fails. Unless you strongly disagree, I will document this.
Sorry, something went wrong.
All reactions
|
||
| PyEval_SetProfileAllThreads(Py_tracefunc func, PyObject *arg) | ||
| { | ||
| PyThreadState *this_tstate = _PyThreadState_GET(); | ||
| PyInterpreterState* interp = this_tstate->interp; | ||
|
|
||
| _PyRuntimeState *runtime = &_PyRuntime; | ||
| HEAD_LOCK(runtime); | ||
| PyThreadState* ts = PyInterpreterState_ThreadHead(interp); | ||
| HEAD_UNLOCK(runtime); | ||
|
|
||
| while (ts) { | ||
| if (_PyEval_SetProfile(ts, func, arg) < 0) { | ||
| _PyErr_WriteUnraisableMsg("in PyEval_SetProfileAllThreads", NULL); | ||
| } | ||
| HEAD_LOCK(runtime); | ||
| ts = PyThreadState_Next(ts); | ||
|
Comment thread
pablogsal marked this conversation as resolved.
|
||
| HEAD_UNLOCK(runtime); | ||
| } | ||
| } | ||
|
Comment thread
pablogsal marked this conversation as resolved.
Outdated
Comment thread
pablogsal marked this conversation as resolved.
Outdated
|
||
|
|
||
| int | ||
| _PyEval_SetTrace(PyThreadState *tstate, Py_tracefunc func, PyObject *arg) | ||
| { | ||
| Expand Down Expand Up | @@ -6508,6 +6533,26 @@ PyEval_SetTrace(Py_tracefunc func, PyObject *arg) | |
| } | ||
| } | ||
|
|
||
| void | ||
| PyEval_SetTraceAllThreads(Py_tracefunc func, PyObject *arg) | ||
| { | ||
| PyThreadState *this_tstate = _PyThreadState_GET(); | ||
| PyInterpreterState* interp = this_tstate->interp; | ||
|
|
||
| _PyRuntimeState *runtime = &_PyRuntime; | ||
| HEAD_LOCK(runtime); | ||
| PyThreadState* ts = PyInterpreterState_ThreadHead(interp); | ||
| HEAD_UNLOCK(runtime); | ||
|
|
||
| while (ts) { | ||
| if (_PyEval_SetTrace(ts, func, arg) < 0) { | ||
| _PyErr_WriteUnraisableMsg("in PyEval_SetTraceAllThreads", NULL); | ||
| } | ||
| HEAD_LOCK(runtime); | ||
| ts = PyThreadState_Next(ts); | ||
| HEAD_UNLOCK(runtime); | ||
| } | ||
| } | ||
|
|
||
| int | ||
| _PyEval_SetCoroutineOriginTrackingDepth(int depth) | ||
| Expand Down | ||
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Back | FazBrowse Home | New Git URL |
Uh oh!
There was an error while loading. Please reload this page.