core.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652
  1. /* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
  2. *
  3. * Permission is hereby granted, free of charge, to any person obtaining a copy
  4. * of this software and associated documentation files (the "Software"), to
  5. * deal in the Software without restriction, including without limitation the
  6. * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  7. * sell copies of the Software, and to permit persons to whom the Software is
  8. * furnished to do so, subject to the following conditions:
  9. *
  10. * The above copyright notice and this permission notice shall be included in
  11. * all copies or substantial portions of the Software.
  12. *
  13. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  14. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  15. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  16. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  17. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  18. * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  19. * IN THE SOFTWARE.
  20. */
  21. #include <assert.h>
  22. #include <errno.h>
  23. #include <limits.h>
  24. #include <stdio.h>
  25. #include <stdlib.h>
  26. #include <string.h>
  27. #if defined(_MSC_VER) || defined(__MINGW64_VERSION_MAJOR)
  28. #include <crtdbg.h>
  29. #endif
  30. #include "uv.h"
  31. #include "internal.h"
  32. #include "queue.h"
  33. #include "handle-inl.h"
  34. #include "heap-inl.h"
  35. #include "req-inl.h"
  36. /* uv_once initialization guards */
  37. static uv_once_t uv_init_guard_ = UV_ONCE_INIT;
  38. #if defined(_DEBUG) && (defined(_MSC_VER) || defined(__MINGW64_VERSION_MAJOR))
  39. /* Our crt debug report handler allows us to temporarily disable asserts
  40. * just for the current thread.
  41. */
  42. UV_THREAD_LOCAL int uv__crt_assert_enabled = TRUE;
  43. static int uv__crt_dbg_report_handler(int report_type, char *message, int *ret_val) {
  44. if (uv__crt_assert_enabled || report_type != _CRT_ASSERT)
  45. return FALSE;
  46. if (ret_val) {
  47. /* Set ret_val to 0 to continue with normal execution.
  48. * Set ret_val to 1 to trigger a breakpoint.
  49. */
  50. if(IsDebuggerPresent())
  51. *ret_val = 1;
  52. else
  53. *ret_val = 0;
  54. }
  55. /* Don't call _CrtDbgReport. */
  56. return TRUE;
  57. }
  58. #else
  59. UV_THREAD_LOCAL int uv__crt_assert_enabled = FALSE;
  60. #endif
  61. #if !defined(__MINGW32__) || __MSVCRT_VERSION__ >= 0x800
  62. static void uv__crt_invalid_parameter_handler(const wchar_t* expression,
  63. const wchar_t* function, const wchar_t * file, unsigned int line,
  64. uintptr_t reserved) {
  65. /* No-op. */
  66. }
  67. #endif
  68. static uv_loop_t** uv__loops;
  69. static int uv__loops_size;
  70. static int uv__loops_capacity;
  71. #define UV__LOOPS_CHUNK_SIZE 8
  72. static uv_mutex_t uv__loops_lock;
  73. static void uv__loops_init(void) {
  74. uv_mutex_init(&uv__loops_lock);
  75. }
  76. static int uv__loops_add(uv_loop_t* loop) {
  77. uv_loop_t** new_loops;
  78. int new_capacity, i;
  79. uv_mutex_lock(&uv__loops_lock);
  80. if (uv__loops_size == uv__loops_capacity) {
  81. new_capacity = uv__loops_capacity + UV__LOOPS_CHUNK_SIZE;
  82. new_loops = uv__realloc(uv__loops, sizeof(uv_loop_t*) * new_capacity);
  83. if (!new_loops)
  84. goto failed_loops_realloc;
  85. uv__loops = new_loops;
  86. for (i = uv__loops_capacity; i < new_capacity; ++i)
  87. uv__loops[i] = NULL;
  88. uv__loops_capacity = new_capacity;
  89. }
  90. uv__loops[uv__loops_size] = loop;
  91. ++uv__loops_size;
  92. uv_mutex_unlock(&uv__loops_lock);
  93. return 0;
  94. failed_loops_realloc:
  95. uv_mutex_unlock(&uv__loops_lock);
  96. return ERROR_OUTOFMEMORY;
  97. }
  98. static void uv__loops_remove(uv_loop_t* loop) {
  99. int loop_index;
  100. int smaller_capacity;
  101. uv_loop_t** new_loops;
  102. uv_mutex_lock(&uv__loops_lock);
  103. for (loop_index = 0; loop_index < uv__loops_size; ++loop_index) {
  104. if (uv__loops[loop_index] == loop)
  105. break;
  106. }
  107. /* If loop was not found, ignore */
  108. if (loop_index == uv__loops_size)
  109. goto loop_removed;
  110. uv__loops[loop_index] = uv__loops[uv__loops_size - 1];
  111. uv__loops[uv__loops_size - 1] = NULL;
  112. --uv__loops_size;
  113. if (uv__loops_size == 0) {
  114. uv__loops_capacity = 0;
  115. uv__free(uv__loops);
  116. uv__loops = NULL;
  117. goto loop_removed;
  118. }
  119. /* If we didn't grow to big skip downsizing */
  120. if (uv__loops_capacity < 4 * UV__LOOPS_CHUNK_SIZE)
  121. goto loop_removed;
  122. /* Downsize only if more than half of buffer is free */
  123. smaller_capacity = uv__loops_capacity / 2;
  124. if (uv__loops_size >= smaller_capacity)
  125. goto loop_removed;
  126. new_loops = uv__realloc(uv__loops, sizeof(uv_loop_t*) * smaller_capacity);
  127. if (!new_loops)
  128. goto loop_removed;
  129. uv__loops = new_loops;
  130. uv__loops_capacity = smaller_capacity;
  131. loop_removed:
  132. uv_mutex_unlock(&uv__loops_lock);
  133. }
  134. void uv__wake_all_loops(void) {
  135. int i;
  136. uv_loop_t* loop;
  137. uv_mutex_lock(&uv__loops_lock);
  138. for (i = 0; i < uv__loops_size; ++i) {
  139. loop = uv__loops[i];
  140. assert(loop);
  141. if (loop->iocp != INVALID_HANDLE_VALUE)
  142. PostQueuedCompletionStatus(loop->iocp, 0, 0, NULL);
  143. }
  144. uv_mutex_unlock(&uv__loops_lock);
  145. }
  146. static void uv_init(void) {
  147. /* Tell Windows that we will handle critical errors. */
  148. SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX |
  149. SEM_NOOPENFILEERRORBOX);
  150. /* Tell the CRT to not exit the application when an invalid parameter is
  151. * passed. The main issue is that invalid FDs will trigger this behavior.
  152. */
  153. #if !defined(__MINGW32__) || __MSVCRT_VERSION__ >= 0x800
  154. _set_invalid_parameter_handler(uv__crt_invalid_parameter_handler);
  155. #endif
  156. /* We also need to setup our debug report handler because some CRT
  157. * functions (eg _get_osfhandle) raise an assert when called with invalid
  158. * FDs even though they return the proper error code in the release build.
  159. */
  160. #if defined(_DEBUG) && (defined(_MSC_VER) || defined(__MINGW64_VERSION_MAJOR))
  161. _CrtSetReportHook(uv__crt_dbg_report_handler);
  162. #endif
  163. /* Initialize tracking of all uv loops */
  164. uv__loops_init();
  165. /* Fetch winapi function pointers. This must be done first because other
  166. * initialization code might need these function pointers to be loaded.
  167. */
  168. uv_winapi_init();
  169. /* Initialize winsock */
  170. uv_winsock_init();
  171. /* Initialize FS */
  172. uv_fs_init();
  173. /* Initialize signal stuff */
  174. uv_signals_init();
  175. /* Initialize console */
  176. uv_console_init();
  177. /* Initialize utilities */
  178. uv__util_init();
  179. /* Initialize system wakeup detection */
  180. uv__init_detect_system_wakeup();
  181. }
  182. int uv_loop_init(uv_loop_t* loop) {
  183. struct heap* timer_heap;
  184. int err;
  185. /* Initialize libuv itself first */
  186. uv__once_init();
  187. /* Create an I/O completion port */
  188. loop->iocp = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 1);
  189. if (loop->iocp == NULL)
  190. return uv_translate_sys_error(GetLastError());
  191. /* To prevent uninitialized memory access, loop->time must be initialized
  192. * to zero before calling uv_update_time for the first time.
  193. */
  194. loop->time = 0;
  195. uv_update_time(loop);
  196. QUEUE_INIT(&loop->wq);
  197. QUEUE_INIT(&loop->handle_queue);
  198. loop->active_reqs.count = 0;
  199. loop->active_handles = 0;
  200. loop->pending_reqs_tail = NULL;
  201. loop->endgame_handles = NULL;
  202. loop->timer_heap = timer_heap = uv__malloc(sizeof(*timer_heap));
  203. if (timer_heap == NULL) {
  204. err = UV_ENOMEM;
  205. goto fail_timers_alloc;
  206. }
  207. heap_init(timer_heap);
  208. loop->check_handles = NULL;
  209. loop->prepare_handles = NULL;
  210. loop->idle_handles = NULL;
  211. loop->next_prepare_handle = NULL;
  212. loop->next_check_handle = NULL;
  213. loop->next_idle_handle = NULL;
  214. memset(&loop->poll_peer_sockets, 0, sizeof loop->poll_peer_sockets);
  215. loop->active_tcp_streams = 0;
  216. loop->active_udp_streams = 0;
  217. loop->timer_counter = 0;
  218. loop->stop_flag = 0;
  219. err = uv_mutex_init(&loop->wq_mutex);
  220. if (err)
  221. goto fail_mutex_init;
  222. err = uv_async_init(loop, &loop->wq_async, uv__work_done);
  223. if (err)
  224. goto fail_async_init;
  225. uv__handle_unref(&loop->wq_async);
  226. loop->wq_async.flags |= UV_HANDLE_INTERNAL;
  227. err = uv__loops_add(loop);
  228. if (err)
  229. goto fail_async_init;
  230. return 0;
  231. fail_async_init:
  232. uv_mutex_destroy(&loop->wq_mutex);
  233. fail_mutex_init:
  234. uv__free(timer_heap);
  235. loop->timer_heap = NULL;
  236. fail_timers_alloc:
  237. CloseHandle(loop->iocp);
  238. loop->iocp = INVALID_HANDLE_VALUE;
  239. return err;
  240. }
  241. void uv_update_time(uv_loop_t* loop) {
  242. uint64_t new_time = uv__hrtime(1000);
  243. assert(new_time >= loop->time);
  244. loop->time = new_time;
  245. }
  246. void uv__once_init(void) {
  247. uv_once(&uv_init_guard_, uv_init);
  248. }
  249. void uv__loop_close(uv_loop_t* loop) {
  250. size_t i;
  251. uv__loops_remove(loop);
  252. /* close the async handle without needing an extra loop iteration */
  253. assert(!loop->wq_async.async_sent);
  254. loop->wq_async.close_cb = NULL;
  255. uv__handle_closing(&loop->wq_async);
  256. uv__handle_close(&loop->wq_async);
  257. for (i = 0; i < ARRAY_SIZE(loop->poll_peer_sockets); i++) {
  258. SOCKET sock = loop->poll_peer_sockets[i];
  259. if (sock != 0 && sock != INVALID_SOCKET)
  260. closesocket(sock);
  261. }
  262. uv_mutex_lock(&loop->wq_mutex);
  263. assert(QUEUE_EMPTY(&loop->wq) && "thread pool work queue not empty!");
  264. assert(!uv__has_active_reqs(loop));
  265. uv_mutex_unlock(&loop->wq_mutex);
  266. uv_mutex_destroy(&loop->wq_mutex);
  267. uv__free(loop->timer_heap);
  268. loop->timer_heap = NULL;
  269. CloseHandle(loop->iocp);
  270. }
  271. int uv__loop_configure(uv_loop_t* loop, uv_loop_option option, va_list ap) {
  272. return UV_ENOSYS;
  273. }
  274. int uv_backend_fd(const uv_loop_t* loop) {
  275. return -1;
  276. }
  277. int uv_loop_fork(uv_loop_t* loop) {
  278. return UV_ENOSYS;
  279. }
  280. int uv_backend_timeout(const uv_loop_t* loop) {
  281. if (loop->stop_flag != 0)
  282. return 0;
  283. if (!uv__has_active_handles(loop) && !uv__has_active_reqs(loop))
  284. return 0;
  285. if (loop->pending_reqs_tail)
  286. return 0;
  287. if (loop->endgame_handles)
  288. return 0;
  289. if (loop->idle_handles)
  290. return 0;
  291. return uv__next_timeout(loop);
  292. }
  293. static void uv__poll_wine(uv_loop_t* loop, DWORD timeout) {
  294. DWORD bytes;
  295. ULONG_PTR key;
  296. OVERLAPPED* overlapped;
  297. uv_req_t* req;
  298. int repeat;
  299. uint64_t timeout_time;
  300. timeout_time = loop->time + timeout;
  301. for (repeat = 0; ; repeat++) {
  302. GetQueuedCompletionStatus(loop->iocp,
  303. &bytes,
  304. &key,
  305. &overlapped,
  306. timeout);
  307. if (overlapped) {
  308. /* Package was dequeued */
  309. req = uv_overlapped_to_req(overlapped);
  310. uv_insert_pending_req(loop, req);
  311. /* Some time might have passed waiting for I/O,
  312. * so update the loop time here.
  313. */
  314. uv_update_time(loop);
  315. } else if (GetLastError() != WAIT_TIMEOUT) {
  316. /* Serious error */
  317. uv_fatal_error(GetLastError(), "GetQueuedCompletionStatus");
  318. } else if (timeout > 0) {
  319. /* GetQueuedCompletionStatus can occasionally return a little early.
  320. * Make sure that the desired timeout target time is reached.
  321. */
  322. uv_update_time(loop);
  323. if (timeout_time > loop->time) {
  324. timeout = (DWORD)(timeout_time - loop->time);
  325. /* The first call to GetQueuedCompletionStatus should return very
  326. * close to the target time and the second should reach it, but
  327. * this is not stated in the documentation. To make sure a busy
  328. * loop cannot happen, the timeout is increased exponentially
  329. * starting on the third round.
  330. */
  331. timeout += repeat ? (1 << (repeat - 1)) : 0;
  332. continue;
  333. }
  334. }
  335. break;
  336. }
  337. }
  338. static void uv__poll(uv_loop_t* loop, DWORD timeout) {
  339. BOOL success;
  340. uv_req_t* req;
  341. OVERLAPPED_ENTRY overlappeds[128];
  342. ULONG count;
  343. ULONG i;
  344. int repeat;
  345. uint64_t timeout_time;
  346. timeout_time = loop->time + timeout;
  347. for (repeat = 0; ; repeat++) {
  348. success = GetQueuedCompletionStatusEx(loop->iocp,
  349. overlappeds,
  350. ARRAY_SIZE(overlappeds),
  351. &count,
  352. timeout,
  353. FALSE);
  354. if (success) {
  355. for (i = 0; i < count; i++) {
  356. /* Package was dequeued, but see if it is not a empty package
  357. * meant only to wake us up.
  358. */
  359. if (overlappeds[i].lpOverlapped) {
  360. req = uv_overlapped_to_req(overlappeds[i].lpOverlapped);
  361. uv_insert_pending_req(loop, req);
  362. }
  363. }
  364. /* Some time might have passed waiting for I/O,
  365. * so update the loop time here.
  366. */
  367. uv_update_time(loop);
  368. } else if (GetLastError() != WAIT_TIMEOUT) {
  369. /* Serious error */
  370. uv_fatal_error(GetLastError(), "GetQueuedCompletionStatusEx");
  371. } else if (timeout > 0) {
  372. /* GetQueuedCompletionStatus can occasionally return a little early.
  373. * Make sure that the desired timeout target time is reached.
  374. */
  375. uv_update_time(loop);
  376. if (timeout_time > loop->time) {
  377. timeout = (DWORD)(timeout_time - loop->time);
  378. /* The first call to GetQueuedCompletionStatus should return very
  379. * close to the target time and the second should reach it, but
  380. * this is not stated in the documentation. To make sure a busy
  381. * loop cannot happen, the timeout is increased exponentially
  382. * starting on the third round.
  383. */
  384. timeout += repeat ? (1 << (repeat - 1)) : 0;
  385. continue;
  386. }
  387. }
  388. break;
  389. }
  390. }
  391. static int uv__loop_alive(const uv_loop_t* loop) {
  392. return uv__has_active_handles(loop) ||
  393. uv__has_active_reqs(loop) ||
  394. loop->endgame_handles != NULL;
  395. }
  396. int uv_loop_alive(const uv_loop_t* loop) {
  397. return uv__loop_alive(loop);
  398. }
  399. int uv_run(uv_loop_t *loop, uv_run_mode mode) {
  400. DWORD timeout;
  401. int r;
  402. int ran_pending;
  403. r = uv__loop_alive(loop);
  404. if (!r)
  405. uv_update_time(loop);
  406. while (r != 0 && loop->stop_flag == 0) {
  407. uv_update_time(loop);
  408. uv__run_timers(loop);
  409. ran_pending = uv_process_reqs(loop);
  410. uv_idle_invoke(loop);
  411. uv_prepare_invoke(loop);
  412. timeout = 0;
  413. if ((mode == UV_RUN_ONCE && !ran_pending) || mode == UV_RUN_DEFAULT)
  414. timeout = uv_backend_timeout(loop);
  415. if (pGetQueuedCompletionStatusEx)
  416. uv__poll(loop, timeout);
  417. else
  418. uv__poll_wine(loop, timeout);
  419. uv_check_invoke(loop);
  420. uv_process_endgames(loop);
  421. if (mode == UV_RUN_ONCE) {
  422. /* UV_RUN_ONCE implies forward progress: at least one callback must have
  423. * been invoked when it returns. uv__io_poll() can return without doing
  424. * I/O (meaning: no callbacks) when its timeout expires - which means we
  425. * have pending timers that satisfy the forward progress constraint.
  426. *
  427. * UV_RUN_NOWAIT makes no guarantees about progress so it's omitted from
  428. * the check.
  429. */
  430. uv__run_timers(loop);
  431. }
  432. r = uv__loop_alive(loop);
  433. if (mode == UV_RUN_ONCE || mode == UV_RUN_NOWAIT)
  434. break;
  435. }
  436. /* The if statement lets the compiler compile it to a conditional store.
  437. * Avoids dirtying a cache line.
  438. */
  439. if (loop->stop_flag != 0)
  440. loop->stop_flag = 0;
  441. return r;
  442. }
  443. int uv_fileno(const uv_handle_t* handle, uv_os_fd_t* fd) {
  444. uv_os_fd_t fd_out;
  445. switch (handle->type) {
  446. case UV_TCP:
  447. fd_out = (uv_os_fd_t)((uv_tcp_t*) handle)->socket;
  448. break;
  449. case UV_NAMED_PIPE:
  450. fd_out = ((uv_pipe_t*) handle)->handle;
  451. break;
  452. case UV_TTY:
  453. fd_out = ((uv_tty_t*) handle)->handle;
  454. break;
  455. case UV_UDP:
  456. fd_out = (uv_os_fd_t)((uv_udp_t*) handle)->socket;
  457. break;
  458. case UV_POLL:
  459. fd_out = (uv_os_fd_t)((uv_poll_t*) handle)->socket;
  460. break;
  461. default:
  462. return UV_EINVAL;
  463. }
  464. if (uv_is_closing(handle) || fd_out == INVALID_HANDLE_VALUE)
  465. return UV_EBADF;
  466. *fd = fd_out;
  467. return 0;
  468. }
  469. int uv__socket_sockopt(uv_handle_t* handle, int optname, int* value) {
  470. int r;
  471. int len;
  472. SOCKET socket;
  473. if (handle == NULL || value == NULL)
  474. return UV_EINVAL;
  475. if (handle->type == UV_TCP)
  476. socket = ((uv_tcp_t*) handle)->socket;
  477. else if (handle->type == UV_UDP)
  478. socket = ((uv_udp_t*) handle)->socket;
  479. else
  480. return UV_ENOTSUP;
  481. len = sizeof(*value);
  482. if (*value == 0)
  483. r = getsockopt(socket, SOL_SOCKET, optname, (char*) value, &len);
  484. else
  485. r = setsockopt(socket, SOL_SOCKET, optname, (const char*) value, len);
  486. if (r == SOCKET_ERROR)
  487. return uv_translate_sys_error(WSAGetLastError());
  488. return 0;
  489. }
  490. int uv_cpumask_size(void) {
  491. return (int)(sizeof(DWORD_PTR) * 8);
  492. }
  493. int uv__getsockpeername(const uv_handle_t* handle,
  494. uv__peersockfunc func,
  495. struct sockaddr* name,
  496. int* namelen,
  497. int delayed_error) {
  498. int result;
  499. uv_os_fd_t fd;
  500. result = uv_fileno(handle, &fd);
  501. if (result != 0)
  502. return result;
  503. if (delayed_error)
  504. return uv_translate_sys_error(delayed_error);
  505. result = func((SOCKET) fd, name, namelen);
  506. if (result != 0)
  507. return uv_translate_sys_error(WSAGetLastError());
  508. return 0;
  509. }