uv_idle_t* next_idle_handle; \
ares_channel ares_chan; \
int ares_active_sockets; \
- uv_timer_t ares_polling_timer;
+ uv_timer_t ares_polling_timer; \
+ /* Counter to keep track of active tcp streams */ \
+ unsigned int active_tcp_streams; \
+ /* Counter to keep track of active udp streams */ \
+ unsigned int active_udp_streams;
#define UV_REQ_TYPE_PRIVATE \
/* TODO: remove the req suffix */ \
#include "ares/inet_ntop.h"
-static uv_counters_t counters;
-
-
-uv_counters_t* uv_counters() {
- return &counters;
-}
-
-
size_t uv_strlcpy(char* dst, const char* src, size_t size) {
size_t n;
#ifdef _WIN32
-static DWORD __stdcall uv__thread_start(void *ctx_v)
+static UINT __stdcall uv__thread_start(void *ctx_v)
#else
static void *uv__thread_start(void *ctx_v)
#endif
loop->ares_active_sockets = 0;
loop->ares_chan = NULL;
+ loop->active_tcp_streams = 0;
+ loop->active_udp_streams = 0;
+
loop->last_err = uv_ok_;
}
uv_loop_t* uv_loop_new(void) {
- assert(0 && "implement me");
- return NULL;
+ uv_loop_t* loop;
+
+ /* Initialize libuv itself first */
+ uv_once(&uv_init_guard_, uv_init);
+
+ loop = (uv_loop_t*)malloc(sizeof(uv_loop_t));
+
+ if (!loop) {
+ uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
+ }
+
+ uv_loop_init(loop);
+ return loop;
}
void uv_loop_delete(uv_loop_t* loop) {
- assert(0 && "implement me");
+ if (loop != &uv_default_loop_) {
+ free(loop);
+ }
}
/* A zero-size buffer for use by uv_tcp_read */
static char uv_zero_[] = "";
-/* Counter to keep track of active tcp streams */
-static unsigned int active_tcp_streams = 0;
-
-
static int uv__tcp_nodelay(uv_tcp_t* handle, SOCKET socket, int enable) {
if (setsockopt(socket,
IPPROTO_TCP,
handle->close_cb((uv_handle_t*)handle);
}
- active_tcp_streams--;
+ loop->active_tcp_streams--;
uv_unref(loop);
}
* Preallocate a read buffer if the number of active streams is below
* the threshold.
*/
- if (active_tcp_streams < uv_active_tcp_streams_threshold) {
+ if (loop->active_tcp_streams < uv_active_tcp_streams_threshold) {
handle->flags &= ~UV_HANDLE_ZERO_READ;
handle->read_buffer = handle->alloc_cb((uv_handle_t*) handle, 65536);
assert(handle->read_buffer.len > 0);
}
}
- active_tcp_streams++;
+ loop->active_tcp_streams++;
return rv;
}
NULL,
0) == 0) {
uv_connection_init((uv_stream_t*)handle);
- active_tcp_streams++;
+ loop->active_tcp_streams++;
((uv_connect_cb)req->cb)(req, 0);
} else {
uv__set_sys_error(loop, WSAGetLastError());
/* A zero-size buffer for use by uv_udp_read */
static char uv_zero_[] = "";
-/* Counter to keep track of active udp streams */
-static unsigned int active_udp_streams = 0;
-
-
int uv_udp_getsockname(uv_udp_t* handle, struct sockaddr* name,
int* namelen) {
uv_loop_t* loop = handle->loop;
* Preallocate a read buffer if the number of active streams is below
* the threshold.
*/
- if (active_udp_streams < uv_active_udp_streams_threshold) {
+ if (loop->active_udp_streams < uv_active_udp_streams_threshold) {
handle->flags &= ~UV_HANDLE_ZERO_READ;
handle->recv_buffer = handle->alloc_cb((uv_handle_t*) handle, 65536);
}
handle->flags |= UV_HANDLE_READING;
- active_udp_streams++;
+ loop->active_udp_streams++;
handle->recv_cb = recv_cb;
handle->alloc_cb = alloc_cb;
int uv_udp_recv_stop(uv_udp_t* handle) {
if (handle->flags & UV_HANDLE_READING) {
handle->flags &= ~UV_HANDLE_READING;
- active_udp_streams--;
+ handle->loop->active_udp_streams--;
}
return 0;
static char *process_title;
-
+static uv_once_t uv_process_title_init_guard_ = UV_ONCE_INIT;
+static CRITICAL_SECTION process_title_lock;
int uv_utf16_to_utf8(const wchar_t* utf16Buffer, size_t utf16Size,
char* utf8Buffer, size_t utf8Size) {
}
+static void uv_process_title_init(void) {
+ InitializeCriticalSection(&process_title_lock);
+}
+
+
uv_err_t uv_set_process_title(const char* title) {
uv_err_t err;
int length;
wchar_t* title_w = NULL;
+ uv_once(&uv_process_title_init_guard_, uv_process_title_init);
+
/* Find out how big the buffer for the wide-char title must be */
length = uv_utf8_to_utf16(title, NULL, 0);
if (!length) {
goto done;
}
+ EnterCriticalSection(&process_title_lock);
free(process_title);
process_title = strdup(title);
+ LeaveCriticalSection(&process_title_lock);
err = uv_ok_;
uv_err_t uv_get_process_title(char* buffer, size_t size) {
+ uv_once(&uv_process_title_init_guard_, uv_process_title_init);
+
+ EnterCriticalSection(&process_title_lock);
/*
* If the process_title was never read before nor explicitly set,
* we must query it with getConsoleTitleW
assert(process_title);
strncpy(buffer, process_title, size);
+ LeaveCriticalSection(&process_title_lock);
return uv_ok_;
}
uv_fs_t handle;
};
+
+struct thread {
+ uv_thread_t thread_id;
+ volatile int thread_called;
+};
+
static void getaddrinfo_do(struct getaddrinfo_req* req);
static void getaddrinfo_cb(uv_getaddrinfo_t* handle,
int status,
static void fs_cb(uv_fs_t* handle) {
struct fs_req* req = container_of(handle, struct fs_req, handle);
+ uv_fs_req_cleanup(handle);
+
if (--req->counter)
fs_do(req);
}
uv_loop_t* loop;
size_t i;
int r;
+ struct thread* thread = arg;
loop = uv_loop_new();
ASSERT(loop != NULL);
ASSERT(r == 0);
uv_loop_delete(loop);
+ thread->thread_called = 1;
}
* that each "finished" callback is run in its originating thread.
*/
TEST_IMPL(threadpool_multiple_event_loops) {
- uv_thread_t threads[8];
+ struct thread threads[8];
size_t i;
int r;
+ memset(threads, 0, sizeof(threads));
+
for (i = 0; i < ARRAY_SIZE(threads); i++) {
- r = uv_thread_create(threads + i, do_work, NULL);
+ r = uv_thread_create(&threads[i].thread_id, do_work, &threads[i]);
ASSERT(r == 0);
}
for (i = 0; i < ARRAY_SIZE(threads); i++) {
- r = uv_thread_join(threads + i);
+ r = uv_thread_join(&threads[i].thread_id);
ASSERT(r == 0);
+ ASSERT(threads[i].thread_called);
}
return 0;