Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gevent
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
gevent
Commits
fc3b2514
Commit
fc3b2514
authored
Jul 15, 2015
by
Jason Madden
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Patch existing locks held at the time of monkey-patching. Fixes #615.
parent
914061ec
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
71 additions
and
2 deletions
+71
-2
changelog.rst
changelog.rst
+14
-1
gevent/monkey.py
gevent/monkey.py
+40
-1
greentest/_import_import_patch.py
greentest/_import_import_patch.py
+1
-0
greentest/_import_patch.py
greentest/_import_patch.py
+2
-0
greentest/test__monkey_multiple_imports.py
greentest/test__monkey_multiple_imports.py
+6
-0
greentest/test__threading_holding_lock_while_monkey.py
greentest/test__threading_holding_lock_while_monkey.py
+8
-0
No files found.
changelog.rst
View file @
fc3b2514
...
...
@@ -73,6 +73,12 @@ Unreleased
also safer (but not configurations that involve such things as the
``SocketHandler``).
- Fix monkey-patching of ``threading.RLock`` under Python 3.
- Under Python 3, monkey-patching at the top-level of a module that
was imported by another module could result in a ``RuntimeError``
from ``importlib``. Reported in :issue:`615` by Daniel Mizyrycki.
(The same thing could happen under Python 2 if a ``threading.RLock``
was held around the monkey-patching call; this is less likely but
not impossible with import hooks.)
1.1a2 (Jul 8, 2015)
===================
...
...
@@ -178,7 +184,7 @@ Unreleased
- ``gevent.pool.Group.imap`` and ``imap_unordered`` now accept
multiple iterables like ``itertools.imap``. :issue:`565` reported by
Thomas Steinacher.
-
Potentially breaking change
: ``gevent.baseserver.BaseServer`` and
-
*Compatibility note*
: ``gevent.baseserver.BaseServer`` and
its subclass ``gevent.server.StreamServer`` now deterministically
close the client socket when the request handler returns.
Previously, the socket was left at the mercies of the garbage
...
...
@@ -188,6 +194,13 @@ Unreleased
future and under CPython 3.x a ResourceWarning could be generated.
This was undocumented behaviour, and the client socket could be kept
open after the request handler returned either accidentally or intentionally.
- *Compatibility note*: ``pywsgi`` now ensures that headers can be
encoded in latin-1 (ISO-8859-1). This improves adherence to the HTTP
standard (and is necessary under Python 3). Under certain
conditions, previous versions could have allowed non-ISO-8859-1
headers to be sent, but their interpretation by a conforming
recipient is unknown; now, a UnicodeError will be raised. See :issue:`614`.
Release 1.0.2
=============
...
...
gevent/monkey.py
View file @
fc3b2514
...
...
@@ -147,13 +147,47 @@ def patch_time():
patch_item
(
time
,
'sleep'
,
sleep
)
def
patch_thread
(
threading
=
True
,
_threading_local
=
True
,
Event
=
False
,
logging
=
True
):
def
_patch_existing_locks
(
threading
):
if
len
(
list
(
threading
.
enumerate
()))
!=
1
:
return
tid
=
threading
.
current_thread
().
ident
rlock_type
=
type
(
threading
.
RLock
())
try
:
import
importlib._bootstrap
except
NameError
:
class
_ModuleLock
(
object
):
pass
else
:
_ModuleLock
=
importlib
.
_bootstrap
.
_ModuleLock
# It might be possible to walk up all the existing stack frames to find
# locked objects...at least if they use `with`. To be sure, we look at every object
# Since we're supposed to be done very early in the process, there shouldn't be
# too many.
gc
=
__import__
(
'gc'
)
for
o
in
gc
.
get_objects
():
if
isinstance
(
o
,
rlock_type
):
if
o
.
_RLock__owner
is
not
None
:
# By definition there's only one thread running,
# so this was the old (native) thread id. Make
# it our current greenlet id so that when it wants to unlock
# and compare self.__owner with _get_ident(), they match
o
.
_RLock__owner
=
tid
elif
isinstance
(
o
,
_ModuleLock
):
if
o
.
owner
is
not
None
:
o
.
owner
=
tid
def
patch_thread
(
threading
=
True
,
_threading_local
=
True
,
Event
=
False
,
logging
=
True
,
existing_locks
=
True
):
"""Replace the standard :mod:`thread` module to make it greenlet-based.
- If *threading* is true (the default), also patch ``threading``.
- If *_threading_local* is true (the default), also patch ``_threading_local.local``.
- If *logging* is True (the default), also patch locks taken if the logging module has
been configured.
- If *existing_locks* is True (the default), and the process is still single threaded,
make sure than any :class:`threading.RLock` (and, under Python 3, :class:`importlib._bootstrap._ModuleLock`)
instances that are currently locked can be properly unlocked.
"""
patch_module
(
'thread'
)
if
threading
:
...
...
@@ -162,6 +196,10 @@ def patch_thread(threading=True, _threading_local=True, Event=False, logging=Tru
if
Event
:
from
gevent.event
import
Event
patch_item
(
threading
,
'Event'
,
Event
)
if
existing_locks
:
_patch_existing_locks
(
threading
)
if
logging
and
'logging'
in
sys
.
modules
:
logging
=
__import__
(
'logging'
)
patch_item
(
logging
,
'_lock'
,
threading
.
RLock
())
...
...
@@ -179,6 +217,7 @@ def patch_thread(threading=True, _threading_local=True, Event=False, logging=Tru
patch_item
(
_threading_local
,
'local'
,
local
)
if
sys
.
version_info
[:
2
]
>=
(
3
,
4
):
# Issue 18808 changes the nature of Thread.join() to use
# locks. This means that a greenlet spawned in the main thread
# (which is already running) cannot wait for the main thread---it
...
...
greentest/_import_import_patch.py
0 → 100644
View file @
fc3b2514
import
_import_patch
greentest/_import_patch.py
0 → 100644
View file @
fc3b2514
import
gevent.monkey
gevent
.
monkey
.
patch_all
()
greentest/test__monkey_multiple_imports.py
0 → 100644
View file @
fc3b2514
# https://github.com/gevent/gevent/issues/615
# Under Python 3, with its use of importlib,
# if the monkey patch is done when the importlib import lock is held
# (e.g., during recursive imports) we could fail to release the lock.
# This is surprisingly common.
import
_import_import_patch
greentest/test__threading_holding_lock_while_monkey.py
0 → 100644
View file @
fc3b2514
from
gevent
import
monkey
import
threading
# Make sure that we can patch gevent while holding
# a threading lock. Under Python2, where RLock is implemented
# in python code, this used to throw RuntimeErro("Cannot release un-acquired lock")
# See https://github.com/gevent/gevent/issues/615
with
threading
.
RLock
():
monkey
.
patch_all
()
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment