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

Commit

Permalink
Merge branch 'v0.6'
Browse files Browse the repository at this point in the history
Conflicts:
	src/unix/core.c
	src/win/winapi.h
  • Loading branch information
bnoordhuis committed Dec 2, 2011
2 parents eb6d754 + 60630da commit f5c2a4a
Show file tree
Hide file tree
Showing 34 changed files with 304 additions and 81 deletions.
1 change: 1 addition & 0 deletions .mailmap
Expand Up @@ -9,3 +9,4 @@ Isaac Z. Schlueter <i@izs.me>
Saúl Ibarra Corretgé <saghul@gmail.com>
Yuki OKUMURA <mjt@cltn.org>
Frank Denis <github@pureftpd.org>
Ryan Emery <seebees@gmail.com>
3 changes: 3 additions & 0 deletions AUTHORS
Expand Up @@ -33,3 +33,6 @@ Roman Shtylman <shtylman@gmail.com>
Frank Denis <github@pureftpd.org>
Carter Allen <CarterA@opt-6.com>
Tj Holowaychuk <tj@vision-media.ca>
Shimon Doodkin <helpmepro1@gmail.com>
Ryan Emery <seebees@gmail.com>
Bruce Mitchener <bruce.mitchener@gmail.com>
2 changes: 1 addition & 1 deletion README.md
@@ -1,7 +1,7 @@
# libuv

libuv is a new platform layer for Node. Its purpose is to abstract IOCP on
windows and libev on Unix systems. We intend to eventually contain all
Windows and libev on Unix systems. We intend to eventually contain all
platform differences in this library.

http://nodejs.org/
Expand Down
1 change: 0 additions & 1 deletion config-unix.mk
Expand Up @@ -51,7 +51,6 @@ endif
ifeq (Darwin,$(uname_S))
EV_CONFIG=config_darwin.h
EIO_CONFIG=config_darwin.h
CPPFLAGS += -D__DARWIN_64_BIT_INO_T=1
CPPFLAGS += -Isrc/ares/config_darwin
LINKFLAGS+=-framework CoreServices
OBJS += src/unix/darwin.o
Expand Down
3 changes: 2 additions & 1 deletion include/uv-private/uv-win.h
Expand Up @@ -291,7 +291,8 @@ RB_HEAD(uv_timer_tree_s, uv_timer_s);
LPFN_WSARECVFROM func_wsarecvfrom;

#define uv_pipe_server_fields \
uv_pipe_accept_t accept_reqs[4]; \
int pending_instances; \
uv_pipe_accept_t* accept_reqs; \
uv_pipe_accept_t* pending_accepts;

#define uv_pipe_connection_fields \
Expand Down
36 changes: 24 additions & 12 deletions include/uv.h
Expand Up @@ -106,7 +106,7 @@ typedef intptr_t ssize_t;
XX( 35, ENOSYS, "function not implemented") \
XX( 36, EPIPE, "broken pipe") \
XX( 37, EPROTO, "protocol error") \
XX( 38, EPROTONOSUPPORT, "protocol not suppored") \
XX( 38, EPROTONOSUPPORT, "protocol not supported") \
XX( 39, EPROTOTYPE, "protocol wrong type for socket") \
XX( 40, ETIMEDOUT, "connection timed out") \
XX( 41, ECHARSET, "") \
Expand Down Expand Up @@ -226,7 +226,6 @@ UV_EXTERN int64_t uv_now(uv_loop_t*);
/*
* The status parameter is 0 if the request completed successfully,
* and should be -1 if the request was cancelled or failed.
* For uv_close_cb, -1 means that the handle was closed due to an error.
* Error details can be obtained by calling uv_last_error().
*
* In the case of uv_read_cb the uv_buf_t returned should be freed by the
Expand Down Expand Up @@ -263,7 +262,7 @@ typedef void (*uv_after_work_cb)(uv_work_t* req);
* This will be called repeatedly after the uv_fs_event_t is initialized.
* If uv_fs_event_t was initialized with a directory the filename parameter
* will be a relative path to a file contained in the directory.
* The events paramenter is an ORed mask of enum uv_fs_event elements.
* The events parameter is an ORed mask of enum uv_fs_event elements.
*/
typedef void (*uv_fs_event_cb)(uv_fs_event_t* handle, const char* filename,
int events, int status);
Expand Down Expand Up @@ -315,8 +314,8 @@ UV_PRIVATE_REQ_TYPES
*
* Shutdown the outgoing (write) side of a duplex stream. It waits for
* pending write requests to complete. The handle should refer to a
* initialized stream. req should be an uninitalized shutdown request
* struct. The cb is a called after shutdown is complete.
* initialized stream. req should be an uninitialized shutdown request
* struct. The cb is called after shutdown is complete.
*/
UV_EXTERN int uv_shutdown(uv_shutdown_t* req, uv_stream_t* handle,
uv_shutdown_cb cb);
Expand Down Expand Up @@ -345,8 +344,8 @@ struct uv_handle_s {
};

/*
* Returns 1 if the prepare/check/idle handle has been started, 0 otherwise.
* For other handle types this always returns 1.
* Returns 1 if the prepare/check/idle/timer handle has been started, 0
* otherwise. For other handle types this always returns 1.
*/
UV_EXTERN int uv_is_active(uv_handle_t* handle);

Expand Down Expand Up @@ -524,7 +523,7 @@ UV_EXTERN int uv_tcp_getpeername(uv_tcp_t* handle, struct sockaddr* name,
* uv_tcp_connect, uv_tcp_connect6
* These functions establish IPv4 and IPv6 TCP connections. Provide an
* initialized TCP handle and an uninitialized uv_connect_t*. The callback
* will be made when the connection is estabished.
* will be made when the connection is established.
*/
UV_EXTERN int uv_tcp_connect(uv_connect_t* req, uv_tcp_t* handle,
struct sockaddr_in address, uv_connect_cb cb);
Expand Down Expand Up @@ -788,6 +787,13 @@ UV_EXTERN int uv_pipe_bind(uv_pipe_t* handle, const char* name);
UV_EXTERN void uv_pipe_connect(uv_connect_t* req, uv_pipe_t* handle,
const char* name, uv_connect_cb cb);

/*
* This setting applies to Windows only.
* Set the number of pending pipe instance handles when the pipe server
* is waiting for connections.
*/
UV_EXTERN void uv_pipe_pending_instances(uv_pipe_t* handle, int count);


/*
* uv_prepare_t is a subclass of uv_handle_t.
Expand Down Expand Up @@ -899,7 +905,7 @@ UV_EXTERN int uv_timer_again(uv_timer_t* timer);

/*
* Set the repeat value. Note that if the repeat value is set from a timer
* callback it does not immediately take effect. If the timer was nonrepeating
* callback it does not immediately take effect. If the timer was non-repeating
* before, it will have been stopped. If it was repeating, then the old repeat
* value will have been used to schedule the next timeout.
*/
Expand Down Expand Up @@ -953,7 +959,7 @@ typedef struct uv_process_options_s {
const char* file; /* Path to program to execute. */
/*
* Command line arguments. args[0] should be the path to the program. On
* Windows this uses CreateProcess which concatinates the arguments into a
* Windows this uses CreateProcess which concatenates the arguments into a
* string this can cause some strange errors. See the note at
* windows_verbatim_arguments.
*/
Expand All @@ -977,7 +983,7 @@ typedef struct uv_process_options_s {
/*
* The user should supply pointers to initialized uv_pipe_t structs for
* stdio. This is used to to send or receive input from the subprocess.
* The user is reponsible for calling uv_close on them.
* The user is responsible for calling uv_close on them.
*/
uv_pipe_t* stdin_stream;
uv_pipe_t* stdout_stream;
Expand Down Expand Up @@ -1037,7 +1043,7 @@ UV_EXTERN int uv_queue_work(uv_loop_t* loop, uv_work_t* req,
* uninitialized uv_fs_t object.
*
* uv_fs_req_cleanup() must be called after completion of the uv_fs_
* function to free any internal memory allocations associted with the
* function to free any internal memory allocations associated with the
* request.
*/

Expand Down Expand Up @@ -1229,6 +1235,12 @@ UV_EXTERN int uv_ip6_name(struct sockaddr_in6* src, char* dst, size_t size);
/* Gets the executable path */
UV_EXTERN int uv_exepath(char* buffer, size_t* size);

/* Gets the current working directory */
UV_EXTERN uv_err_t uv_cwd(char* buffer, size_t size);

/* Changes the current working directory */
UV_EXTERN uv_err_t uv_chdir(const char* dir);

/* Gets memory info in bytes */
UV_EXTERN uint64_t uv_get_free_memory(void);
UV_EXTERN uint64_t uv_get_total_memory(void);
Expand Down
40 changes: 40 additions & 0 deletions src/unix/core.c
Expand Up @@ -827,3 +827,43 @@ int uv__cloexec(int fd, int set) {
return 0;
#endif
}


/* TODO move to uv-common.c? */
size_t uv__strlcpy(char* dst, const char* src, size_t size) {
const char *org;

if (size == 0) {
return 0;
}

org = src;
while (--size && *src) {
*dst++ = *src++;
}
*dst = '\0';

return src - org;
}


uv_err_t uv_cwd(char* buffer, size_t size) {
if (!buffer || !size) {
return uv__new_artificial_error(UV_EINVAL);
}

if (getcwd(buffer, size)) {
return uv_ok_;
} else {
return uv__new_sys_error(errno);
}
}


uv_err_t uv_chdir(const char* dir) {
if (chdir(dir) == 0) {
return uv_ok_;
} else {
return uv__new_sys_error(errno);
}
}
5 changes: 5 additions & 0 deletions src/unix/pipe.c
Expand Up @@ -271,3 +271,8 @@ void uv__pipe_accept(EV_P_ ev_io* watcher, int revents) {

errno = saved_errno;
}


void uv_pipe_pending_instances(uv_pipe_t* handle, int count) {
return 0;
}
6 changes: 3 additions & 3 deletions src/win/cares.c
Expand Up @@ -62,7 +62,7 @@ static void CALLBACK uv_ares_socksignal_tp(void* parameter,
/* do not fail if error, thread may run after socket close */
/* The code assumes that c-ares will write all pending data in the */
/* callback, unless the socket would block. We can clear the state here */
/* to avoid unecessary signals. */
/* to avoid unnecessary signals. */
WSAEnumNetworkEvents(sockhandle->sock,
sockhandle->h_event,
&network_events);
Expand Down Expand Up @@ -113,7 +113,7 @@ static void uv_ares_sockstate_cb(void *data, ares_socket_t sock, int read,
if (read == 0 && write == 0) {
/* if read and write are 0, cleanup existing data */
/* The code assumes that c-ares does a callback with read = 0 and */
/* write = 0 when the socket is closed. After we recieve this we stop */
/* write = 0 when the socket is closed. After we receive this we stop */
/* monitoring the socket. */
if (uv_handle_ares != NULL) {
uv_req_t* uv_ares_req;
Expand Down Expand Up @@ -244,7 +244,7 @@ void uv_process_ares_cleanup_req(uv_loop_t* loop, uv_ares_task_t* handle,
}
}
} else {
/* stil busy - repost and try again */
/* still busy - repost and try again */
POST_COMPLETION_FOR_REQ(loop, req);
}
}
Expand Down
16 changes: 7 additions & 9 deletions src/win/core.c
Expand Up @@ -91,7 +91,7 @@ static void uv_loop_init(uv_loop_t* loop) {


static void uv_default_loop_init(void) {
/* Intialize libuv itself first */
/* Initialize libuv itself first */
uv_once(&uv_init_guard_, uv_init);

/* Initialize the main loop */
Expand Down Expand Up @@ -204,21 +204,19 @@ static void uv_poll_ex(uv_loop_t* loop, int block) {
uv_idle_invoke((loop)); \
} \
\
/* Completely flush all pending reqs and endgames. */ \
/* We do even when we just called the idle callbacks because those may */ \
/* have closed handles or started requests that short-circuited. */ \
while ((loop)->pending_reqs_tail || (loop)->endgame_handles) { \
uv_process_endgames((loop)); \
uv_process_reqs((loop)); \
} \
uv_process_reqs((loop)); \
uv_process_endgames((loop)); \
\
if ((loop)->refs <= 0) { \
break; \
} \
\
uv_prepare_invoke((loop)); \
\
poll((loop), (loop)->idle_handles == NULL && (loop)->refs > 0); \
poll((loop), (loop)->idle_handles == NULL && \
(loop)->pending_reqs_tail == NULL && \
(loop)->endgame_handles == NULL && \
(loop)->refs > 0); \
\
uv_check_invoke((loop)); \
}
Expand Down
33 changes: 28 additions & 5 deletions src/win/pipe.c
Expand Up @@ -39,6 +39,8 @@ static const uv_buf_t uv_null_buf_ = { 0, NULL };
/* when the local ends wants to shut it down. */
static const int64_t eof_timeout = 50; /* ms */

static const int default_pending_pipe_instances = 4;

/* IPC protocol flags. */
#define UV_IPC_RAW_DATA 0x0001
#define UV_IPC_UV_STREAM 0x0002
Expand Down Expand Up @@ -249,7 +251,7 @@ void uv_pipe_endgame(uv_loop_t* loop, uv_pipe_t* handle) {
return;
}

/* Run FlushFileBuffers in the thhead pool. */
/* Run FlushFileBuffers in the thread pool. */
result = QueueUserWorkItem(pipe_shutdown_thread_proc,
req,
WT_EXECUTELONGFUNCTION);
Expand Down Expand Up @@ -293,6 +295,12 @@ void uv_pipe_endgame(uv_loop_t* loop, uv_pipe_t* handle) {
}
}

if (handle->flags & UV_HANDLE_PIPESERVER) {
assert(handle->accept_reqs);
free(handle->accept_reqs);
handle->accept_reqs = NULL;
}

/* Remember the state of this flag because the close callback is */
/* allowed to clobber or free the handle's memory */
uv_alloced = handle->flags & UV_HANDLE_UV_ALLOCED;
Expand All @@ -310,6 +318,12 @@ void uv_pipe_endgame(uv_loop_t* loop, uv_pipe_t* handle) {
}


void uv_pipe_pending_instances(uv_pipe_t* handle, int count) {
handle->pending_instances = count;
handle->flags |= UV_HANDLE_PIPESERVER;
}


/* Creates a pipe server. */
int uv_pipe_bind(uv_pipe_t* handle, const char* name) {
uv_loop_t* loop = handle->loop;
Expand All @@ -326,7 +340,17 @@ int uv_pipe_bind(uv_pipe_t* handle, const char* name) {
return -1;
}

for (i = 0; i < COUNTOF(handle->accept_reqs); i++) {
if (!(handle->flags & UV_HANDLE_PIPESERVER)) {
handle->pending_instances = default_pending_pipe_instances;
}

handle->accept_reqs = (uv_pipe_accept_t*)
malloc(sizeof(uv_pipe_accept_t) * handle->pending_instances);
if (!handle->accept_reqs) {
uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
}

for (i = 0; i < handle->pending_instances; i++) {
req = &handle->accept_reqs[i];
uv_req_init(loop, (uv_req_t*) req);
req->type = UV_ACCEPT;
Expand Down Expand Up @@ -537,14 +561,13 @@ void close_pipe(uv_pipe_t* handle, int* status, uv_err_t* err) {
}

if (handle->flags & UV_HANDLE_PIPESERVER) {
for (i = 0; i < COUNTOF(handle->accept_reqs); i++) {
for (i = 0; i < handle->pending_instances; i++) {
pipeHandle = handle->accept_reqs[i].pipeHandle;
if (pipeHandle != INVALID_HANDLE_VALUE) {
CloseHandle(pipeHandle);
handle->accept_reqs[i].pipeHandle = INVALID_HANDLE_VALUE;
}
}

}

if (handle->flags & UV_HANDLE_CONNECTION) {
Expand Down Expand Up @@ -686,7 +709,7 @@ int uv_pipe_listen(uv_pipe_t* handle, int backlog, uv_connection_cb cb) {
/* First pipe handle should have already been created in uv_pipe_bind */
assert(handle->accept_reqs[0].pipeHandle != INVALID_HANDLE_VALUE);

for (i = 0; i < COUNTOF(handle->accept_reqs); i++) {
for (i = 0; i < handle->pending_instances; i++) {
uv_pipe_queue_accept(loop, handle, &handle->accept_reqs[i], i == 0);
}

Expand Down
8 changes: 4 additions & 4 deletions src/win/process.c
Expand Up @@ -254,7 +254,7 @@ static wchar_t* path_search_walk_ext(const wchar_t *dir,
* - CMD does not trim leading/trailing whitespace from path/pathex entries
* nor from the environment variables as a whole.
*
* - When cmd.exe cannot read a directory, it wil just skip it and go on
* - When cmd.exe cannot read a directory, it will just skip it and go on
* searching. However, unlike posix-y systems, it will happily try to run a
* file that is not readable/executable; if the spawn fails it will not
* continue searching.
Expand Down Expand Up @@ -400,7 +400,7 @@ wchar_t* quote_cmd_arg(const wchar_t *source, wchar_t *target) {
}

/*
* Expected intput/output:
* Expected input/output:
* input : hello"world
* output: "hello\"world"
* input : hello""world
Expand Down Expand Up @@ -1018,7 +1018,7 @@ int uv_spawn(uv_loop_t* loop, uv_process_t* process,

} else {
/* CreateProcessW failed, but this failure should be delivered */
/* asynchronously to retain unix compatibility. So pretent spawn */
/* asynchronously to retain unix compatibility. So pretend spawn */
/* succeeded, and start a thread instead that prints an error */
/* to the child's intended stderr. */
process->spawn_errno = GetLastError();
Expand Down Expand Up @@ -1046,7 +1046,7 @@ int uv_spawn(uv_loop_t* loop, uv_process_t* process,
close_child_stdio(process);
} else {
/* We're keeping the handles open, the thread pool is going to have */
/* it's way with them. But at least make them noninheritable. */
/* it's way with them. But at least make them non-inheritable. */
int i;
for (i = 0; i < COUNTOF(process->child_stdio); i++) {
SetHandleInformation(child_stdio[i], HANDLE_FLAG_INHERIT, 0);
Expand Down

0 comments on commit f5c2a4a

Please sign in to comment.