Skip to content
This repository has been archived by the owner on May 4, 2018. It is now read-only.

Commit

Permalink
unix, windows: preliminary signal handler support
Browse files Browse the repository at this point in the history
* a no-op on Windows for now
* only supports the main loop on UNIX (again, for now)
  • Loading branch information
bnoordhuis committed Aug 10, 2012
1 parent 5143d54 commit ee50db6
Show file tree
Hide file tree
Showing 15 changed files with 559 additions and 1 deletion.
1 change: 1 addition & 0 deletions config-unix.mk
Expand Up @@ -37,6 +37,7 @@ OBJS += src/unix/loop-watcher.o
OBJS += src/unix/pipe.o
OBJS += src/unix/poll.o
OBJS += src/unix/process.o
OBJS += src/unix/signal.o
OBJS += src/unix/stream.o
OBJS += src/unix/tcp.o
OBJS += src/unix/thread.o
Expand Down
5 changes: 5 additions & 0 deletions include/uv-private/uv-unix.h
Expand Up @@ -134,6 +134,7 @@ struct uv__io_s {
/* RB_HEAD(uv__timers, uv_timer_s) */ \
struct uv__timers { struct uv_timer_s* rbh_root; } timer_handles; \
uint64_t time; \
void* signal_ctx; \
UV_LOOP_PRIVATE_PLATFORM_FIELDS

#define UV_REQ_BUFSML_SIZE (4)
Expand Down Expand Up @@ -272,6 +273,10 @@ struct uv__io_s {
struct termios orig_termios; \
int mode;

#define UV_SIGNAL_PRIVATE_FIELDS \
ngx_queue_t queue; \
unsigned int signum; \

/* UV_FS_EVENT_PRIVATE_FIELDS */
#if defined(__linux__)

Expand Down
3 changes: 3 additions & 0 deletions include/uv-private/uv-win.h
Expand Up @@ -511,6 +511,9 @@ RB_HEAD(uv_timer_tree_s, uv_timer_s);
wchar_t* dirw; \
char* buffer;

#define UV_SIGNAL_PRIVATE_FIELDS \
/* empty */

int uv_utf16_to_utf8(const wchar_t* utf16Buffer, size_t utf16Size,
char* utf8Buffer, size_t utf8Size);
int uv_utf8_to_utf16(const char* utf8Buffer, wchar_t* utf16Buffer,
Expand Down
27 changes: 27 additions & 0 deletions include/uv.h
Expand Up @@ -146,6 +146,7 @@ typedef enum {
XX(TIMER, timer) \
XX(TTY, tty) \
XX(UDP, udp) \
XX(SIGNAL, signal) \

#define UV_REQ_TYPE_MAP(XX) \
XX(CONNECT, connect) \
Expand Down Expand Up @@ -193,6 +194,7 @@ typedef struct uv_async_s uv_async_t;
typedef struct uv_process_s uv_process_t;
typedef struct uv_fs_event_s uv_fs_event_t;
typedef struct uv_fs_poll_s uv_fs_poll_t;
typedef struct uv_signal_s uv_signal_t;

/* Request types. */
typedef struct uv_req_s uv_req_t;
Expand Down Expand Up @@ -316,6 +318,9 @@ typedef void (*uv_fs_poll_cb)(uv_fs_poll_t* handle,
const uv_statbuf_t* prev,
const uv_statbuf_t* curr);

typedef void (*uv_signal_cb)(uv_signal_t* handle, int signum);


typedef enum {
UV_LEAVE_GROUP = 0,
UV_JOIN_GROUP
Expand Down Expand Up @@ -1567,6 +1572,27 @@ UV_EXTERN int uv_fs_poll_start(uv_fs_poll_t* handle,

UV_EXTERN int uv_fs_poll_stop(uv_fs_poll_t* handle);


/*
* UNIX signal handling on a per-event loop basis. The implementation is not
* ultra efficient so don't go creating a million event loops with a million
* signal watchers.
*
* TODO(bnoordhuis) As of 2012-08-10 only the default event loop supports
* signals. That will be fixed.
*/
struct uv_signal_s {
UV_HANDLE_FIELDS
uv_signal_cb signal_cb;
UV_SIGNAL_PRIVATE_FIELDS
};

/* These functions are no-ops on Windows. */
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);


/*
* Gets load avg
* See: http://en.wikipedia.org/wiki/Load_(computing)
Expand Down Expand Up @@ -1804,6 +1830,7 @@ struct uv_loop_s {
#undef UV_FS_REQ_PRIVATE_FIELDS
#undef UV_WORK_PRIVATE_FIELDS
#undef UV_FS_EVENT_PRIVATE_FIELDS
#undef UV_SIGNAL_PRIVATE_FIELDS
#undef UV_LOOP_PRIVATE_FIELDS
#undef UV_LOOP_PRIVATE_PLATFORM_FIELDS

Expand Down
5 changes: 5 additions & 0 deletions src/unix/core.c
Expand Up @@ -116,6 +116,10 @@ void uv_close(uv_handle_t* handle, uv_close_cb close_cb) {
uv__fs_poll_close((uv_fs_poll_t*)handle);
break;

case UV_SIGNAL:
uv__signal_close((uv_signal_t*)handle);
break;

default:
assert(0);
}
Expand Down Expand Up @@ -143,6 +147,7 @@ static void uv__finish_close(uv_handle_t* handle) {
case UV_FS_EVENT:
case UV_FS_POLL:
case UV_POLL:
case UV_SIGNAL:
break;

case UV_NAMED_PIPE:
Expand Down
4 changes: 4 additions & 0 deletions src/unix/internal.h
Expand Up @@ -153,6 +153,10 @@ int uv_pipe_listen(uv_pipe_t* handle, int backlog, uv_connection_cb cb);
void uv__run_timers(uv_loop_t* loop);
unsigned int uv__next_timeout(uv_loop_t* loop);

/* signal */
void uv__signal_close(uv_signal_t* handle);
void uv__signal_unregister(uv_loop_t* loop);

/* various */
void uv__async_close(uv_async_t* handle);
void uv__check_close(uv_check_t* handle);
Expand Down
8 changes: 7 additions & 1 deletion src/unix/loop.c
Expand Up @@ -44,6 +44,7 @@ int uv__loop_init(uv_loop_t* loop, int default_loop) {
ngx_queue_init(&loop->prepare_handles);
ngx_queue_init(&loop->handle_queue);
loop->closing_handles = NULL;
loop->signal_ctx = NULL;
loop->time = uv_hrtime() / 1000000;
loop->async_pipefd[0] = -1;
loop->async_pipefd[1] = -1;
Expand All @@ -63,16 +64,21 @@ int uv__loop_init(uv_loop_t* loop, int default_loop) {


void uv__loop_delete(uv_loop_t* loop) {
uv__signal_unregister(loop);
ev_loop_destroy(loop->ev);

#if __linux__
if (loop->inotify_fd != -1) {
uv__io_stop(loop, &loop->inotify_read_watcher);
close(loop->inotify_fd);
loop->inotify_fd = -1;
}
#endif

#if HAVE_PORTS_FS
if (loop->fs_fd != -1)
if (loop->fs_fd != -1) {
close(loop->fs_fd);
loop->fs_fd = -1;
}
#endif
}

0 comments on commit ee50db6

Please sign in to comment.