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
022a063d
Commit
022a063d
authored
Apr 07, 2016
by
Jason Madden
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
flesh out remainder of libuv functions and callbacks.
parent
945abc50
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
226 additions
and
19 deletions
+226
-19
src/gevent/libuv/_corecffi_build.py
src/gevent/libuv/_corecffi_build.py
+4
-1
src/gevent/libuv/_corecffi_cdef.c
src/gevent/libuv/_corecffi_cdef.c
+169
-17
src/gevent/libuv/_corecffi_source.c
src/gevent/libuv/_corecffi_source.c
+53
-1
No files found.
src/gevent/libuv/_corecffi_build.py
View file @
022a063d
...
...
@@ -14,6 +14,7 @@ import struct
__all__
=
[]
WIN
=
sys
.
platform
.
startswith
(
'win32'
)
def
system_bits
():
return
struct
.
calcsize
(
'P'
)
*
8
...
...
@@ -40,9 +41,11 @@ _source = read_source('_corecffi_source.c')
_cdef
=
_cdef
.
replace
(
'#define GEVENT_ST_NLINK_T int'
,
''
)
_cdef
=
_cdef
.
replace
(
'#define GEVENT_STRUCT_DONE int'
,
''
)
_cdef
=
_cdef
.
replace
(
'#define GEVENT_UV_OS_SOCK_T int'
,
''
)
_cdef
=
_cdef
.
replace
(
'GEVENT_ST_NLINK_T'
,
st_nlink_type
())
_cdef
=
_cdef
.
replace
(
"GEVENT_STRUCT_DONE _;"
,
'...;'
)
_cdef
=
_cdef
.
replace
(
"GEVENT_UV_OS_SOCK_T"
,
'int'
if
not
WIN
else
'SOCKET'
)
# if sys.platform.startswith('win'):
# # We must have the vfd_open, etc, functions on
...
...
src/gevent/libuv/_corecffi_cdef.c
View file @
022a063d
/* 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
typedef
enum
{
UV_RUN_DEFAULT
=
0
,
...
...
@@ -10,33 +11,91 @@ typedef enum {
enum
uv_poll_event
{
UV_READABLE
=
1
,
UV_WRITABLE
=
2
UV_WRITABLE
=
2
,
/* new in 1.9
UV_DISCONNECT = 4
*/
};
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
};
// handle structs and types
struct
uv_loop_s
{
void
*
data
;
GEVENT_STRUCT_DONE
_
;
};
struct
uv_handle_s
{
struct
uv_loop_s
*
loop
;
void
*
data
;
GEVENT_STRUCT_DONE
_
;
};
struct
uv_idle_s
{
void
*
data
;
GEVENT_STRUCT_DONE
_
;
};
struct
uv_prepare_s
{
void
*
data
;
GEVENT_STRUCT_DONE
_
;
};
struct
uv_timer_s
{
void
*
data
;
GEVENT_STRUCT_DONE
_
;
};
struct
uv_signal_s
{
void
*
data
;
GEVENT_STRUCT_DONE
_
;
};
struct
uv_poll_s
{
void
*
data
;
GEVENT_STRUCT_DONE
_
;
};
struct
uv_check_s
{
void
*
data
;
GEVENT_STRUCT_DONE
_
;
};
struct
uv_async_s
{
void
*
data
;
GEVENT_STRUCT_DONE
_
;
};
struct
uv_fs_event_s
{
void
*
data
;
GEVENT_STRUCT_DONE
_
;
};
struct
uv_fs_poll_s
{
void
*
data
;
GEVENT_STRUCT_DONE
_
;
};
...
...
@@ -48,20 +107,62 @@ 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
;
typedef
void
(
*
uv_walk_cb
)(
uv_handle_t
*
handle
,
void
*
arg
);
// 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_timer_cb
)(
uv_timer_t
*
handle
);
typedef
void
(
*
uv_signal_cb
)(
uv_signal_t
*
handle
,
int
signum
);
typedef
void
(
*
uv_check_cb
)(
uv_check_t
*
handle
);
// 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
();
int
uv_loop_init
(
uv_loop_t
*
loop
);
int
uv_loop_alive
(
const
uv_loop_t
*
loop
);
int
uv_loop_close
(
uv_loop_t
*
loop
);
int
uv_run
(
uv_loop_t
*
,
uv_run_mode
mode
);
void
uv_stop
(
uv_loop_t
*
);
void
uv_walk
(
uv_loop_t
*
loop
,
uv_walk_cb
walk_cb
,
void
*
arg
);
...
...
@@ -100,6 +201,12 @@ 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
);
...
...
@@ -116,25 +223,70 @@ 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.
// 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.
// The socket is set to non-blocking mode.
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
(
uv_loop_t
*
,
uv_fs_poll_t
*
);
int
uv_fs_poll_start
(
uv_fs_poll_t
*
,
uv_fs_poll_cb
,
const
char
*
path
,
unsigned
int
);
int
uv_fs_poll_stop
(
uv_fs_poll_t
*
);
/* 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);
//uv_handle_t *cast_handle(void *handle);
// variables that we fill in. 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.
static
int
(
*
python_callback
)(
void
*
handle
,
int
revents
);
static
void
(
*
python_handle_error
)(
void
*
handle
,
int
revents
);
static
void
(
*
python_stop
)(
void
*
handle
);
/*
* 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
* because they all start with the same members---lib
e
v itself relies on this. Each
* We use a single C callback for every watcher type
that shares the same signature
, which in turn calls the
* Python callbacks. The
uv_handle_t
pointer type can be used for every watcher type
* because they all start with the same members---lib
u
v itself relies on this. Each
* watcher types has a 'void* data' that stores the CFFI handle to the Python watcher
* object.
*/
//static void _gevent_generic_callback(struct ev_loop* loop, struct ev_watcher* watcher, int revents);
static
void
_gevent_generic_callback0
(
uv_handle_t
*
handle
);
// no extra args
static
void
_gevent_generic_callback1
(
uv_handle_t
*
handle
,
int
arg
);
// one extra args. Everything will funnel through this
static
void
_gevent_poll_callback2
(
uv_handle_t
*
handle
,
int
status
,
int
events
);
static
void
_gevent_fs_event_callback3
(
uv_handle_t
*
handle
,
const
char
*
filename
,
int
events
,
int
status
);
static
void
_gevent_fs_poll_callback3
(
uv_handle_t
*
handle
,
int
status
,
const
uv_stat_t
*
prev
,
const
uv_stat_t
*
curr
);
src/gevent/libuv/_corecffi_source.c
View file @
022a063d
#include <uv.h>
#include "uv.h"
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_callback1
(
uv_handle_t
*
watcher
,
int
arg
)
{
void
*
handle
=
watcher
->
data
;
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
0
:
// 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!
if
(
!
uv_is_active
(
watcher
))
{
python_stop
(
handle
);
}
break
;
default:
assert
(
cb_result
==
1
);
// watcher is already stopped and dead, nothing to do.
}
}
static
void
_gevent_generic_callback0
(
uv_handle_t
*
handle
)
{
_gevent_generic_callback1
(
handle
,
0
);
}
static
void
_gevent_poll_callback2
(
uv_handle_t
*
handle
,
int
status
,
int
events
)
{
_gevent_generic_callback1
(
handle
,
status
<
0
?
status
:
events
);
}
static
void
_gevent_fs_event_callback3
(
uv_handle_t
*
handle
,
const
char
*
filename
,
int
events
,
int
status
)
{
_gevent_generic_callback1
(
handle
,
status
<
0
?
status
:
events
);
}
static
void
_gevent_fs_poll_callback3
(
uv_handle_t
*
handle
,
int
status
,
const
uv_stat_t
*
prev
,
const
uv_stat_t
*
curr
)
{
// stat pointers are valid for this callback only.
// Will need a custom callback for this or somehow be able to pass
// copied data up.
}
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