Windows: Use 32-bit distribution of python
This commit is contained in:
181
python/gevent/libuv/_corecffi_source.c
Normal file
181
python/gevent/libuv/_corecffi_source.c
Normal file
@@ -0,0 +1,181 @@
|
||||
#include <string.h>
|
||||
#include "uv.h"
|
||||
|
||||
typedef void* GeventWatcherObject;
|
||||
|
||||
static int python_callback(GeventWatcherObject handle, int revents);
|
||||
static void python_queue_callback(uv_handle_t* watcher_ptr, int revents);
|
||||
static void python_handle_error(GeventWatcherObject handle, int revents);
|
||||
static void python_stop(GeventWatcherObject handle);
|
||||
|
||||
static void _gevent_noop(void* handle) {}
|
||||
|
||||
static void (*gevent_noop)(void* handle) = &_gevent_noop;
|
||||
|
||||
static void _gevent_generic_callback1_unused(uv_handle_t* watcher, int arg)
|
||||
{
|
||||
// Python code may set this to NULL or even change it
|
||||
// out from under us, which would tend to break things.
|
||||
GeventWatcherObject handle = watcher->data;
|
||||
const int cb_result = python_callback(handle, arg);
|
||||
switch(cb_result) {
|
||||
case -1:
|
||||
// in case of exception, call self.loop.handle_error;
|
||||
// this function is also responsible for stopping the watcher
|
||||
// and allowing memory to be freed
|
||||
python_handle_error(handle, arg);
|
||||
break;
|
||||
case 1:
|
||||
// Code to stop the event IF NEEDED. Note that if python_callback
|
||||
// has disposed of the last reference to the handle,
|
||||
// `watcher` could now be invalid/disposed memory!
|
||||
if (!uv_is_active(watcher)) {
|
||||
if (watcher->data != handle) {
|
||||
if (watcher->data) {
|
||||
// If Python set the data to NULL, then they
|
||||
// expected to be stopped. That's fine.
|
||||
// Otherwise, something weird happened.
|
||||
fprintf(stderr,
|
||||
"WARNING: gevent: watcher handle changed in callback "
|
||||
"from %p to %p for watcher at %p of type %d\n",
|
||||
handle, watcher->data, watcher, watcher->type);
|
||||
// There's a very good chance that the object the
|
||||
// handle referred to has been changed and/or the
|
||||
// old handle has been deallocated (most common), so
|
||||
// passing the old handle will crash. Instead we
|
||||
// pass a sigil to let python distinguish this case.
|
||||
python_stop(NULL);
|
||||
}
|
||||
}
|
||||
else {
|
||||
python_stop(handle);
|
||||
}
|
||||
}
|
||||
break;
|
||||
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 (of type %d) and handle %p\n",
|
||||
cb_result,
|
||||
watcher, watcher->type, handle);
|
||||
// XXX: Possible leaking of resources here? Should we be
|
||||
// closing the watcher?
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void _gevent_generic_callback1(uv_handle_t* watcher, int arg)
|
||||
{
|
||||
python_queue_callback(watcher, arg);
|
||||
}
|
||||
|
||||
static void _gevent_generic_callback0(uv_handle_t* handle)
|
||||
{
|
||||
_gevent_generic_callback1(handle, 0);
|
||||
}
|
||||
|
||||
static void _gevent_async_callback0(uv_async_t* handle)
|
||||
{
|
||||
_gevent_generic_callback0((uv_handle_t*)handle);
|
||||
}
|
||||
|
||||
static void _gevent_timer_callback0(uv_timer_t* handle)
|
||||
{
|
||||
_gevent_generic_callback0((uv_handle_t*)handle);
|
||||
}
|
||||
|
||||
static void _gevent_prepare_callback0(uv_prepare_t* handle)
|
||||
{
|
||||
_gevent_generic_callback0((uv_handle_t*)handle);
|
||||
}
|
||||
|
||||
static void _gevent_check_callback0(uv_check_t* handle)
|
||||
{
|
||||
_gevent_generic_callback0((uv_handle_t*)handle);
|
||||
}
|
||||
|
||||
static void _gevent_idle_callback0(uv_idle_t* handle)
|
||||
{
|
||||
_gevent_generic_callback0((uv_handle_t*)handle);
|
||||
}
|
||||
|
||||
static void _gevent_signal_callback1(uv_signal_t* handle, int signum)
|
||||
{
|
||||
_gevent_generic_callback1((uv_handle_t*)handle, signum);
|
||||
}
|
||||
|
||||
|
||||
static void _gevent_poll_callback2(void* handle, int status, int events)
|
||||
{
|
||||
_gevent_generic_callback1(handle, status < 0 ? status : events);
|
||||
}
|
||||
|
||||
static void _gevent_fs_event_callback3(void* handle, const char* filename, int events, int status)
|
||||
{
|
||||
_gevent_generic_callback1(handle, status < 0 ? status : events);
|
||||
}
|
||||
|
||||
|
||||
typedef struct _gevent_fs_poll_s {
|
||||
uv_fs_poll_t handle;
|
||||
uv_stat_t curr;
|
||||
uv_stat_t prev;
|
||||
} gevent_fs_poll_t;
|
||||
|
||||
static void _gevent_fs_poll_callback3(void* handlep, int status, const uv_stat_t* prev, const uv_stat_t* curr)
|
||||
{
|
||||
// stat pointers are valid for this callback only.
|
||||
// if given, copy them into our structure, where they can be reached
|
||||
// from python, just like libev's watcher does, before calling
|
||||
// the callback.
|
||||
|
||||
// The callback is invoked with status < 0 if path does not exist
|
||||
// or is inaccessible. The watcher is not stopped but your
|
||||
// callback is not called again until something changes (e.g. when
|
||||
// the file is created or the error reason changes).
|
||||
// In that case the fields will be 0 in curr/prev.
|
||||
|
||||
|
||||
gevent_fs_poll_t* handle = (gevent_fs_poll_t*)handlep;
|
||||
assert(status == 0);
|
||||
|
||||
handle->curr = *curr;
|
||||
handle->prev = *prev;
|
||||
|
||||
_gevent_generic_callback1((uv_handle_t*)handle, 0);
|
||||
}
|
||||
|
||||
static void gevent_uv_walk_callback_close(uv_handle_t* handle, void* arg)
|
||||
{
|
||||
if( handle && !uv_is_closing(handle) ) {
|
||||
uv_close(handle, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static void gevent_close_all_handles(uv_loop_t* loop)
|
||||
{
|
||||
uv_walk(loop, gevent_uv_walk_callback_close, NULL);
|
||||
}
|
||||
|
||||
static void gevent_zero_timer(uv_timer_t* handle)
|
||||
{
|
||||
memset(handle, 0, sizeof(uv_timer_t));
|
||||
}
|
||||
|
||||
static void gevent_zero_check(uv_check_t* handle)
|
||||
{
|
||||
memset(handle, 0, sizeof(uv_check_t));
|
||||
}
|
||||
|
||||
static void gevent_zero_prepare(uv_prepare_t* handle)
|
||||
{
|
||||
memset(handle, 0, sizeof(uv_prepare_t));
|
||||
}
|
||||
|
||||
static void gevent_zero_loop(uv_loop_t* handle)
|
||||
{
|
||||
memset(handle, 0, sizeof(uv_loop_t));
|
||||
}
|
||||
Reference in New Issue
Block a user