static void uv_default_loop_init(void) { /* Initialize libuv itself first */ uv__once_init(); /* Initialize the main loop */ uv_loop_init(&uv_default_loop_); }
int uv_get_process_title(char* buffer, size_t size) { size_t len; if (buffer == NULL || size == 0) return UV_EINVAL; uv__once_init(); EnterCriticalSection(&process_title_lock); /* * If the process_title was never read before nor explicitly set, * we must query it with getConsoleTitleW */ if (!process_title && uv__get_process_title() == -1) { LeaveCriticalSection(&process_title_lock); return uv_translate_sys_error(GetLastError()); } assert(process_title); len = strlen(process_title) + 1; if (size < len) { LeaveCriticalSection(&process_title_lock); return UV_ENOBUFS; } memcpy(buffer, process_title, len); LeaveCriticalSection(&process_title_lock); return 0; }
int uv_cond_init(uv_cond_t* cond) { uv__once_init(); if (HAVE_CONDVAR_API()) return uv_cond_condvar_init(cond); else return uv_cond_fallback_init(cond); }
int uv_rwlock_init(uv_rwlock_t* rwlock) { uv__once_init(); if (HAVE_SRWLOCK_API()) return uv__rwlock_srwlock_init(rwlock); else return uv__rwlock_fallback_init(rwlock); }
int uv_loop_init(uv_loop_t* loop) { /* Initialize libuv itself first */ uv__once_init(); /* Create an I/O completion port */ loop->iocp = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 1); if (loop->iocp == NULL) return uv_translate_sys_error(GetLastError()); /* To prevent uninitialized memory access, loop->time must be initialized * to zero before calling uv_update_time for the first time. */ loop->time = 0; uv_update_time(loop); QUEUE_INIT(&loop->wq); QUEUE_INIT(&loop->handle_queue); QUEUE_INIT(&loop->active_reqs); loop->active_handles = 0; loop->pending_reqs_tail = NULL; loop->endgame_handles = NULL; RB_INIT(&loop->timers); loop->check_handles = NULL; loop->prepare_handles = NULL; loop->idle_handles = NULL; loop->next_prepare_handle = NULL; loop->next_check_handle = NULL; loop->next_idle_handle = NULL; memset(&loop->poll_peer_sockets, 0, sizeof loop->poll_peer_sockets); loop->active_tcp_streams = 0; loop->active_udp_streams = 0; loop->timer_counter = 0; loop->stop_flag = 0; if (uv_mutex_init(&loop->wq_mutex)) abort(); if (uv_async_init(loop, &loop->wq_async, uv__work_done)) abort(); uv__handle_unref(&loop->wq_async); loop->wq_async.flags |= UV__HANDLE_INTERNAL; return 0; }
uv_loop_t* uv_loop_new(void) { uv_loop_t* loop; /* Initialize libuv itself first */ uv__once_init(); loop = (uv_loop_t*)malloc(sizeof(uv_loop_t)); if (!loop) { uv_fatal_error(ERROR_OUTOFMEMORY, "malloc"); } uv_loop_init(loop); return loop; }
int uv_set_process_title(const char* title) { int err; int length; WCHAR* title_w = NULL; uv__once_init(); /* Find out how big the buffer for the wide-char title must be */ length = uv_utf8_to_utf16(title, NULL, 0); if (!length) { err = GetLastError(); goto done; } /* Convert to wide-char string */ title_w = (WCHAR*)malloc(sizeof(WCHAR) * length); if (!title_w) { uv_fatal_error(ERROR_OUTOFMEMORY, "malloc"); } length = uv_utf8_to_utf16(title, title_w, length); if (!length) { err = GetLastError(); goto done; } /* If the title must be truncated insert a \0 terminator there */ if (length > MAX_TITLE_LENGTH) { title_w[MAX_TITLE_LENGTH - 1] = L'\0'; } if (!SetConsoleTitleW(title_w)) { err = GetLastError(); goto done; } EnterCriticalSection(&process_title_lock); free(process_title); process_title = strdup(title); LeaveCriticalSection(&process_title_lock); err = 0; done: free(title_w); return uv_translate_sys_error(err); }
uv_err_t uv_get_process_title(char* buffer, size_t size) { uv__once_init(); EnterCriticalSection(&process_title_lock); /* * If the process_title was never read before nor explicitly set, * we must query it with getConsoleTitleW */ if (!process_title && uv__get_process_title() == -1) { return uv__new_sys_error(GetLastError()); } assert(process_title); strncpy(buffer, process_title, size); LeaveCriticalSection(&process_title_lock); return uv_ok_; }
uint64_t uv_hrtime(void) { LARGE_INTEGER counter; uv__once_init(); /* If the performance frequency is zero, there's no support. */ if (!hrtime_frequency_) { /* uv__set_sys_error(loop, ERROR_NOT_SUPPORTED); */ return 0; } if (!QueryPerformanceCounter(&counter)) { /* uv__set_sys_error(loop, GetLastError()); */ return 0; } /* Because we have no guarantee about the order of magnitude of the */ /* performance counter frequency, and there may not be much headroom to */ /* multiply by NANOSEC without overflowing, we use 128-bit math instead. */ return ((uint64_t) counter.LowPart * NANOSEC / hrtime_frequency_) + (((uint64_t) counter.HighPart * NANOSEC / hrtime_frequency_) << 32); }
int uv_cpu_info(uv_cpu_info_t** cpu_infos_ptr, int* cpu_count_ptr) { uv_cpu_info_t* cpu_infos; SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION* sppi; DWORD sppi_size; SYSTEM_INFO system_info; DWORD cpu_count, r, i; NTSTATUS status; ULONG result_size; int err; uv_cpu_info_t* cpu_info; cpu_infos = NULL; cpu_count = 0; sppi = NULL; uv__once_init(); GetSystemInfo(&system_info); cpu_count = system_info.dwNumberOfProcessors; cpu_infos = calloc(cpu_count, sizeof *cpu_infos); if (cpu_infos == NULL) { err = ERROR_OUTOFMEMORY; goto error; } sppi_size = cpu_count * sizeof(*sppi); sppi = malloc(sppi_size); if (sppi == NULL) { err = ERROR_OUTOFMEMORY; goto error; } status = pNtQuerySystemInformation(SystemProcessorPerformanceInformation, sppi, sppi_size, &result_size); if (!NT_SUCCESS(status)) { err = pRtlNtStatusToDosError(status); goto error; } assert(result_size == sppi_size); for (i = 0; i < cpu_count; i++) { WCHAR key_name[128]; HKEY processor_key; DWORD cpu_speed; DWORD cpu_speed_size = sizeof(cpu_speed); WCHAR cpu_brand[256]; DWORD cpu_brand_size = sizeof(cpu_brand); size_t len; len = _snwprintf(key_name, ARRAY_SIZE(key_name), L"HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\%d", i); assert(len > 0 && len < ARRAY_SIZE(key_name)); r = RegOpenKeyExW(HKEY_LOCAL_MACHINE, key_name, 0, KEY_QUERY_VALUE, &processor_key); if (r != ERROR_SUCCESS) { err = GetLastError(); goto error; } if (RegQueryValueExW(processor_key, L"~MHz", NULL, NULL, (BYTE*) &cpu_speed, &cpu_speed_size) != ERROR_SUCCESS) { err = GetLastError(); RegCloseKey(processor_key); goto error; } if (RegQueryValueExW(processor_key, L"ProcessorNameString", NULL, NULL, (BYTE*) &cpu_brand, &cpu_brand_size) != ERROR_SUCCESS) { err = GetLastError(); RegCloseKey(processor_key); goto error; } RegCloseKey(processor_key); cpu_info = &cpu_infos[i]; cpu_info->speed = cpu_speed; cpu_info->cpu_times.user = sppi[i].UserTime.QuadPart / 10000; cpu_info->cpu_times.sys = (sppi[i].KernelTime.QuadPart - sppi[i].IdleTime.QuadPart) / 10000; cpu_info->cpu_times.idle = sppi[i].IdleTime.QuadPart / 10000; cpu_info->cpu_times.irq = sppi[i].InterruptTime.QuadPart / 10000; cpu_info->cpu_times.nice = 0; len = WideCharToMultiByte(CP_UTF8, 0, cpu_brand, cpu_brand_size / sizeof(WCHAR), NULL, 0, NULL, NULL); if (len == 0) { err = GetLastError(); goto error; } assert(len > 0); /* Allocate 1 extra byte for the null terminator. */ cpu_info->model = malloc(len + 1); if (cpu_info->model == NULL) { err = ERROR_OUTOFMEMORY; goto error; } if (WideCharToMultiByte(CP_UTF8, 0, cpu_brand, cpu_brand_size / sizeof(WCHAR), cpu_info->model, len, NULL, NULL) == 0) { err = GetLastError(); goto error; } /* Ensure that cpu_info->model is null terminated. */ cpu_info->model[len] = '\0'; } free(sppi); *cpu_count_ptr = cpu_count; *cpu_infos_ptr = cpu_infos; return 0; error: /* This is safe because the cpu_infos array is zeroed on allocation. */ for (i = 0; i < cpu_count; i++) free(cpu_infos[i].model); free(cpu_infos); free(sppi); return uv_translate_sys_error(err); }
uint64_t uv_hrtime(void) { uv__once_init(); return uv__hrtime(UV__NANOSEC); }
uv_err_t uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) { SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION* sppi; DWORD sppi_size; SYSTEM_INFO system_info; DWORD cpu_count, i, r; ULONG result_size; size_t size; uv_err_t err; uv_cpu_info_t* cpu_info; *cpu_infos = NULL; *count = 0; uv__once_init(); GetSystemInfo(&system_info); cpu_count = system_info.dwNumberOfProcessors; size = cpu_count * sizeof(uv_cpu_info_t); *cpu_infos = (uv_cpu_info_t*) malloc(size); if (*cpu_infos == NULL) { err = uv__new_artificial_error(UV_ENOMEM); goto out; } memset(*cpu_infos, 0, size); sppi_size = sizeof(*sppi) * cpu_count; sppi = (SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION*) malloc(sppi_size); if (!sppi) { uv_fatal_error(ERROR_OUTOFMEMORY, "malloc"); } r = pNtQuerySystemInformation(SystemProcessorPerformanceInformation, sppi, sppi_size, &result_size); if (r != ERROR_SUCCESS || result_size != sppi_size) { err = uv__new_sys_error(GetLastError()); goto out; } for (i = 0; i < cpu_count; i++) { WCHAR key_name[128]; HKEY processor_key; DWORD cpu_speed; DWORD cpu_speed_size = sizeof(cpu_speed); WCHAR cpu_brand[256]; DWORD cpu_brand_size = sizeof(cpu_brand); _snwprintf(key_name, ARRAY_SIZE(key_name), L"HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\%d", i); r = RegOpenKeyExW(HKEY_LOCAL_MACHINE, key_name, 0, KEY_QUERY_VALUE, &processor_key); if (r != ERROR_SUCCESS) { err = uv__new_sys_error(GetLastError()); goto out; } if (RegQueryValueExW(processor_key, L"~MHz", NULL, NULL, (BYTE*) &cpu_speed, &cpu_speed_size) != ERROR_SUCCESS) { err = uv__new_sys_error(GetLastError()); RegCloseKey(processor_key); goto out; } if (RegQueryValueExW(processor_key, L"ProcessorNameString", NULL, NULL, (BYTE*) &cpu_brand, &cpu_brand_size) != ERROR_SUCCESS) { err = uv__new_sys_error(GetLastError()); RegCloseKey(processor_key); goto out; } RegCloseKey(processor_key); cpu_info = &(*cpu_infos)[i]; cpu_info->speed = cpu_speed; cpu_info->cpu_times.user = sppi[i].UserTime.QuadPart / 10000; cpu_info->cpu_times.sys = (sppi[i].KernelTime.QuadPart - sppi[i].IdleTime.QuadPart) / 10000; cpu_info->cpu_times.idle = sppi[i].IdleTime.QuadPart / 10000; cpu_info->cpu_times.irq = sppi[i].InterruptTime.QuadPart / 10000; cpu_info->cpu_times.nice = 0; size = uv_utf16_to_utf8(cpu_brand, cpu_brand_size / sizeof(WCHAR), NULL, 0); if (size == 0) { err = uv__new_sys_error(GetLastError()); goto out; } /* Allocate 1 extra byte for the null terminator. */ cpu_info->model = (char*) malloc(size + 1); if (cpu_info->model == NULL) { err = uv__new_artificial_error(UV_ENOMEM); goto out; } if (uv_utf16_to_utf8(cpu_brand, cpu_brand_size / sizeof(WCHAR), cpu_info->model, size) == 0) { err = uv__new_sys_error(GetLastError()); goto out; } /* Ensure that cpu_info->model is null terminated. */ cpu_info->model[size] = '\0'; (*count)++; } err = uv_ok_; out: if (sppi) { free(sppi); } if (err.code != UV_OK && *cpu_infos != NULL) { int i; for (i = 0; i < *count; i++) { /* This is safe because the cpu_infos memory area is zeroed out */ /* immediately after allocating it. */ free((*cpu_infos)[i].model); } free(*cpu_infos); *cpu_infos = NULL; *count = 0; } return err; }
int uv_loop_init(uv_loop_t* loop) { struct heap* timer_heap; int err; /* Initialize libuv itself first */ uv__once_init(); /* Create an I/O completion port */ loop->iocp = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 1); if (loop->iocp == NULL) return uv_translate_sys_error(GetLastError()); /* To prevent uninitialized memory access, loop->time must be initialized * to zero before calling uv_update_time for the first time. */ loop->time = 0; uv_update_time(loop); QUEUE_INIT(&loop->wq); QUEUE_INIT(&loop->handle_queue); loop->active_reqs.count = 0; loop->active_handles = 0; loop->pending_reqs_tail = NULL; loop->endgame_handles = NULL; loop->timer_heap = timer_heap = uv__malloc(sizeof(*timer_heap)); if (timer_heap == NULL) { err = UV_ENOMEM; goto fail_timers_alloc; } heap_init(timer_heap); loop->check_handles = NULL; loop->prepare_handles = NULL; loop->idle_handles = NULL; loop->next_prepare_handle = NULL; loop->next_check_handle = NULL; loop->next_idle_handle = NULL; memset(&loop->poll_peer_sockets, 0, sizeof loop->poll_peer_sockets); loop->active_tcp_streams = 0; loop->active_udp_streams = 0; loop->timer_counter = 0; loop->stop_flag = 0; err = uv_mutex_init(&loop->wq_mutex); if (err) goto fail_mutex_init; err = uv_async_init(loop, &loop->wq_async, uv__work_done); if (err) goto fail_async_init; uv__handle_unref(&loop->wq_async); loop->wq_async.flags |= UV_HANDLE_INTERNAL; err = uv__loops_add(loop); if (err) goto fail_async_init; return 0; fail_async_init: uv_mutex_destroy(&loop->wq_mutex); fail_mutex_init: uv__free(timer_heap); loop->timer_heap = NULL; fail_timers_alloc: CloseHandle(loop->iocp); loop->iocp = INVALID_HANDLE_VALUE; return err; }