-
Notifications
You must be signed in to change notification settings - Fork 399
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Capture the
threading.Thread.name
attribute
Previously we only captured the thread name as set by `prctl`, but not the thread name as returned by `threading.current_thread().name`. Begin capturing the name for the Python thread as well. We retain only the last name set for each thread, so assignments to `Thread.name` override earlier calls to `prctl(PR_SET_NAME)`, and vice versa. This implementation uses a custom descriptor to intercept assignments to `Thread._name` and `Thread._ident` in order to detect when a thread has a name or a thread id assigned to it. Because this is tricky and a bit fragile (poking at the internals of `Thread`), I've implemented that descriptor in a Python module. At least that way if it ever breaks, it should be a bit easier for someone to investigate. Signed-off-by: Matt Wozniski <[email protected]>
- Loading branch information
Showing
7 changed files
with
141 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
Capture the name attribute of Python `threading.Thread` objects. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import threading | ||
from typing import Callable | ||
|
||
|
||
class ThreadNameInterceptor: | ||
"""Record the name of each threading.Thread for Memray's reports. | ||
The name can be set either before or after the thread is started, and from | ||
either the same thread or a different thread. Whenever an assignment to | ||
either `Thread._name` or `Thread._ident` is performed and the other has | ||
already been set, we call a callback with the thread's ident and name. | ||
""" | ||
|
||
def __init__(self, attr: str, callback: Callable[[int, str], None]) -> None: | ||
self._attr = attr | ||
self._callback = callback | ||
|
||
def __set__(self, instance: threading.Thread, value: object) -> None: | ||
instance.__dict__[self._attr] = value | ||
ident = instance.__dict__.get("_ident") | ||
name = instance.__dict__.get("_name") | ||
if ident is not None and name is not None: | ||
self._callback(ident, name) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters