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
111521eb
Commit
111521eb
authored
Feb 24, 2018
by
Jason Madden
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'master' of
https://github.com/gevent/gevent
parents
df0163d0
b3537301
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
71 additions
and
37 deletions
+71
-37
CHANGES.rst
CHANGES.rst
+6
-4
src/gevent/_greenlet.pxd
src/gevent/_greenlet.pxd
+30
-8
src/gevent/greenlet.py
src/gevent/greenlet.py
+35
-25
No files found.
CHANGES.rst
View file @
111521eb
...
...
@@ -87,13 +87,15 @@
- Greenlet objects now keep track of their spawning parent greenlet
and the code location that spawned them, in addition to maintaining
a "spawn tree local" mapping. Based on a proposal from PayPal and
comments by Mahmoud Hashemi and Kurt Rose. See :issue:`755` and
:pr:`1115`. As always, feedback is appreciated.
a "spawn tree local" mapping. This adds some runtime overhead in
relative terms, but absolute numbers are still relatively small.
Based on a proposal from PayPal and comments by Mahmoud Hashemi and
Kurt Rose. See :issue:`755` and :pr:`1115`. As always, feedback is
appreciated.
- The :mod:`gevent.greenlet` module is now compiled with Cython to
offset any performance decrease due to :issue:`755`. Please open
issues for any compatibility concerns. See :pr:`1115`.
issues for any compatibility concerns. See :pr:`1115`
and :pr:`1120`
.
- Greenlet objects now have a ``minimal_ident`` property. It functions
similarly to ``Thread.ident`` or ``id`` by uniquely identifying the
...
...
src/gevent/_greenlet.pxd
View file @
111521eb
...
...
@@ -4,6 +4,8 @@ cimport cython
from
gevent.__ident
cimport
IdentRegistry
cdef
bint
_greenlet_imported
cdef
bint
_PYPY
cdef
sys_getframe
cdef
sys_exc_info
cdef
extern
from
"greenlet/greenlet.h"
:
...
...
@@ -25,6 +27,23 @@ cdef inline void greenlet_init():
PyGreenlet_Import
()
_greenlet_imported
=
True
cdef
extern
from
"Python.h"
:
ctypedef
class
types
.
CodeType
[
object
PyCodeObject
]:
pass
cdef
extern
from
"frameobject.h"
:
ctypedef
class
types
.
FrameType
[
object
PyFrameObject
]:
cdef
CodeType
f_code
cdef
int
f_lineno
# We can't declare this in the object, because it's
# allowed to be NULL, and Cython can't handle that.
# We have to go through the python machinery to get a
# proper None instead.
# cdef FrameType f_back
cdef
void
_init
()
cdef
class
SpawnedLink
:
...
...
@@ -42,18 +61,18 @@ cdef class FailureSpawnedLink(SpawnedLink):
@
cython
.
final
@
cython
.
internal
cdef
class
_Frame
:
cdef
readonly
object
f_code
cdef
readonly
CodeType
f_code
cdef
readonly
int
f_lineno
cdef
public
_Frame
f_back
cdef
readonly
_Frame
f_back
@
cython
.
final
@
cython
.
locals
(
previous
=
_Frame
,
first
=
_Frame
,
next_frame
=
_Frame
)
cdef
_Frame
_extract_stack
(
int
limit
,
_Frame
f_back
)
@
cython
.
locals
(
frames
=
list
,
frame
=
FrameType
)
cdef
inline
list
_extract_stack
(
int
limit
)
@
cython
.
final
@
cython
.
locals
(
previous
=
_Frame
,
frame
=
tuple
,
f
=
_Frame
)
cdef
_Frame
_Frame_from_list
(
list
frames
)
cdef
class
Greenlet
(
greenlet
):
...
...
@@ -61,7 +80,10 @@ cdef class Greenlet(greenlet):
cdef
readonly
args
cdef
readonly
object
spawning_greenlet
cdef
public
dict
spawn_tree_locals
cdef
readonly
_Frame
spawning_stack
# This is accessed with getattr() dynamically so it
# must be visible to Python
cdef
readonly
list
_spawning_stack_frames
cdef
list
_links
cdef
tuple
_exc_info
...
...
src/gevent/greenlet.py
View file @
111521eb
...
...
@@ -2,13 +2,15 @@
# cython: auto_pickle=False,embedsignature=True,always_allow_keywords=False
from
__future__
import
absolute_import
,
print_function
,
division
import
sys
from
sys
import
_getframe
as
sys_getframe
from
sys
import
exc_info
as
sys_exc_info
from
weakref
import
ref
as
wref
from
greenlet
import
greenlet
from
gevent._compat
import
reraise
from
gevent._compat
import
PYPY
as
_PYPY
from
gevent._tblib
import
dump_traceback
from
gevent._tblib
import
load_traceback
from
gevent.hub
import
GreenletExit
...
...
@@ -18,8 +20,7 @@ from gevent.hub import get_hub
from
gevent.hub
import
iwait
from
gevent.hub
import
wait
from
gevent.timeout
import
Timeout
_PYPY
=
hasattr
(
sys
,
'pypy_version_info'
)
from
gevent._util
import
Lazy
__all__
=
[
...
...
@@ -108,26 +109,28 @@ class _Frame(object):
self
.
f_lineno
=
f_lineno
self
.
f_back
=
None
f_globals
=
property
(
lambda
_self
:
None
)
@
property
def
f_globals
(
self
):
return
None
def
_
extract_stack
(
limit
,
f_back
):
def
_
Frame_from_list
(
frames
):
previous
=
None
frame
=
sys
.
_getframe
()
first
=
None
for
frame
in
reversed
(
frames
):
f
=
_Frame
(
*
frame
)
f
.
f_back
=
previous
previous
=
f
return
previous
first
=
previous
=
_Frame
(
frame
.
f_code
,
frame
.
f_lineno
)
limit
-=
1
frame
=
frame
.
f_back
def
_extract_stack
(
limit
):
frame
=
sys_getframe
()
frame
s
=
[]
while
limit
and
frame
is
not
None
:
limit
-=
1
next_frame
=
_Frame
(
frame
.
f_code
,
frame
.
f_lineno
)
previous
.
f_back
=
next_frame
previous
=
next_frame
frames
.
append
((
frame
.
f_code
,
frame
.
f_lineno
))
frame
=
frame
.
f_back
previous
.
f_back
=
f_back
return
first
return
frames
_greenlet__init__
=
greenlet
.
__init__
...
...
@@ -274,9 +277,16 @@ class Greenlet(greenlet):
# Its children get separate locals.
spawner
.
spawn_tree_locals
=
self
.
spawn_tree_locals
self
.
_spawning_stack_frames
=
_extract_stack
(
self
.
spawning_stack_limit
)
self
.
_spawning_stack_frames
.
extend
(
getattr
(
spawner
,
'_spawning_stack_frames'
,
[]))
self
.
spawning_stack
=
_extract_stack
(
self
.
spawning_stack_limit
,
getattr
(
spawner
,
'spawning_stack'
,
None
))
@
Lazy
def
spawning_stack
(
self
):
# Store this in the __dict__. We don't use it from the C
# code. It's tempting to discard _spawning_stack_frames
# after this, but child greenlets may still be created
# that need it.
return
_Frame_from_list
(
self
.
_spawning_stack_frames
)
def
_get_minimal_ident
(
self
):
reg
=
self
.
parent
.
ident_registry
...
...
@@ -476,9 +486,9 @@ class Greenlet(greenlet):
.. versionadded:: 1.1
"""
e
xc_info
=
self
.
_exc_info
if
e
xc_info
is
not
None
and
exc_info
[
0
]
is
not
None
:
return
(
e
xc_info
[
0
],
exc_info
[
1
],
load_traceback
(
exc_info
[
2
]))
e
i
=
self
.
_exc_info
if
e
i
is
not
None
and
ei
[
0
]
is
not
None
:
return
(
e
i
[
0
],
ei
[
1
],
load_traceback
(
ei
[
2
]))
def
throw
(
self
,
*
args
):
"""Immediately switch into the greenlet and raise an exception in it.
...
...
@@ -708,7 +718,7 @@ class Greenlet(greenlet):
try
:
result
=
self
.
_run
(
*
self
.
args
,
**
self
.
kwargs
)
except
:
# pylint:disable=bare-except
self
.
_report_error
(
sys
.
exc_info
())
self
.
_report_error
(
sys
_
exc_info
())
return
self
.
_report_result
(
result
)
finally
:
...
...
@@ -801,7 +811,7 @@ class Greenlet(greenlet):
try
:
link
(
self
)
except
:
# pylint:disable=bare-except
self
.
parent
.
handle_error
((
link
,
self
),
*
sys
.
exc_info
())
self
.
parent
.
handle_error
((
link
,
self
),
*
sys
_
exc_info
())
class
_dummy_event
(
object
):
...
...
@@ -828,7 +838,7 @@ def _kill(glet, exception, waiter):
glet
.
throw
(
exception
)
except
:
# pylint:disable=bare-except
# XXX do we need this here?
glet
.
parent
.
handle_error
(
glet
,
*
sys
.
exc_info
())
glet
.
parent
.
handle_error
(
glet
,
*
sys
_
exc_info
())
if
waiter
is
not
None
:
waiter
.
switch
()
...
...
@@ -863,7 +873,7 @@ def _killall3(greenlets, exception, waiter):
try
:
g
.
throw
(
exception
)
except
:
# pylint:disable=bare-except
g
.
parent
.
handle_error
(
g
,
*
sys
.
exc_info
())
g
.
parent
.
handle_error
(
g
,
*
sys
_
exc_info
())
if
not
g
.
dead
:
diehards
.
append
(
g
)
waiter
.
switch
(
diehards
)
...
...
@@ -875,7 +885,7 @@ def _killall(greenlets, exception):
try
:
g
.
throw
(
exception
)
except
:
# pylint:disable=bare-except
g
.
parent
.
handle_error
(
g
,
*
sys
.
exc_info
())
g
.
parent
.
handle_error
(
g
,
*
sys
_
exc_info
())
def
killall
(
greenlets
,
exception
=
GreenletExit
,
block
=
True
,
timeout
=
None
):
...
...
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