Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@clayg
Created April 20, 2022 17:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save clayg/1e2e4cb8f9fd35032fb56358f93754ec to your computer and use it in GitHub Desktop.
Save clayg/1e2e4cb8f9fd35032fb56358f93754ec to your computer and use it in GitHub Desktop.
See if green_existing_locks works?
import logging
import eventlet.patcher
eventlet.patcher.monkey_patch(thread=True)
import threading
def take_and_release():
try:
logging._lock.acquire()
finally:
logging._lock.release()
assert logging._lock.acquire()
t = threading.Thread(target=take_and_release)
t.start()
t.join(timeout=1)
# we should timeout, and the thread is still blocking
assert t.isAlive()
logging._lock.release()
t.join(timeout=1)
assert not t.isAlive()
print('locking works')
@clayg
Copy link
Author

clayg commented Apr 20, 2022

if you comment out the patching; this works on py2 and py3

if you DO the patch - it doesn't work on py3

@tipabu
Copy link

tipabu commented Apr 20, 2022

If you patch eventlet like

diff --git a/eventlet/patcher.py b/eventlet/patcher.py
index b249d6f..a2f29fa 100644
--- a/eventlet/patcher.py
+++ b/eventlet/patcher.py
@@ -425,7 +425,7 @@ def _fix_py2_rlock(rlock, tid):
 
 def _fix_py3_rlock(old):
     import gc
-    import threading
+    from eventlet.green import threading
     new = threading._PyRLock()
     while old._is_owned():
         old.release()
@@ -434,14 +434,23 @@ def _fix_py3_rlock(old):
         new.acquire()
     gc.collect()
     for ref in gc.get_referrers(old):
-        try:
-            ref_vars = vars(ref)
-        except TypeError:
-            pass
-        else:
-            for k, v in ref_vars.items():
+        if isinstance(ref, dict):
+            for k, v in ref.items():
+                if v == old:
+                    ref[k] = new
+        elif isinstance(ref, list):
+            for k, v in enumerate(ref):
                 if v == old:
-                    setattr(ref, k, new)
+                    ref[k] = new
+        else:
+            try:
+                ref_vars = vars(ref)
+            except TypeError:
+                pass
+            else:
+                for k, v in ref_vars.items():
+                    if v == old:
+                        setattr(ref, k, new)
 
 
 def _green_os_modules():

it can work on py310 -- but prior to that, those C RLocks don't show up in gc.get_objects()! See eventlet/eventlet#546

@tipabu
Copy link

tipabu commented Apr 20, 2022

Submitted that as eventlet/eventlet#754 -- FWIW, if I add

eventlet.patcher._fix_py3_rlock(logging._lock)

right after monkey patching, this guy seems happy on older py3 versions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment