Skip to content

Commit

Permalink
bug #1111: try to make oneshot() thread safe
Browse files Browse the repository at this point in the history
  • Loading branch information
giampaolo committed Dec 8, 2018
1 parent 5398c48 commit 455a460
Showing 1 changed file with 33 additions and 36 deletions.
69 changes: 33 additions & 36 deletions psutil/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@
import signal
import subprocess
import sys
import threading
import time
try:
import pwd
Expand Down Expand Up @@ -361,7 +360,6 @@ def _init(self, pid, _ignore_nsp=False):
self._proc = _psplatform.Process(pid)
self._last_sys_cpu_times = None
self._last_proc_cpu_times = None
self._lock = threading.RLock()
# cache creation time for later use in is_running() method
try:
self.create_time()
Expand Down Expand Up @@ -458,41 +456,40 @@ def oneshot(self):
...
>>>
"""
with self._lock:
if self._oneshot_inctx:
# NOOP: this covers the use case where the user enters the
# context twice. Since as_dict() internally uses oneshot()
# I expect that the code below will be a pretty common
# "mistake" that the user will make, so let's guard
# against that:
#
# >>> with p.oneshot():
# ... p.as_dict()
# ...
if self._oneshot_inctx:
# NOOP: this covers the use case where the user enters the
# context twice. Since as_dict() internally uses oneshot()
# I expect that the code below will be a pretty common
# "mistake" that the user will make, so let's guard
# against that:
#
# >>> with p.oneshot():
# ... p.as_dict()
# ...
yield
else:
self._oneshot_inctx = True
try:
# cached in case cpu_percent() is used
self.cpu_times.cache_activate()
# cached in case memory_percent() is used
self.memory_info.cache_activate()
# cached in case parent() is used
self.ppid.cache_activate()
# cached in case username() is used
if POSIX:
self.uids.cache_activate()
# specific implementation cache
self._proc.oneshot_enter()
yield
else:
self._oneshot_inctx = True
try:
# cached in case cpu_percent() is used
self.cpu_times.cache_activate()
# cached in case memory_percent() is used
self.memory_info.cache_activate()
# cached in case parent() is used
self.ppid.cache_activate()
# cached in case username() is used
if POSIX:
self.uids.cache_activate()
# specific implementation cache
self._proc.oneshot_enter()
yield
finally:
self.cpu_times.cache_deactivate()
self.memory_info.cache_deactivate()
self.ppid.cache_deactivate()
if POSIX:
self.uids.cache_deactivate()
self._proc.oneshot_exit()
self._oneshot_inctx = False
finally:
self.cpu_times.cache_deactivate()
self.memory_info.cache_deactivate()
self.ppid.cache_deactivate()
if POSIX:
self.uids.cache_deactivate()
self._proc.oneshot_exit()
self._oneshot_inctx = False

def as_dict(self, attrs=None, ad_value=None):
"""Utility method returning process information as a
Expand Down

0 comments on commit 455a460

Please sign in to comment.