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
6c30ef65
Commit
6c30ef65
authored
Mar 24, 2018
by
Jason Madden
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Also compile the Event and (more importantly) AsyncResult class.
parent
4bac7f17
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
155 additions
and
26 deletions
+155
-26
.gitignore
.gitignore
+1
-0
CHANGES.rst
CHANGES.rst
+4
-0
setup.py
setup.py
+14
-0
src/gevent/__imap.pxd
src/gevent/__imap.pxd
+4
-1
src/gevent/_event.pxd
src/gevent/_event.pxd
+70
-0
src/gevent/_greenlet.pxd
src/gevent/_greenlet.pxd
+6
-4
src/gevent/_imap.py
src/gevent/_imap.py
+10
-9
src/gevent/event.py
src/gevent/event.py
+45
-12
src/gevent/greenlet.py
src/gevent/greenlet.py
+1
-0
No files found.
.gitignore
View file @
6c30ef65
...
...
@@ -12,6 +12,7 @@ src/gevent/local.c
src/gevent/greenlet.c
src/gevent/_ident.c
src/gevent/_imap.c
src/gevent/event.c
src/gevent/libev/corecext.c
src/gevent/libev/corecext.h
src/gevent/libev/_corecffi.c
...
...
CHANGES.rst
View file @
6c30ef65
...
...
@@ -49,6 +49,10 @@ Enhancements
``IMapUnordered`` classes are now compiled with Cython, further
reducing the overhead of ``[Thread]Pool.imap``.
- The classes `gevent.event.Event` and `gevent.event.AsyncResult`
are compiled with Cython for improved performance. Please report any
compatibility issues.
Monitoring and Debugging
------------------------
...
...
setup.py
View file @
6c30ef65
...
...
@@ -99,12 +99,19 @@ IMAP = Extension(name="gevent.__imap",
depends
=
[
'src/gevent/__imap.pxd'
],
include_dirs
=
include_dirs
)
EVENT
=
Extension
(
name
=
"gevent._event"
,
sources
=
[
"src/gevent/event.py"
],
depends
=
[
'src/gevent/_event.pxd'
],
include_dirs
=
include_dirs
)
_to_cythonize
=
[
SEMAPHORE
,
LOCAL
,
GREENLET
,
IDENT
,
IMAP
,
EVENT
,
]
EXT_MODULES
=
[
...
...
@@ -115,6 +122,7 @@ EXT_MODULES = [
GREENLET
,
IDENT
,
IMAP
,
EVENT
,
]
LIBEV_CFFI_MODULE
=
'src/gevent/libev/_corecffi_build.py:ffi'
...
...
@@ -177,6 +185,12 @@ if PYPY:
_to_cythonize
.
remove
(
SEMAPHORE
)
_to_cythonize
.
remove
(
IDENT
)
EXT_MODULES
.
remove
(
IMAP
)
_to_cythonize
.
remove
(
IMAP
)
EXT_MODULES
.
remove
(
EVENT
)
_to_cythonize
.
remove
(
EVENT
)
for
mod
in
_to_cythonize
:
EXT_MODULES
.
remove
(
mod
)
...
...
src/gevent/__imap.pxd
View file @
6c30ef65
...
...
@@ -2,9 +2,12 @@ cimport cython
from
gevent._greenlet
cimport
Greenlet
from
gevent.__semaphore
cimport
Semaphore
@
cython
.
freelist
(
100
)
cdef
class
Failure
:
cdef
readonly
exc
cdef
_raise_exception
cdef
raise_exception
cdef
inline
_raise_exc
(
Failure
failure
)
cdef
class
IMapUnordered
(
Greenlet
):
cdef
bint
_zipped
...
...
src/gevent/_event.pxd
0 → 100644
View file @
6c30ef65
cimport
cython
cdef
_None
cdef
reraise
cdef
dump_traceback
cdef
load_traceback
cdef
get_hub
cdef
InvalidSwitchError
cdef
Timeout
cdef
bint
_greenlet_imported
cdef
extern
from
"greenlet/greenlet.h"
:
ctypedef
class
greenlet
.
greenlet
[
object
PyGreenlet
]:
pass
# These are actually macros and so much be included
# (defined) in each .pxd, as are the two functions
# that call them.
greenlet
PyGreenlet_GetCurrent
()
void
PyGreenlet_Import
()
cdef
inline
greenlet
getcurrent
():
return
PyGreenlet_GetCurrent
()
cdef
inline
void
greenlet_init
():
global
_greenlet_imported
if
not
_greenlet_imported
:
PyGreenlet_Import
()
_greenlet_imported
=
True
cdef
void
_init
()
cdef
class
_AbstractLinkable
:
cdef
_notifier
cdef
set
_links
cdef
readonly
hub
cpdef
rawlink
(
self
,
callback
)
cpdef
bint
ready
(
self
)
cpdef
unlink
(
self
,
callback
)
cdef
_check_and_notify
(
self
)
@
cython
.
locals
(
todo
=
set
)
cpdef
_notify_links
(
self
)
cdef
_wait_core
(
self
,
timeout
,
catch
=*
)
cdef
_wait_return_value
(
self
,
waited
,
wait_success
)
cdef
_wait
(
self
,
timeout
=*
)
cdef
class
Event
(
_AbstractLinkable
):
cdef
bint
_flag
cdef
class
AsyncResult
(
_AbstractLinkable
):
cdef
readonly
_value
cdef
readonly
tuple
_exc_info
# For the use of _imap.py
cdef
public
int
_imap_task_index
cpdef
get
(
self
,
block
=*
,
timeout
=*
)
cpdef
bint
successful
(
self
)
cpdef
wait
(
self
,
timeout
=*
)
cpdef
bint
done
(
self
)
cpdef
bint
cancel
(
self
)
cpdef
bint
cancelled
(
self
)
src/gevent/_greenlet.pxd
View file @
6c30ef65
...
...
@@ -43,7 +43,6 @@ cdef extern from "frameobject.h":
# proper None instead.
# cdef FrameType f_back
cdef
void
_init
()
cdef
class
SpawnedLink
:
...
...
@@ -119,9 +118,12 @@ cdef class Greenlet(greenlet):
# This is used as the target of a callback
# from the loop, and so needs to be a cpdef
cpdef
_notify_links
(
self
)
# IMapUnordered greenlets in pools need to access this
# method
cpdef
_raise_exception
(
self
)
# Hmm, declaring _raise_exception causes issues when _imap
# is also compiled.
# TypeError: wrap() takes exactly one argument (0 given)
# cpdef _raise_exception(self)
@
cython
.
final
cdef
greenlet
get_hub
()
...
...
src/gevent/_imap.py
View file @
6c30ef65
# -*- coding: utf-8 -*-
# Copyright (c) 2018 gevent
# cython: auto_pickle=False,embedsignature=True,always_allow_keywords=False
# cython: auto_pickle=False,embedsignature=True,always_allow_keywords=False
,infer_types=True
"""
Iterators across greenlets or AsyncResult objects.
...
...
@@ -24,18 +24,19 @@ locals()['Semaphore'] = _semaphore.Semaphore
class
Failure
(
object
):
__slots__
=
(
'exc'
,
'
_
raise_exception'
)
__slots__
=
(
'exc'
,
'raise_exception'
)
def
__init__
(
self
,
exc
,
raise_exception
=
None
):
self
.
exc
=
exc
self
.
_
raise_exception
=
raise_exception
self
.
raise_exception
=
raise_exception
def
raise_exc
(
self
):
if
self
.
_raise_exception
:
self
.
_raise_exception
()
else
:
raise
self
.
exc
def
_raise_exc
(
failure
):
# For cython.
if
failure
.
raise_exception
:
failure
.
raise_exception
()
else
:
raise
failure
.
exc
class
IMapUnordered
(
Greenlet
):
# pylint:disable=undefined-variable
"""
...
...
@@ -102,7 +103,7 @@ class IMapUnordered(Greenlet): # pylint:disable=undefined-variable
self
.
_result_semaphore
.
release
()
value
=
self
.
_inext
()
if
isinstance
(
value
,
Failure
):
raise
value
.
exc
_raise_exc
(
value
)
return
value
next
=
__next__
# Py2
...
...
src/gevent/event.py
View file @
6c30ef65
# Copyright (c) 2009-2016 Denis Bilenko, gevent contributors. See LICENSE for details.
# cython: auto_pickle=False,embedsignature=True,always_allow_keywords=False,infer_types=True
"""Basic synchronization primitives: Event and AsyncResult"""
from
__future__
import
print_function
import
sys
...
...
@@ -8,19 +10,27 @@ from gevent._compat import reraise
from
gevent._tblib
import
dump_traceback
,
load_traceback
from
gevent.hub
import
_get_hub_noargs
as
get_hub
from
gevent.hub
import
getcurrent
from
gevent.hub
import
InvalidSwitchError
from
gevent.timeout
import
Timeout
__all__
=
[
'Event'
,
'AsyncResult'
]
__all__
=
[
'Event'
,
'AsyncResult'
,
]
locals
()[
'getcurrent'
]
=
__import__
(
'greenlet'
).
getcurrent
locals
()[
'greenlet_init'
]
=
lambda
:
None
import
cython
class
_AbstractLinkable
(
object
):
# Encapsulates the standard parts of the linking and notifying protocol
# common to both repeatable events and one-time events (AsyncResult).
_
notifier
=
None
_
_slots__
=
(
'_links'
,
'hub'
,
'_notifier'
)
def
__init__
(
self
):
# Also previously, AsyncResult maintained the order of notifications, but Event
...
...
@@ -35,6 +45,7 @@ class _AbstractLinkable(object):
# uniqueness would be with a 2.7+ OrderedDict.)
self
.
_links
=
set
()
self
.
hub
=
get_hub
()
self
.
_notifier
=
None
def
ready
(
self
):
# Instances must define this
...
...
@@ -95,14 +106,14 @@ class _AbstractLinkable(object):
# bool(self._notifier) would turn to False as soon as we exit this
# method anyway.
del
todo
del
self
.
_notifier
self
.
_notifier
=
None
def
_wait_core
(
self
,
timeout
,
catch
=
Timeout
):
# The core of the wait implementation, handling
# switching and linking. If *catch* is set to (),
# a timeout that elapses will be allowed to be raised.
# Returns a true value if the wait succeeded without timing out.
switch
=
getcurrent
().
switch
switch
=
getcurrent
().
switch
# pylint:disable=undefined-variable
self
.
rawlink
(
switch
)
try
:
with
Timeout
.
_start_new_or_dummy
(
timeout
)
as
timer
:
...
...
@@ -148,7 +159,11 @@ class Event(_AbstractLinkable):
the waiting greenlets being awakened. These details may change in the future.
"""
_flag
=
False
__slots__
=
(
'_flag'
,)
def
__init__
(
self
):
_AbstractLinkable
.
__init__
(
self
)
self
.
_flag
=
False
def
__str__
(
self
):
return
'<%s %s _links[%s]>'
%
(
self
.
__class__
.
__name__
,
(
self
.
_flag
and
'set'
)
or
'clear'
,
len
(
self
.
_links
))
...
...
@@ -157,8 +172,14 @@ class Event(_AbstractLinkable):
"""Return true if and only if the internal flag is true."""
return
self
.
_flag
isSet
=
is_set
# makes it a better drop-in replacement for threading.Event
ready
=
is_set
# makes it compatible with AsyncResult and Greenlet (for example in wait())
def
isSet
(
self
):
# makes it a better drop-in replacement for threading.Event
return
self
.
_flag
def
ready
(
self
):
# makes it compatible with AsyncResult and Greenlet (for
# example in wait())
return
self
.
_flag
def
set
(
self
):
"""
...
...
@@ -221,7 +242,7 @@ class Event(_AbstractLinkable):
return
self
.
_wait
(
timeout
)
def
_reset_internal_locks
(
self
):
# pragma: no cover
# for compatibility with threading.Event
(only in case of patch_all(Event=True), by default Event is not patched)
# for compatibility with threading.Event
# Exception AttributeError: AttributeError("'Event' object has no attribute '_reset_internal_locks'",)
# in <module 'threading' from '/usr/lib/python2.7/threading.pyc'> ignored
pass
...
...
@@ -277,9 +298,12 @@ class AsyncResult(_AbstractLinkable):
merged.
"""
_value
=
_NONE
_exc_info
=
()
_notifier
=
None
__slots__
=
(
'_value'
,
'_exc_info'
,
'_imap_task_index'
)
def
__init__
(
self
):
_AbstractLinkable
.
__init__
(
self
)
self
.
_value
=
_NONE
self
.
_exc_info
=
()
@
property
def
_exception
(
self
):
...
...
@@ -448,3 +472,12 @@ class AsyncResult(_AbstractLinkable):
return
False
# exception is a method, we use it as a property
def
_init
():
greenlet_init
()
# pylint:disable=undefined-variable
_init
()
from
gevent._util
import
import_c_accel
import_c_accel
(
globals
(),
'gevent._event'
)
src/gevent/greenlet.py
View file @
6c30ef65
# Copyright (c) 2009-2012 Denis Bilenko. See LICENSE for details.
# cython: auto_pickle=False,embedsignature=True,always_allow_keywords=False
from
__future__
import
absolute_import
,
print_function
,
division
from
sys
import
_getframe
as
sys_getframe
...
...
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