You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
394 lines
13 KiB
394 lines
13 KiB
5 years ago
|
/* markers for the CFFI parser. Replaced when the string is read. */
|
||
|
#define GEVENT_STRUCT_DONE int
|
||
|
#define GEVENT_ST_NLINK_T int
|
||
|
#define GEVENT_UV_OS_SOCK_T int
|
||
|
|
||
|
#define UV_EBUSY ...
|
||
|
|
||
|
#define UV_VERSION_MAJOR ...
|
||
|
#define UV_VERSION_MINOR ...
|
||
|
#define UV_VERSION_PATCH ...
|
||
|
|
||
|
typedef enum {
|
||
|
UV_RUN_DEFAULT = 0,
|
||
|
UV_RUN_ONCE,
|
||
|
UV_RUN_NOWAIT
|
||
|
} uv_run_mode;
|
||
|
|
||
|
typedef enum {
|
||
|
UV_UNKNOWN_HANDLE = 0,
|
||
|
UV_ASYNC,
|
||
|
UV_CHECK,
|
||
|
UV_FS_EVENT,
|
||
|
UV_FS_POLL,
|
||
|
UV_HANDLE,
|
||
|
UV_IDLE,
|
||
|
UV_NAMED_PIPE,
|
||
|
UV_POLL,
|
||
|
UV_PREPARE,
|
||
|
UV_PROCESS,
|
||
|
UV_STREAM,
|
||
|
UV_TCP,
|
||
|
UV_TIMER,
|
||
|
UV_TTY,
|
||
|
UV_UDP,
|
||
|
UV_SIGNAL,
|
||
|
UV_FILE,
|
||
|
UV_HANDLE_TYPE_MAX
|
||
|
} uv_handle_type;
|
||
|
|
||
|
enum uv_poll_event {
|
||
|
UV_READABLE = 1,
|
||
|
UV_WRITABLE = 2,
|
||
|
/* new in 1.9 */
|
||
|
UV_DISCONNECT = 4,
|
||
|
/* new in 1.14.0 */
|
||
|
UV_PRIORITIZED = 8,
|
||
|
};
|
||
|
|
||
|
enum uv_fs_event {
|
||
|
UV_RENAME = 1,
|
||
|
UV_CHANGE = 2
|
||
|
};
|
||
|
|
||
|
enum uv_fs_event_flags {
|
||
|
/*
|
||
|
* By default, if the fs event watcher is given a directory name, we will
|
||
|
* watch for all events in that directory. This flags overrides this behavior
|
||
|
* and makes fs_event report only changes to the directory entry itself. This
|
||
|
* flag does not affect individual files watched.
|
||
|
* This flag is currently not implemented yet on any backend.
|
||
|
*/
|
||
|
UV_FS_EVENT_WATCH_ENTRY = 1,
|
||
|
/*
|
||
|
* By default uv_fs_event will try to use a kernel interface such as inotify
|
||
|
* or kqueue to detect events. This may not work on remote filesystems such
|
||
|
* as NFS mounts. This flag makes fs_event fall back to calling stat() on a
|
||
|
* regular interval.
|
||
|
* This flag is currently not implemented yet on any backend.
|
||
|
*/
|
||
|
UV_FS_EVENT_STAT = 2,
|
||
|
/*
|
||
|
* By default, event watcher, when watching directory, is not registering
|
||
|
* (is ignoring) changes in it's subdirectories.
|
||
|
* This flag will override this behaviour on platforms that support it.
|
||
|
*/
|
||
|
UV_FS_EVENT_RECURSIVE = 4
|
||
|
};
|
||
|
|
||
|
const char* uv_strerror(int);
|
||
|
const char* uv_err_name(int);
|
||
|
const char* uv_version_string(void);
|
||
|
const char* uv_handle_type_name(uv_handle_type type);
|
||
|
|
||
|
// handle structs and types
|
||
|
struct uv_loop_s {
|
||
|
void* data;
|
||
|
GEVENT_STRUCT_DONE _;
|
||
|
};
|
||
|
struct uv_handle_s {
|
||
|
struct uv_loop_s* loop;
|
||
|
uv_handle_type type;
|
||
|
void *data;
|
||
|
GEVENT_STRUCT_DONE _;
|
||
|
};
|
||
|
struct uv_idle_s {
|
||
|
struct uv_loop_s* loop;
|
||
|
uv_handle_type type;
|
||
|
void *data;
|
||
|
GEVENT_STRUCT_DONE _;
|
||
|
};
|
||
|
struct uv_prepare_s {
|
||
|
struct uv_loop_s* loop;
|
||
|
uv_handle_type type;
|
||
|
void *data;
|
||
|
GEVENT_STRUCT_DONE _;
|
||
|
};
|
||
|
struct uv_timer_s {
|
||
|
struct uv_loop_s* loop;
|
||
|
uv_handle_type type;
|
||
|
void *data;
|
||
|
GEVENT_STRUCT_DONE _;
|
||
|
};
|
||
|
struct uv_signal_s {
|
||
|
struct uv_loop_s* loop;
|
||
|
uv_handle_type type;
|
||
|
void *data;
|
||
|
GEVENT_STRUCT_DONE _;
|
||
|
};
|
||
|
struct uv_poll_s {
|
||
|
struct uv_loop_s* loop;
|
||
|
uv_handle_type type;
|
||
|
void *data;
|
||
|
GEVENT_STRUCT_DONE _;
|
||
|
};
|
||
|
|
||
|
struct uv_check_s {
|
||
|
struct uv_loop_s* loop;
|
||
|
uv_handle_type type;
|
||
|
void *data;
|
||
|
GEVENT_STRUCT_DONE _;
|
||
|
};
|
||
|
|
||
|
struct uv_async_s {
|
||
|
struct uv_loop_s* loop;
|
||
|
uv_handle_type type;
|
||
|
void *data;
|
||
|
void (*async_cb)(struct uv_async_s *);
|
||
|
GEVENT_STRUCT_DONE _;
|
||
|
};
|
||
|
|
||
|
struct uv_fs_event_s {
|
||
|
struct uv_loop_s* loop;
|
||
|
uv_handle_type type;
|
||
|
void *data;
|
||
|
GEVENT_STRUCT_DONE _;
|
||
|
};
|
||
|
|
||
|
struct uv_fs_poll_s {
|
||
|
struct uv_loop_s* loop;
|
||
|
uv_handle_type type;
|
||
|
void *data;
|
||
|
GEVENT_STRUCT_DONE _;
|
||
|
};
|
||
|
|
||
|
typedef struct uv_loop_s uv_loop_t;
|
||
|
typedef struct uv_handle_s uv_handle_t;
|
||
|
typedef struct uv_idle_s uv_idle_t;
|
||
|
typedef struct uv_prepare_s uv_prepare_t;
|
||
|
typedef struct uv_timer_s uv_timer_t;
|
||
|
typedef struct uv_signal_s uv_signal_t;
|
||
|
typedef struct uv_poll_s uv_poll_t;
|
||
|
typedef struct uv_check_s uv_check_t;
|
||
|
typedef struct uv_async_s uv_async_t;
|
||
|
typedef struct uv_fs_event_s uv_fs_event_t;
|
||
|
typedef struct uv_fs_poll_s uv_fs_poll_t;
|
||
|
|
||
|
|
||
|
size_t uv_handle_size(uv_handle_type);
|
||
|
|
||
|
// callbacks with the same signature
|
||
|
typedef void (*uv_close_cb)(uv_handle_t *handle);
|
||
|
typedef void (*uv_idle_cb)(uv_idle_t *handle);
|
||
|
typedef void (*uv_timer_cb)(uv_timer_t *handle);
|
||
|
typedef void (*uv_check_cb)(uv_check_t* handle);
|
||
|
typedef void (*uv_async_cb)(uv_async_t* handle);
|
||
|
typedef void (*uv_prepare_cb)(uv_prepare_t *handle);
|
||
|
|
||
|
// callbacks with distinct sigs
|
||
|
typedef void (*uv_walk_cb)(uv_handle_t *handle, void *arg);
|
||
|
typedef void (*uv_poll_cb)(uv_poll_t *handle, int status, int events);
|
||
|
typedef void (*uv_signal_cb)(uv_signal_t *handle, int signum);
|
||
|
|
||
|
// Callback passed to uv_fs_event_start() which will be called
|
||
|
// repeatedly after the handle is started. If the handle was started
|
||
|
// with a directory the filename parameter will be a relative path to
|
||
|
// a file contained in the directory. The events parameter is an ORed
|
||
|
// mask of uv_fs_event elements.
|
||
|
typedef void (*uv_fs_event_cb)(uv_fs_event_t* handle, const char* filename, int events, int status);
|
||
|
|
||
|
typedef struct {
|
||
|
long tv_sec;
|
||
|
long tv_nsec;
|
||
|
} uv_timespec_t;
|
||
|
|
||
|
typedef struct {
|
||
|
uint64_t st_dev;
|
||
|
uint64_t st_mode;
|
||
|
uint64_t st_nlink;
|
||
|
uint64_t st_uid;
|
||
|
uint64_t st_gid;
|
||
|
uint64_t st_rdev;
|
||
|
uint64_t st_ino;
|
||
|
uint64_t st_size;
|
||
|
uint64_t st_blksize;
|
||
|
uint64_t st_blocks;
|
||
|
uint64_t st_flags;
|
||
|
uint64_t st_gen;
|
||
|
uv_timespec_t st_atim;
|
||
|
uv_timespec_t st_mtim;
|
||
|
uv_timespec_t st_ctim;
|
||
|
uv_timespec_t st_birthtim;
|
||
|
} uv_stat_t;
|
||
|
|
||
|
typedef void (*uv_fs_poll_cb)(uv_fs_poll_t* handle, int status, const uv_stat_t* prev, const uv_stat_t* curr);
|
||
|
|
||
|
// loop functions
|
||
|
uv_loop_t *uv_default_loop();
|
||
|
uv_loop_t* uv_loop_new(); // not documented; neither is uv_loop_delete
|
||
|
int uv_loop_init(uv_loop_t* loop);
|
||
|
int uv_loop_fork(uv_loop_t* loop);
|
||
|
int uv_loop_alive(const uv_loop_t *loop);
|
||
|
int uv_loop_close(uv_loop_t* loop);
|
||
|
uint64_t uv_backend_timeout(uv_loop_t* loop);
|
||
|
int uv_run(uv_loop_t *, uv_run_mode mode);
|
||
|
int uv_backend_fd(const uv_loop_t* loop);
|
||
|
// The narrative docs for the two time functions say 'const',
|
||
|
// but the header does not.
|
||
|
void uv_update_time(uv_loop_t* loop);
|
||
|
uint64_t uv_now(uv_loop_t* loop);
|
||
|
void uv_stop(uv_loop_t *);
|
||
|
void uv_walk(uv_loop_t *loop, uv_walk_cb walk_cb, void *arg);
|
||
|
|
||
|
// handle functions
|
||
|
// uv_handle_t is the base type for all libuv handle types.
|
||
|
|
||
|
void uv_ref(void *);
|
||
|
void uv_unref(void *);
|
||
|
int uv_has_ref(void *);
|
||
|
void uv_close(void *handle, uv_close_cb close_cb);
|
||
|
int uv_is_active(void *handle);
|
||
|
int uv_is_closing(void *handle);
|
||
|
|
||
|
// idle functions
|
||
|
// Idle handles will run the given callback once per loop iteration, right
|
||
|
// before the uv_prepare_t handles. Note: The notable difference with prepare
|
||
|
// handles is that when there are active idle handles, the loop will perform a
|
||
|
// zero timeout poll instead of blocking for i/o. Warning: Despite the name,
|
||
|
// idle handles will get their callbacks called on every loop iteration, not
|
||
|
// when the loop is actually "idle".
|
||
|
int uv_idle_init(uv_loop_t *, uv_idle_t *idle);
|
||
|
int uv_idle_start(uv_idle_t *idle, uv_idle_cb cb);
|
||
|
int uv_idle_stop(uv_idle_t *idle);
|
||
|
|
||
|
// prepare functions
|
||
|
// Prepare handles will run the given callback once per loop iteration, right
|
||
|
// before polling for i/o.
|
||
|
int uv_prepare_init(uv_loop_t *, uv_prepare_t *prepare);
|
||
|
int uv_prepare_start(uv_prepare_t *prepare, uv_prepare_cb cb);
|
||
|
int uv_prepare_stop(uv_prepare_t *prepare);
|
||
|
|
||
|
// check functions
|
||
|
// Check handles will run the given callback once per loop iteration, right
|
||
|
int uv_check_init(uv_loop_t *, uv_check_t *check);
|
||
|
int uv_check_start(uv_check_t *check, uv_check_cb cb);
|
||
|
int uv_check_stop(uv_check_t *check);
|
||
|
|
||
|
// async functions
|
||
|
// Async handles allow the user to "wakeup" the event loop and get a callback called from another thread.
|
||
|
|
||
|
int uv_async_init(uv_loop_t *, uv_async_t*, uv_async_cb);
|
||
|
int uv_async_send(uv_async_t*);
|
||
|
|
||
|
// timer functions
|
||
|
// Timer handles are used to schedule callbacks to be called in the future.
|
||
|
int uv_timer_init(uv_loop_t *, uv_timer_t *handle);
|
||
|
int uv_timer_start(uv_timer_t *handle, uv_timer_cb cb, uint64_t timeout, uint64_t repeat);
|
||
|
int uv_timer_stop(uv_timer_t *handle);
|
||
|
int uv_timer_again(uv_timer_t *handle);
|
||
|
void uv_timer_set_repeat(uv_timer_t *handle, uint64_t repeat);
|
||
|
uint64_t uv_timer_get_repeat(const uv_timer_t *handle);
|
||
|
|
||
|
// signal functions
|
||
|
// Signal handles implement Unix style signal handling on a per-event loop
|
||
|
// bases.
|
||
|
int uv_signal_init(uv_loop_t *loop, uv_signal_t *handle);
|
||
|
int uv_signal_start(uv_signal_t *handle, uv_signal_cb signal_cb, int signum);
|
||
|
int uv_signal_stop(uv_signal_t *handle);
|
||
|
|
||
|
// poll functions Poll handles are used to watch file descriptors for
|
||
|
// readability and writability, similar to the purpose of poll(2). It
|
||
|
// is not okay to have multiple active poll handles for the same
|
||
|
// socket, this can cause libuv to busyloop or otherwise malfunction.
|
||
|
//
|
||
|
// The purpose of poll handles is to enable integrating external
|
||
|
// libraries that rely on the event loop to signal it about the socket
|
||
|
// status changes, like c-ares or libssh2. Using uv_poll_t for any
|
||
|
// other purpose is not recommended; uv_tcp_t, uv_udp_t, etc. provide
|
||
|
// an implementation that is faster and more scalable than what can be
|
||
|
// achieved with uv_poll_t, especially on Windows.
|
||
|
//
|
||
|
// Note On windows only sockets can be polled with poll handles. On
|
||
|
// Unix any file descriptor that would be accepted by poll(2) can be
|
||
|
// used.
|
||
|
int uv_poll_init(uv_loop_t *loop, uv_poll_t *handle, int fd);
|
||
|
|
||
|
// Initialize the handle using a socket descriptor. On Unix this is
|
||
|
// identical to uv_poll_init(). On windows it takes a SOCKET handle;
|
||
|
// SOCKET handles are another name for HANDLE objects in win32, and
|
||
|
// those are defined as PVOID, even though they are not actually
|
||
|
// pointers (they're small integers). CPython and PyPy both return
|
||
|
// the SOCKET (as cast to an int) from the socket.fileno() method.
|
||
|
// libuv uses ``uv_os_sock_t`` for this type, which is defined as an
|
||
|
// int on unix.
|
||
|
int uv_poll_init_socket(uv_loop_t* loop, uv_poll_t* handle, GEVENT_UV_OS_SOCK_T socket);
|
||
|
int uv_poll_start(uv_poll_t *handle, int events, uv_poll_cb cb);
|
||
|
int uv_poll_stop(uv_poll_t *handle);
|
||
|
|
||
|
// FS Event handles allow the user to monitor a given path for
|
||
|
// changes, for example, if the file was renamed or there was a
|
||
|
// generic change in it. This handle uses the best backend for the job
|
||
|
// on each platform.
|
||
|
//
|
||
|
// Thereas also uv_fs_poll_t that uses stat for filesystems where
|
||
|
// the kernel event isn't available.
|
||
|
int uv_fs_event_init(uv_loop_t*, uv_fs_event_t*);
|
||
|
int uv_fs_event_start(uv_fs_event_t*, uv_fs_event_cb, const char* path, unsigned int flags);
|
||
|
int uv_fs_event_stop(uv_fs_event_t*);
|
||
|
int uv_fs_event_getpath(uv_fs_event_t*, char* buffer, size_t* size);
|
||
|
|
||
|
// FS Poll handles allow the user to monitor a given path for changes.
|
||
|
// Unlike uv_fs_event_t, fs poll handles use stat to detect when a
|
||
|
// file has changed so they can work on file systems where fs event
|
||
|
// handles can't.
|
||
|
//
|
||
|
// This is a closer match to libev.
|
||
|
int uv_fs_poll_init(void*, void*);
|
||
|
int uv_fs_poll_start(void*, uv_fs_poll_cb, const char* path, unsigned int);
|
||
|
int uv_fs_poll_stop(void*);
|
||
|
|
||
|
|
||
|
/* Standard library */
|
||
|
void* memset(void *b, int c, size_t len);
|
||
|
|
||
|
|
||
|
/* gevent callbacks */
|
||
|
// Implemented in Python code as 'def_extern'. In the case of poll callbacks and fs
|
||
|
// callbacks, if *status* is less than 0, it will be passed in the revents
|
||
|
// field. In cases of no extra arguments, revents will be 0.
|
||
|
// These will be created as static functions at the end of the
|
||
|
// _source.c and must be pre-declared at the top of that file if we
|
||
|
// call them
|
||
|
typedef void* GeventWatcherObject;
|
||
|
extern "Python" {
|
||
|
// Standard gevent._ffi.loop callbacks.
|
||
|
int python_callback(GeventWatcherObject handle, int revents);
|
||
|
void python_handle_error(GeventWatcherObject handle, int revents);
|
||
|
void python_stop(GeventWatcherObject handle);
|
||
|
|
||
|
void python_check_callback(uv_check_t* handle);
|
||
|
void python_prepare_callback(uv_prepare_t* handle);
|
||
|
void python_timer0_callback(uv_check_t* handle);
|
||
|
|
||
|
// libuv specific callback
|
||
|
void _uv_close_callback(uv_handle_t* handle);
|
||
|
void python_sigchld_callback(uv_signal_t* handle, int signum);
|
||
|
void python_queue_callback(uv_handle_t* handle, int revents);
|
||
|
}
|
||
|
// A variable we fill in.
|
||
|
static void (*gevent_noop)(void* handle);
|
||
|
|
||
|
static void _gevent_signal_callback1(uv_signal_t* handle, int arg);
|
||
|
static void _gevent_async_callback0(uv_async_t* handle);
|
||
|
static void _gevent_prepare_callback0(uv_prepare_t* handle);
|
||
|
static void _gevent_timer_callback0(uv_timer_t* handle);
|
||
|
static void _gevent_check_callback0(uv_check_t* handle);
|
||
|
static void _gevent_idle_callback0(uv_idle_t* handle);
|
||
|
static void _gevent_poll_callback2(uv_poll_t* handle, int status, int events);
|
||
|
static void _gevent_fs_event_callback3(uv_fs_event_t* handle, const char* filename, int events, int status);
|
||
|
|
||
|
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(uv_fs_poll_t* handle, int status, const uv_stat_t* prev, const uv_stat_t* curr);
|
||
|
|
||
|
static void gevent_uv_walk_callback_close(uv_handle_t* handle, void* arg);
|
||
|
static void gevent_close_all_handles(uv_loop_t* loop);
|
||
|
static void gevent_zero_timer(uv_timer_t* handle);
|
||
|
static void gevent_zero_prepare(uv_prepare_t* handle);
|
||
|
static void gevent_zero_check(uv_check_t* handle);
|
||
|
static void gevent_zero_loop(uv_loop_t* handle);
|