Windows: Use 32-bit distribution of python
This commit is contained in:
@@ -64,7 +64,8 @@ struct ev_loop {
|
||||
// Watcher types
|
||||
// base for all watchers
|
||||
struct ev_watcher{
|
||||
GEVENT_STRUCT_DONE _;
|
||||
void* data;
|
||||
GEVENT_STRUCT_DONE _;
|
||||
};
|
||||
|
||||
struct ev_io {
|
||||
@@ -137,6 +138,9 @@ unsigned int ev_embeddable_backends (void);
|
||||
ev_tstamp ev_time (void);
|
||||
void ev_set_syserr_cb(void *);
|
||||
|
||||
void ev_set_userdata(struct ev_loop*, void*);
|
||||
void* ev_userdata(struct ev_loop*);
|
||||
|
||||
int ev_priority(void*);
|
||||
void ev_set_priority(void*, int);
|
||||
|
||||
@@ -212,10 +216,19 @@ void (*gevent_noop)(struct ev_loop *_loop, struct ev_timer *w, int revents);
|
||||
void ev_sleep (ev_tstamp delay); /* sleep for a while */
|
||||
|
||||
/* gevent callbacks */
|
||||
static int (*python_callback)(void* handle, int revents);
|
||||
static void (*python_handle_error)(void* handle, int revents);
|
||||
static void (*python_stop)(void* handle);
|
||||
/* These will be created as static functions at the end of the
|
||||
* _source.c and must be declared there too.
|
||||
*/
|
||||
extern "Python" {
|
||||
int python_callback(void* handle, int revents);
|
||||
void python_handle_error(void* handle, int revents);
|
||||
void python_stop(void* handle);
|
||||
void python_check_callback(struct ev_loop*, void*, int);
|
||||
void python_prepare_callback(struct ev_loop*, void*, int);
|
||||
|
||||
// libev specific
|
||||
void _syserr_cb(char*);
|
||||
}
|
||||
/*
|
||||
* We use a single C callback for every watcher type, which in turn calls the
|
||||
* Python callbacks. The ev_watcher pointer type can be used for every watcher type
|
||||
@@ -224,3 +237,7 @@ static void (*python_stop)(void* handle);
|
||||
* object.
|
||||
*/
|
||||
static void _gevent_generic_callback(struct ev_loop* loop, struct ev_watcher* watcher, int revents);
|
||||
|
||||
static void gevent_zero_check(struct ev_check* handle);
|
||||
static void gevent_zero_timer(struct ev_timer* handle);
|
||||
static void gevent_zero_prepare(struct ev_prepare* handle);
|
||||
|
||||
@@ -13,9 +13,10 @@ static void
|
||||
_gevent_noop(struct ev_loop *_loop, struct ev_timer *w, int revents) { }
|
||||
|
||||
void (*gevent_noop)(struct ev_loop *, struct ev_timer *, int) = &_gevent_noop;
|
||||
static int (*python_callback)(void* handle, int revents);
|
||||
static void (*python_handle_error)(void* handle, int revents);
|
||||
static void (*python_stop)(void* handle);
|
||||
|
||||
static int python_callback(void* handle, int revents);
|
||||
static void python_handle_error(void* handle, int revents);
|
||||
static void python_stop(void* handle);
|
||||
|
||||
static void _gevent_generic_callback(struct ev_loop* loop,
|
||||
struct ev_watcher* watcher,
|
||||
@@ -30,7 +31,7 @@ static void _gevent_generic_callback(struct ev_loop* loop,
|
||||
// and allowing memory to be freed
|
||||
python_handle_error(handle, revents);
|
||||
break;
|
||||
case 0:
|
||||
case 1:
|
||||
// Code to stop the event. Note that if python_callback
|
||||
// has disposed of the last reference to the handle,
|
||||
// `watcher` could now be invalid/disposed memory!
|
||||
@@ -38,8 +39,31 @@ static void _gevent_generic_callback(struct ev_loop* loop,
|
||||
python_stop(handle);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
assert(cb_result == 1);
|
||||
case 2:
|
||||
// watcher is already stopped and dead, nothing to do.
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr,
|
||||
"WARNING: gevent: Unexpected return value %d from Python callback "
|
||||
"for watcher %p and handle %d\n",
|
||||
cb_result,
|
||||
watcher, handle);
|
||||
// XXX: Possible leaking of resources here? Should we be
|
||||
// closing the watcher?
|
||||
}
|
||||
}
|
||||
|
||||
static void gevent_zero_timer(struct ev_timer* handle)
|
||||
{
|
||||
memset(handle, 0, sizeof(struct ev_timer));
|
||||
}
|
||||
|
||||
static void gevent_zero_check(struct ev_check* handle)
|
||||
{
|
||||
memset(handle, 0, sizeof(struct ev_check));
|
||||
}
|
||||
|
||||
static void gevent_zero_prepare(struct ev_prepare* handle)
|
||||
{
|
||||
memset(handle, 0, sizeof(struct ev_prepare));
|
||||
}
|
||||
|
||||
@@ -1,42 +1,29 @@
|
||||
/* Copyright (c) 2011-2012 Denis Bilenko. See LICENSE for details. */
|
||||
#include <stddef.h>
|
||||
#include "Python.h"
|
||||
#include "ev.h"
|
||||
#include "corecext.h"
|
||||
#include "callbacks.h"
|
||||
#ifdef Py_PYTHON_H
|
||||
|
||||
/* the name changes depending on our file layout and --module-name option */
|
||||
#define _GEVENTLOOP struct __pyx_vtabstruct_6gevent_5libev_8corecext_loop
|
||||
#if PY_MAJOR_VERSION >= 3
|
||||
#define PyInt_FromLong PyLong_FromLong
|
||||
#endif
|
||||
|
||||
|
||||
static void gevent_handle_error(struct PyGeventLoopObject* loop, PyObject* context) {
|
||||
PyThreadState *tstate;
|
||||
PyObject *type, *value, *traceback, *result;
|
||||
tstate = PyThreadState_GET();
|
||||
type = tstate->curexc_type;
|
||||
if (!type)
|
||||
return;
|
||||
value = tstate->curexc_value;
|
||||
traceback = tstate->curexc_traceback;
|
||||
if (!value) value = Py_None;
|
||||
if (!traceback) traceback = Py_None;
|
||||
|
||||
Py_INCREF(type);
|
||||
Py_INCREF(value);
|
||||
Py_INCREF(traceback);
|
||||
|
||||
PyErr_Clear();
|
||||
|
||||
result = ((_GEVENTLOOP *)loop->__pyx_vtab)->handle_error(loop, context, type, value, traceback, 0);
|
||||
|
||||
if (result) {
|
||||
Py_DECREF(result);
|
||||
}
|
||||
else {
|
||||
PyErr_Print();
|
||||
PyErr_Clear();
|
||||
}
|
||||
|
||||
Py_DECREF(type);
|
||||
Py_DECREF(value);
|
||||
Py_DECREF(traceback);
|
||||
}
|
||||
#ifndef CYTHON_INLINE
|
||||
#if defined(__clang__)
|
||||
#define CYTHON_INLINE __inline__ __attribute__ ((__unused__))
|
||||
#elif defined(__GNUC__)
|
||||
#define CYTHON_INLINE __inline__
|
||||
#elif defined(_MSC_VER)
|
||||
#define CYTHON_INLINE __inline
|
||||
#elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
|
||||
#define CYTHON_INLINE inline
|
||||
#else
|
||||
#define CYTHON_INLINE
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
static CYTHON_INLINE void gevent_check_signals(struct PyGeventLoopObject* loop) {
|
||||
@@ -69,7 +56,7 @@ static void gevent_stop(PyObject* watcher, struct PyGeventLoopObject* loop) {
|
||||
error = 1;
|
||||
method = PyObject_GetAttrString(watcher, "stop");
|
||||
if (method) {
|
||||
result = PyObject_Call(method, __pyx_empty_tuple, NULL);
|
||||
result = PyObject_Call(method, _empty_tuple, NULL);
|
||||
if (result) {
|
||||
Py_DECREF(result);
|
||||
error = 0;
|
||||
@@ -94,7 +81,7 @@ static void gevent_callback(struct PyGeventLoopObject* loop, PyObject* callback,
|
||||
Py_INCREF(watcher);
|
||||
gevent_check_signals(loop);
|
||||
if (args == Py_None) {
|
||||
args = __pyx_empty_tuple;
|
||||
args = _empty_tuple;
|
||||
}
|
||||
length = PyTuple_Size(args);
|
||||
if (length < 0) {
|
||||
@@ -143,7 +130,7 @@ end:
|
||||
}
|
||||
|
||||
|
||||
static void gevent_call(struct PyGeventLoopObject* loop, struct PyGeventCallbackObject* cb) {
|
||||
void gevent_call(struct PyGeventLoopObject* loop, struct PyGeventCallbackObject* cb) {
|
||||
/* no need for GIL here because it is only called from run_callbacks which already has GIL */
|
||||
PyObject *result, *callback, *args;
|
||||
if (!loop || !cb)
|
||||
@@ -179,11 +166,16 @@ static void gevent_call(struct PyGeventLoopObject* loop, struct PyGeventCallback
|
||||
Py_DECREF(loop);
|
||||
}
|
||||
|
||||
/*
|
||||
* PyGeventWatcherObject is the first member of all the structs, so
|
||||
* it is the same in all of them and they can all safely be cast to
|
||||
* it. We could also use the *data member of the libev watcher objects.
|
||||
*/
|
||||
|
||||
#undef DEFINE_CALLBACK
|
||||
#define DEFINE_CALLBACK(WATCHER_LC, WATCHER_TYPE) \
|
||||
static void gevent_callback_##WATCHER_LC(struct ev_loop *_loop, void *c_watcher, int revents) { \
|
||||
struct PyGevent##WATCHER_TYPE##Object* watcher = GET_OBJECT(PyGevent##WATCHER_TYPE##Object, c_watcher, _watcher); \
|
||||
void gevent_callback_##WATCHER_LC(struct ev_loop *_loop, void *c_watcher, int revents) { \
|
||||
struct PyGeventWatcherObject* watcher = (struct PyGeventWatcherObject*)GET_OBJECT(PyGevent##WATCHER_TYPE##Object, c_watcher, _watcher); \
|
||||
gevent_callback(watcher->loop, watcher->_callback, watcher->args, (PyObject*)watcher, c_watcher, revents); \
|
||||
}
|
||||
|
||||
@@ -191,7 +183,7 @@ static void gevent_call(struct PyGeventLoopObject* loop, struct PyGeventCallback
|
||||
DEFINE_CALLBACKS
|
||||
|
||||
|
||||
static void gevent_run_callbacks(struct ev_loop *_loop, void *watcher, int revents) {
|
||||
void gevent_run_callbacks(struct ev_loop *_loop, void *watcher, int revents) {
|
||||
struct PyGeventLoopObject* loop;
|
||||
PyObject *result;
|
||||
GIL_DECLARE;
|
||||
@@ -199,7 +191,7 @@ static void gevent_run_callbacks(struct ev_loop *_loop, void *watcher, int reven
|
||||
loop = GET_OBJECT(PyGeventLoopObject, watcher, _prepare);
|
||||
Py_INCREF(loop);
|
||||
gevent_check_signals(loop);
|
||||
result = ((_GEVENTLOOP *)loop->__pyx_vtab)->_run_callbacks(loop);
|
||||
result = gevent_loop_run_callbacks(loop);
|
||||
if (result) {
|
||||
Py_DECREF(result);
|
||||
}
|
||||
@@ -211,15 +203,14 @@ static void gevent_run_callbacks(struct ev_loop *_loop, void *watcher, int reven
|
||||
GIL_RELEASE;
|
||||
}
|
||||
|
||||
#if defined(_WIN32)
|
||||
/* This is only used on Win32 */
|
||||
|
||||
static void gevent_periodic_signal_check(struct ev_loop *_loop, void *watcher, int revents) {
|
||||
void gevent_periodic_signal_check(struct ev_loop *_loop, void *watcher, int revents) {
|
||||
GIL_DECLARE;
|
||||
GIL_ENSURE;
|
||||
gevent_check_signals(GET_OBJECT(PyGeventLoopObject, watcher, _periodic_signal_checker));
|
||||
GIL_RELEASE;
|
||||
}
|
||||
|
||||
#endif /* _WIN32 */
|
||||
|
||||
#endif /* Py_PYTHON_H */
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
struct ev_loop;
|
||||
struct PyGeventLoopObject;
|
||||
struct PyGeventCallbackObject;
|
||||
|
||||
#define DEFINE_CALLBACK(WATCHER_LC, WATCHER_TYPE) \
|
||||
static void gevent_callback_##WATCHER_LC(struct ev_loop *, void *, int);
|
||||
void gevent_callback_##WATCHER_LC(struct ev_loop *, void *, int);
|
||||
|
||||
|
||||
#define DEFINE_CALLBACKS0 \
|
||||
@@ -11,33 +15,24 @@
|
||||
DEFINE_CALLBACK(check, Check); \
|
||||
DEFINE_CALLBACK(fork, Fork); \
|
||||
DEFINE_CALLBACK(async, Async); \
|
||||
DEFINE_CALLBACK(stat, Stat);
|
||||
DEFINE_CALLBACK(stat, Stat); \
|
||||
DEFINE_CALLBACK(child, Child);
|
||||
|
||||
|
||||
#ifndef _WIN32
|
||||
|
||||
#define DEFINE_CALLBACKS \
|
||||
DEFINE_CALLBACKS0 \
|
||||
DEFINE_CALLBACK(child, Child)
|
||||
|
||||
#else
|
||||
|
||||
#define DEFINE_CALLBACKS DEFINE_CALLBACKS0
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
DEFINE_CALLBACKS
|
||||
|
||||
|
||||
static void gevent_run_callbacks(struct ev_loop *, void *, int);
|
||||
struct PyGeventLoopObject;
|
||||
static void gevent_handle_error(struct PyGeventLoopObject* loop, PyObject* context);
|
||||
struct PyGeventCallbackObject;
|
||||
static void gevent_call(struct PyGeventLoopObject* loop, struct PyGeventCallbackObject* cb);
|
||||
void gevent_run_callbacks(struct ev_loop *, void *, int);
|
||||
|
||||
#if defined(_WIN32)
|
||||
static void gevent_periodic_signal_check(struct ev_loop *, void *, int);
|
||||
#endif
|
||||
|
||||
static void gevent_noop(struct ev_loop *_loop, void *watcher, int revents) { }
|
||||
|
||||
void gevent_call(struct PyGeventLoopObject* loop, struct PyGeventCallbackObject* cb);
|
||||
|
||||
static void gevent_noop(struct ev_loop *_loop, void *watcher, int revents) {
|
||||
}
|
||||
|
||||
/* Only used on Win32 */
|
||||
void gevent_periodic_signal_check(struct ev_loop *, void *, int);
|
||||
|
||||
22963
python/gevent/libev/corecext.c
Normal file
22963
python/gevent/libev/corecext.c
Normal file
File diff suppressed because it is too large
Load Diff
BIN
python/gevent/libev/corecext.cp36-win32.pyd
Normal file
BIN
python/gevent/libev/corecext.cp36-win32.pyd
Normal file
Binary file not shown.
Binary file not shown.
147
python/gevent/libev/corecext.h
Normal file
147
python/gevent/libev/corecext.h
Normal file
@@ -0,0 +1,147 @@
|
||||
/* Generated by Cython 0.28.5 */
|
||||
|
||||
#ifndef __PYX_HAVE__gevent__libev__corecext
|
||||
#define __PYX_HAVE__gevent__libev__corecext
|
||||
|
||||
struct PyGeventCallbackObject;
|
||||
struct PyGeventLoopObject;
|
||||
struct PyGeventWatcherObject;
|
||||
struct PyGeventIOObject;
|
||||
struct PyGeventTimerObject;
|
||||
struct PyGeventSignalObject;
|
||||
struct PyGeventIdleObject;
|
||||
struct PyGeventPrepareObject;
|
||||
struct PyGeventCheckObject;
|
||||
struct PyGeventForkObject;
|
||||
struct PyGeventAsyncObject;
|
||||
struct PyGeventChildObject;
|
||||
struct PyGeventStatObject;
|
||||
|
||||
struct PyGeventCallbackObject {
|
||||
PyObject_HEAD
|
||||
PyObject *callback;
|
||||
PyObject *args;
|
||||
struct PyGeventCallbackObject *next;
|
||||
};
|
||||
|
||||
struct PyGeventLoopObject {
|
||||
PyObject_HEAD
|
||||
struct __pyx_vtabstruct_6gevent_5libev_8corecext_loop *__pyx_vtab;
|
||||
struct ev_prepare _prepare;
|
||||
struct ev_timer _timer0;
|
||||
struct ev_timer _periodic_signal_checker;
|
||||
PyObject *error_handler;
|
||||
struct ev_loop *_ptr;
|
||||
struct __pyx_obj_6gevent_5libev_8corecext_CallbackFIFO *_callbacks;
|
||||
int starting_timer_may_update_loop_time;
|
||||
int _default;
|
||||
};
|
||||
|
||||
struct PyGeventWatcherObject {
|
||||
PyObject_HEAD
|
||||
struct PyGeventLoopObject *loop;
|
||||
PyObject *_callback;
|
||||
PyObject *args;
|
||||
struct ev_watcher *__pyx___watcher;
|
||||
struct __pyx_t_6gevent_5libev_8corecext_start_and_stop *__pyx___ss;
|
||||
unsigned int _flags;
|
||||
};
|
||||
|
||||
struct PyGeventIOObject {
|
||||
struct PyGeventWatcherObject __pyx_base;
|
||||
struct ev_io _watcher;
|
||||
};
|
||||
|
||||
struct PyGeventTimerObject {
|
||||
struct PyGeventWatcherObject __pyx_base;
|
||||
struct ev_timer _watcher;
|
||||
};
|
||||
|
||||
struct PyGeventSignalObject {
|
||||
struct PyGeventWatcherObject __pyx_base;
|
||||
struct ev_signal _watcher;
|
||||
};
|
||||
|
||||
struct PyGeventIdleObject {
|
||||
struct PyGeventWatcherObject __pyx_base;
|
||||
struct ev_idle _watcher;
|
||||
};
|
||||
|
||||
struct PyGeventPrepareObject {
|
||||
struct PyGeventWatcherObject __pyx_base;
|
||||
struct ev_prepare _watcher;
|
||||
};
|
||||
|
||||
struct PyGeventCheckObject {
|
||||
struct PyGeventWatcherObject __pyx_base;
|
||||
struct ev_check _watcher;
|
||||
};
|
||||
|
||||
struct PyGeventForkObject {
|
||||
struct PyGeventWatcherObject __pyx_base;
|
||||
struct ev_fork _watcher;
|
||||
};
|
||||
|
||||
struct PyGeventAsyncObject {
|
||||
struct PyGeventWatcherObject __pyx_base;
|
||||
struct ev_async _watcher;
|
||||
};
|
||||
|
||||
struct PyGeventChildObject {
|
||||
struct PyGeventWatcherObject __pyx_base;
|
||||
struct ev_child _watcher;
|
||||
};
|
||||
|
||||
struct PyGeventStatObject {
|
||||
struct PyGeventWatcherObject __pyx_base;
|
||||
struct ev_stat _watcher;
|
||||
PyObject *path;
|
||||
PyObject *_paths;
|
||||
};
|
||||
|
||||
#ifndef __PYX_HAVE_API__gevent__libev__corecext
|
||||
|
||||
#ifndef __PYX_EXTERN_C
|
||||
#ifdef __cplusplus
|
||||
#define __PYX_EXTERN_C extern "C"
|
||||
#else
|
||||
#define __PYX_EXTERN_C extern
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef DL_IMPORT
|
||||
#define DL_IMPORT(_T) _T
|
||||
#endif
|
||||
|
||||
__PYX_EXTERN_C DL_IMPORT(PyTypeObject) PyGeventCallback_Type;
|
||||
__PYX_EXTERN_C DL_IMPORT(PyTypeObject) PyGeventLoop_Type;
|
||||
__PYX_EXTERN_C DL_IMPORT(PyTypeObject) PyGeventWatcher_Type;
|
||||
__PYX_EXTERN_C DL_IMPORT(PyTypeObject) PyGeventIO_Type;
|
||||
__PYX_EXTERN_C DL_IMPORT(PyTypeObject) PyGeventTimer_Type;
|
||||
__PYX_EXTERN_C DL_IMPORT(PyTypeObject) PyGeventSignal_Type;
|
||||
__PYX_EXTERN_C DL_IMPORT(PyTypeObject) PyGeventIdle_Type;
|
||||
__PYX_EXTERN_C DL_IMPORT(PyTypeObject) PyGeventPrepare_Type;
|
||||
__PYX_EXTERN_C DL_IMPORT(PyTypeObject) PyGeventCheck_Type;
|
||||
__PYX_EXTERN_C DL_IMPORT(PyTypeObject) PyGeventFork_Type;
|
||||
__PYX_EXTERN_C DL_IMPORT(PyTypeObject) PyGeventAsync_Type;
|
||||
__PYX_EXTERN_C DL_IMPORT(PyTypeObject) PyGeventChild_Type;
|
||||
__PYX_EXTERN_C DL_IMPORT(PyTypeObject) PyGeventStat_Type;
|
||||
|
||||
__PYX_EXTERN_C void gevent_handle_error(struct PyGeventLoopObject *, PyObject *);
|
||||
__PYX_EXTERN_C PyObject *gevent_loop_run_callbacks(struct PyGeventLoopObject *);
|
||||
|
||||
__PYX_EXTERN_C PyObject *GEVENT_CORE_EVENTS;
|
||||
__PYX_EXTERN_C PyObject *_empty_tuple;
|
||||
|
||||
#endif /* !__PYX_HAVE_API__gevent__libev__corecext */
|
||||
|
||||
/* WARNING: the interface of the module init function changed in CPython 3.5. */
|
||||
/* It now returns a PyModuleDef instance instead of a PyModule instance. */
|
||||
|
||||
#if PY_MAJOR_VERSION < 3
|
||||
PyMODINIT_FUNC initcorecext(void);
|
||||
#else
|
||||
PyMODINIT_FUNC PyInit_corecext(void);
|
||||
#endif
|
||||
|
||||
#endif /* !__PYX_HAVE__gevent__libev__corecext */
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,13 +1,42 @@
|
||||
#if defined(LIBEV_EMBED)
|
||||
#include "ev.c"
|
||||
#undef LIBEV_EMBED
|
||||
#define LIBEV_EMBED 1
|
||||
#define gevent_ev_loop_origflags(loop) ((loop)->origflags)
|
||||
#define gevent_ev_loop_sig_pending(loop) ((loop))->sig_pending
|
||||
#define gevent_ev_loop_backend_fd(loop) ((loop))->backend_fd
|
||||
#define gevent_ev_loop_activecnt(loop) ((loop))->activecnt
|
||||
#if EV_USE_SIGNALFD
|
||||
#define gevent_ev_loop_sigfd(loop) ((loop))->sigfd
|
||||
#else
|
||||
#define gevent_ev_loop_sigfd(loop) -1
|
||||
#endif /* !EV_USE_SIGNALFD */
|
||||
#else /* !LIBEV_EMBED */
|
||||
#include "ev.h"
|
||||
|
||||
#define gevent_ev_loop_origflags(loop) -1
|
||||
#define gevent_ev_loop_sig_pending(loop) -1
|
||||
#define gevent_ev_loop_backend_fd(loop) -1
|
||||
#define gevent_ev_loop_activecnt(loop) -1
|
||||
#define gevent_ev_loop_sigfd(loop) -1
|
||||
|
||||
#define LIBEV_EMBED 0
|
||||
#define EV_USE_FLOOR -1
|
||||
#define EV_USE_CLOCK_SYSCALL -1
|
||||
#define EV_USE_REALTIME -1
|
||||
#define EV_USE_MONOTONIC -1
|
||||
#define EV_USE_NANOSLEEP -1
|
||||
#define EV_USE_INOTIFY -1
|
||||
#define EV_USE_SIGNALFD -1
|
||||
#define EV_USE_EVENTFD -1
|
||||
#define EV_USE_4HEAP -1
|
||||
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <signal.h>
|
||||
#endif
|
||||
#endif /* !_WIN32 */
|
||||
|
||||
#endif
|
||||
#endif /* LIBEV_EMBED */
|
||||
|
||||
#ifndef _WIN32
|
||||
|
||||
@@ -58,9 +87,14 @@ static void gevent_reset_sigchld_handler(void) {
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
#else /* !_WIN32 */
|
||||
|
||||
#define gevent_ev_default_loop ev_default_loop
|
||||
static void gevent_install_sigchld_handler(void) { }
|
||||
static void gevent_reset_sigchld_handler(void) { }
|
||||
|
||||
#endif
|
||||
// Fake child functions that we can link to.
|
||||
static void ev_child_start(struct ev_loop* loop, ev_child* w) {};
|
||||
static void ev_child_stop(struct ev_loop* loop, ev_child* w) {};
|
||||
|
||||
#endif /* _WIN32 */
|
||||
|
||||
@@ -1,18 +1,22 @@
|
||||
# From cython/includes/libc/stdint.pxd
|
||||
# Longness only used for type promotion.
|
||||
# Actual compile time size used for conversions.
|
||||
# We don't have stdint.h on visual studio 9.0 (2008) on windows, sigh,
|
||||
# so go with Py_ssize_t
|
||||
# ssize_t -> intptr_t
|
||||
|
||||
cdef extern from "libev_vfd.h":
|
||||
#ifdef _WIN32
|
||||
#ifdef _WIN64
|
||||
ctypedef long long vfd_socket_t
|
||||
#else
|
||||
ctypedef long vfd_socket_t
|
||||
#endif
|
||||
#else
|
||||
ctypedef int vfd_socket_t
|
||||
#endif
|
||||
long vfd_get(int)
|
||||
# cython doesn't process pre-processor directives, so they
|
||||
# don't matter in this file. It just takes the last definition it sees.
|
||||
ctypedef Py_ssize_t intptr_t
|
||||
ctypedef intptr_t vfd_socket_t
|
||||
|
||||
vfd_socket_t vfd_get(int)
|
||||
int vfd_open(long) except -1
|
||||
void vfd_free(int)
|
||||
|
||||
cdef extern from "libev.h":
|
||||
cdef extern from "libev.h" nogil:
|
||||
int LIBEV_EMBED
|
||||
int EV_MINPRI
|
||||
int EV_MAXPRI
|
||||
|
||||
@@ -87,6 +91,9 @@ cdef extern from "libev.h":
|
||||
int sigfd
|
||||
unsigned int origflags
|
||||
|
||||
struct ev_watcher:
|
||||
void* data;
|
||||
|
||||
struct ev_io:
|
||||
int fd
|
||||
int events
|
||||
@@ -125,6 +132,13 @@ cdef extern from "libev.h":
|
||||
stat prev
|
||||
double interval
|
||||
|
||||
union ev_any_watcher:
|
||||
ev_watcher w
|
||||
ev_io io
|
||||
ev_timer timer
|
||||
ev_signal signal
|
||||
ev_idle idle
|
||||
|
||||
int ev_version_major()
|
||||
int ev_version_minor()
|
||||
|
||||
@@ -132,7 +146,9 @@ cdef extern from "libev.h":
|
||||
unsigned int ev_recommended_backends()
|
||||
unsigned int ev_embeddable_backends()
|
||||
|
||||
double ev_time()
|
||||
ctypedef double ev_tstamp
|
||||
|
||||
ev_tstamp ev_time()
|
||||
void ev_set_syserr_cb(void *)
|
||||
|
||||
int ev_priority(void*)
|
||||
@@ -186,6 +202,8 @@ cdef extern from "libev.h":
|
||||
|
||||
ev_loop* ev_default_loop(unsigned int flags)
|
||||
ev_loop* ev_loop_new(unsigned int flags)
|
||||
void* ev_userdata(ev_loop*)
|
||||
void ev_set_userdata(ev_loop*, void*)
|
||||
void ev_loop_destroy(ev_loop*)
|
||||
void ev_loop_fork(ev_loop*)
|
||||
int ev_is_default_loop(ev_loop*)
|
||||
@@ -195,7 +213,7 @@ cdef extern from "libev.h":
|
||||
void ev_verify(ev_loop*)
|
||||
void ev_run(ev_loop*, int flags) nogil
|
||||
|
||||
double ev_now(ev_loop*)
|
||||
ev_tstamp ev_now(ev_loop*)
|
||||
void ev_now_update(ev_loop*)
|
||||
|
||||
void ev_ref(ev_loop*)
|
||||
@@ -203,6 +221,15 @@ cdef extern from "libev.h":
|
||||
void ev_break(ev_loop*, int)
|
||||
unsigned int ev_pending_count(ev_loop*)
|
||||
|
||||
# gevent extra functions. These are defined in libev.h.
|
||||
ev_loop* gevent_ev_default_loop(unsigned int flags)
|
||||
void gevent_install_sigchld_handler()
|
||||
void gevent_reset_sigchld_handler()
|
||||
|
||||
# These compensate for lack of access to ev_loop struct definition
|
||||
# when LIBEV_EMBED is false.
|
||||
unsigned int gevent_ev_loop_origflags(ev_loop*);
|
||||
int gevent_ev_loop_sig_pending(ev_loop*);
|
||||
int gevent_ev_loop_backend_fd(ev_loop*);
|
||||
int gevent_ev_loop_activecnt(ev_loop*);
|
||||
int gevent_ev_loop_sigfd(ev_loop*);
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
#ifdef _WIN32
|
||||
#ifdef _WIN64
|
||||
typedef PY_LONG_LONG vfd_socket_t;
|
||||
/* see discussion in the libuv directory: this is a SOCKET which is a
|
||||
HANDLE which is a PVOID (even though they're really small ints),
|
||||
and CPython and PyPy return that SOCKET cast to an int from
|
||||
fileno()
|
||||
*/
|
||||
typedef intptr_t vfd_socket_t;
|
||||
#define vfd_socket_object PyLong_FromLongLong
|
||||
#else
|
||||
typedef long vfd_socket_t;
|
||||
#define vfd_socket_object PyInt_FromLong
|
||||
#endif
|
||||
|
||||
#ifdef LIBEV_EMBED
|
||||
/*
|
||||
* If libev on win32 is embedded, then we can use an
|
||||
@@ -53,13 +54,13 @@ static CRITICAL_SECTION* vfd_make_lock()
|
||||
#define VFD_GIL_DECLARE PyGILState_STATE ___save
|
||||
#define VFD_GIL_ENSURE ___save = PyGILState_Ensure()
|
||||
#define VFD_GIL_RELEASE PyGILState_Release(___save)
|
||||
#else
|
||||
#else /* ! WITH_THREAD */
|
||||
#define VFD_LOCK_ENTER
|
||||
#define VFD_LOCK_LEAVE
|
||||
#define VFD_GIL_DECLARE
|
||||
#define VFD_GIL_ENSURE
|
||||
#define VFD_GIL_RELEASE
|
||||
#endif
|
||||
#endif /*_WITH_THREAD */
|
||||
|
||||
/*
|
||||
* Given a virtual fd returns an OS handle or -1
|
||||
@@ -67,7 +68,7 @@ static CRITICAL_SECTION* vfd_make_lock()
|
||||
*/
|
||||
static vfd_socket_t vfd_get(int fd)
|
||||
{
|
||||
int handle = -1;
|
||||
vfd_socket_t handle = -1;
|
||||
VFD_LOCK_ENTER;
|
||||
if (vfd_entries != NULL && fd >= 0 && fd < vfd_num)
|
||||
handle = vfd_entries[fd].handle;
|
||||
@@ -201,7 +202,7 @@ done:
|
||||
#define vfd_free(fd) vfd_free_((fd), 0)
|
||||
#define EV_WIN32_CLOSE_FD(fd) vfd_free_((fd), 1)
|
||||
|
||||
#else
|
||||
#else /* !LIBEV_EMBED */
|
||||
/*
|
||||
* If libev on win32 is not embedded in gevent, then
|
||||
* the only way to map vfds is to use the default of
|
||||
@@ -211,13 +212,14 @@ done:
|
||||
#define vfd_get(fd) _get_osfhandle((fd))
|
||||
#define vfd_open(fd) _open_osfhandle((fd), 0)
|
||||
#define vfd_free(fd)
|
||||
#endif
|
||||
#else
|
||||
#endif /* LIBEV_EMBED */
|
||||
|
||||
#else /* !_WIN32 */
|
||||
/*
|
||||
* On non-win32 platforms vfd_* are noop macros
|
||||
*/
|
||||
typedef int vfd_socket_t;
|
||||
#define vfd_get(fd) (fd)
|
||||
#define vfd_open(fd) ((int)(fd))
|
||||
#define vfd_open(fd) (fd)
|
||||
#define vfd_free(fd)
|
||||
#endif
|
||||
#endif /* _WIN32 */
|
||||
|
||||
282
python/gevent/libev/watcher.py
Normal file
282
python/gevent/libev/watcher.py
Normal file
@@ -0,0 +1,282 @@
|
||||
# pylint: disable=too-many-lines, protected-access, redefined-outer-name, not-callable
|
||||
# pylint: disable=no-member
|
||||
from __future__ import absolute_import, print_function
|
||||
import sys
|
||||
|
||||
from gevent.libev import _corecffi # pylint:disable=no-name-in-module,import-error
|
||||
|
||||
ffi = _corecffi.ffi # pylint:disable=no-member
|
||||
libev = _corecffi.lib # pylint:disable=no-member
|
||||
|
||||
if hasattr(libev, 'vfd_open'):
|
||||
# Must be on windows
|
||||
assert sys.platform.startswith("win"), "vfd functions only needed on windows"
|
||||
vfd_open = libev.vfd_open
|
||||
vfd_free = libev.vfd_free
|
||||
vfd_get = libev.vfd_get
|
||||
else:
|
||||
vfd_open = vfd_free = vfd_get = lambda fd: fd
|
||||
|
||||
#####
|
||||
## NOTE on Windows:
|
||||
# The C implementation does several things specially for Windows;
|
||||
# a possibly incomplete list is:
|
||||
#
|
||||
# - the loop runs a periodic signal checker;
|
||||
# - the io watcher constructor is different and it has a destructor;
|
||||
# - the child watcher is not defined
|
||||
#
|
||||
# The CFFI implementation does none of these things, and so
|
||||
# is possibly NOT FUNCTIONALLY CORRECT on Win32
|
||||
#####
|
||||
_NOARGS = ()
|
||||
_events = [(libev.EV_READ, 'READ'),
|
||||
(libev.EV_WRITE, 'WRITE'),
|
||||
(libev.EV__IOFDSET, '_IOFDSET'),
|
||||
(libev.EV_PERIODIC, 'PERIODIC'),
|
||||
(libev.EV_SIGNAL, 'SIGNAL'),
|
||||
(libev.EV_CHILD, 'CHILD'),
|
||||
(libev.EV_STAT, 'STAT'),
|
||||
(libev.EV_IDLE, 'IDLE'),
|
||||
(libev.EV_PREPARE, 'PREPARE'),
|
||||
(libev.EV_CHECK, 'CHECK'),
|
||||
(libev.EV_EMBED, 'EMBED'),
|
||||
(libev.EV_FORK, 'FORK'),
|
||||
(libev.EV_CLEANUP, 'CLEANUP'),
|
||||
(libev.EV_ASYNC, 'ASYNC'),
|
||||
(libev.EV_CUSTOM, 'CUSTOM'),
|
||||
(libev.EV_ERROR, 'ERROR')]
|
||||
|
||||
from gevent._ffi import watcher as _base
|
||||
|
||||
def _events_to_str(events):
|
||||
return _base.events_to_str(events, _events)
|
||||
|
||||
|
||||
|
||||
class watcher(_base.watcher):
|
||||
_FFI = ffi
|
||||
_LIB = libev
|
||||
_watcher_prefix = 'ev'
|
||||
|
||||
# Flags is a bitfield with the following meaning:
|
||||
# 0000 -> default, referenced (when active)
|
||||
# 0010 -> ev_unref has been called
|
||||
# 0100 -> not referenced; independent of 0010
|
||||
_flags = 0
|
||||
|
||||
def __init__(self, _loop, ref=True, priority=None, args=_base._NOARGS):
|
||||
if ref:
|
||||
self._flags = 0
|
||||
else:
|
||||
self._flags = 4
|
||||
|
||||
super(watcher, self).__init__(_loop, ref=ref, priority=priority, args=args)
|
||||
|
||||
def _watcher_ffi_set_priority(self, priority):
|
||||
libev.ev_set_priority(self._watcher, priority)
|
||||
|
||||
def _watcher_ffi_init(self, args):
|
||||
self._watcher_init(self._watcher,
|
||||
self._watcher_callback,
|
||||
*args)
|
||||
|
||||
def _watcher_ffi_start(self):
|
||||
self._watcher_start(self.loop._ptr, self._watcher)
|
||||
|
||||
def _watcher_ffi_ref(self):
|
||||
if self._flags & 2: # we've told libev we're not referenced
|
||||
self.loop.ref()
|
||||
self._flags &= ~2
|
||||
|
||||
def _watcher_ffi_unref(self):
|
||||
if self._flags & 6 == 4:
|
||||
# We're not referenced, but we haven't told libev that
|
||||
self.loop.unref()
|
||||
self._flags |= 2 # now we've told libev
|
||||
|
||||
def _get_ref(self):
|
||||
return False if self._flags & 4 else True
|
||||
|
||||
def _set_ref(self, value):
|
||||
if value:
|
||||
if not self._flags & 4:
|
||||
return # ref is already True
|
||||
if self._flags & 2: # ev_unref was called, undo
|
||||
self.loop.ref()
|
||||
self._flags &= ~6 # do not want unref, no outstanding unref
|
||||
else:
|
||||
if self._flags & 4:
|
||||
return # ref is already False
|
||||
self._flags |= 4 # we're not referenced
|
||||
if not self._flags & 2 and libev.ev_is_active(self._watcher):
|
||||
# we haven't told libev we're not referenced, but it thinks we're
|
||||
# active so we need to undo that
|
||||
self.loop.unref()
|
||||
self._flags |= 2 # libev knows we're not referenced
|
||||
|
||||
ref = property(_get_ref, _set_ref)
|
||||
|
||||
|
||||
def _get_priority(self):
|
||||
return libev.ev_priority(self._watcher)
|
||||
|
||||
@_base.not_while_active
|
||||
def _set_priority(self, priority):
|
||||
libev.ev_set_priority(self._watcher, priority)
|
||||
|
||||
priority = property(_get_priority, _set_priority)
|
||||
|
||||
def feed(self, revents, callback, *args):
|
||||
self.callback = callback
|
||||
self.args = args or _NOARGS
|
||||
if self._flags & 6 == 4:
|
||||
self.loop.unref()
|
||||
self._flags |= 2
|
||||
libev.ev_feed_event(self.loop._ptr, self._watcher, revents)
|
||||
if not self._flags & 1:
|
||||
# Py_INCREF(<PyObjectPtr>self)
|
||||
self._flags |= 1
|
||||
|
||||
@property
|
||||
def pending(self):
|
||||
return True if self._watcher and libev.ev_is_pending(self._watcher) else False
|
||||
|
||||
|
||||
class io(_base.IoMixin, watcher):
|
||||
|
||||
EVENT_MASK = libev.EV__IOFDSET | libev.EV_READ | libev.EV_WRITE
|
||||
|
||||
def _get_fd(self):
|
||||
return vfd_get(self._watcher.fd)
|
||||
|
||||
@_base.not_while_active
|
||||
def _set_fd(self, fd):
|
||||
vfd = vfd_open(fd)
|
||||
vfd_free(self._watcher.fd)
|
||||
self._watcher_init(self._watcher, self._watcher_callback, vfd, self._watcher.events)
|
||||
|
||||
fd = property(_get_fd, _set_fd)
|
||||
|
||||
def _get_events(self):
|
||||
return self._watcher.events
|
||||
|
||||
@_base.not_while_active
|
||||
def _set_events(self, events):
|
||||
self._watcher_init(self._watcher, self._watcher_callback, self._watcher.fd, events)
|
||||
|
||||
events = property(_get_events, _set_events)
|
||||
|
||||
@property
|
||||
def events_str(self):
|
||||
return _events_to_str(self._watcher.events)
|
||||
|
||||
def _format(self):
|
||||
return ' fd=%s events=%s' % (self.fd, self.events_str)
|
||||
|
||||
|
||||
class timer(_base.TimerMixin, watcher):
|
||||
|
||||
@property
|
||||
def at(self):
|
||||
return self._watcher.at
|
||||
|
||||
def again(self, callback, *args, **kw):
|
||||
# Exactly the same as start(), just with a different initializer
|
||||
# function
|
||||
self._watcher_start = libev.ev_timer_again
|
||||
try:
|
||||
self.start(callback, *args, **kw)
|
||||
finally:
|
||||
del self._watcher_start
|
||||
|
||||
|
||||
class signal(_base.SignalMixin, watcher):
|
||||
pass
|
||||
|
||||
class idle(_base.IdleMixin, watcher):
|
||||
pass
|
||||
|
||||
class prepare(_base.PrepareMixin, watcher):
|
||||
pass
|
||||
|
||||
class check(_base.CheckMixin, watcher):
|
||||
pass
|
||||
|
||||
class fork(_base.ForkMixin, watcher):
|
||||
pass
|
||||
|
||||
|
||||
class async_(_base.AsyncMixin, watcher):
|
||||
|
||||
def send(self):
|
||||
libev.ev_async_send(self.loop._ptr, self._watcher)
|
||||
|
||||
@property
|
||||
def pending(self):
|
||||
return True if libev.ev_async_pending(self._watcher) else False
|
||||
|
||||
# Provide BWC for those that have async
|
||||
locals()['async'] = async_
|
||||
|
||||
class _ClosedWatcher(object):
|
||||
__slots__ = ('pid', 'rpid', 'rstatus')
|
||||
|
||||
def __init__(self, other):
|
||||
self.pid = other.pid
|
||||
self.rpid = other.rpid
|
||||
self.rstatus = other.rstatus
|
||||
|
||||
def __bool__(self):
|
||||
return False
|
||||
__nonzero__ = __bool__
|
||||
|
||||
class child(_base.ChildMixin, watcher):
|
||||
_watcher_type = 'child'
|
||||
|
||||
def close(self):
|
||||
# Capture the properties we defer to our _watcher, because
|
||||
# we're about to discard it.
|
||||
closed_watcher = _ClosedWatcher(self._watcher)
|
||||
super(child, self).close()
|
||||
self._watcher = closed_watcher
|
||||
|
||||
@property
|
||||
def pid(self):
|
||||
return self._watcher.pid
|
||||
|
||||
@property
|
||||
def rpid(self):
|
||||
return self._watcher.rpid
|
||||
|
||||
@rpid.setter
|
||||
def rpid(self, value):
|
||||
self._watcher.rpid = value
|
||||
|
||||
@property
|
||||
def rstatus(self):
|
||||
return self._watcher.rstatus
|
||||
|
||||
@rstatus.setter
|
||||
def rstatus(self, value):
|
||||
self._watcher.rstatus = value
|
||||
|
||||
|
||||
class stat(_base.StatMixin, watcher):
|
||||
_watcher_type = 'stat'
|
||||
|
||||
@property
|
||||
def attr(self):
|
||||
if not self._watcher.attr.st_nlink:
|
||||
return
|
||||
return self._watcher.attr
|
||||
|
||||
@property
|
||||
def prev(self):
|
||||
if not self._watcher.prev.st_nlink:
|
||||
return
|
||||
return self._watcher.prev
|
||||
|
||||
@property
|
||||
def interval(self):
|
||||
return self._watcher.interval
|
||||
Reference in New Issue
Block a user