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 
22 #include <assert.h>
23 #include <errno.h>
24 #include <limits.h>
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #if defined(_MSC_VER) || defined(__MINGW64_VERSION_MAJOR)
29 #include <crtdbg.h>
30 #endif
31 
32 #include "uv.h"
33 #include "internal.h"
34 #include "queue.h"
35 #include "handle-inl.h"
36 #include "heap-inl.h"
37 #include "req-inl.h"
38 
39 /* uv_once initialization guards */
40 static uv_once_t uv_init_guard_ = UV_ONCE_INIT;
41 
42 
43 #if defined(_DEBUG) && (defined(_MSC_VER) || defined(__MINGW64_VERSION_MAJOR))
44 /* Our crt debug report handler allows us to temporarily disable asserts
45  * just for the current thread.
46  */
47 
48 UV_THREAD_LOCAL int uv__crt_assert_enabled = TRUE;
49 
uv__crt_dbg_report_handler(int report_type,char * message,int * ret_val)50 static int uv__crt_dbg_report_handler(int report_type, char *message, int *ret_val) {
51   if (uv__crt_assert_enabled || report_type != _CRT_ASSERT)
52     return FALSE;
53 
54   if (ret_val) {
55     /* Set ret_val to 0 to continue with normal execution.
56      * Set ret_val to 1 to trigger a breakpoint.
57     */
58 
59     if(IsDebuggerPresent())
60       *ret_val = 1;
61     else
62       *ret_val = 0;
63   }
64 
65   /* Don't call _CrtDbgReport. */
66   return TRUE;
67 }
68 #else
69 UV_THREAD_LOCAL int uv__crt_assert_enabled = FALSE;
70 #endif
71 
72 
73 #if !defined(__MINGW32__) || __MSVCRT_VERSION__ >= 0x800
uv__crt_invalid_parameter_handler(const wchar_t * expression,const wchar_t * function,const wchar_t * file,unsigned int line,uintptr_t reserved)74 static void uv__crt_invalid_parameter_handler(const wchar_t* expression,
75     const wchar_t* function, const wchar_t * file, unsigned int line,
76     uintptr_t reserved) {
77   /* No-op. */
78 }
79 #endif
80 
81 static uv_loop_t** uv__loops;
82 static int uv__loops_size;
83 static int uv__loops_capacity;
84 #define UV__LOOPS_CHUNK_SIZE 8
85 static uv_mutex_t uv__loops_lock;
86 
uv__loops_init(void)87 static void uv__loops_init(void) {
88   uv_mutex_init(&uv__loops_lock);
89 }
90 
uv__loops_add(uv_loop_t * loop)91 static int uv__loops_add(uv_loop_t* loop) {
92   uv_loop_t** new_loops;
93   int new_capacity, i;
94 
95   uv_mutex_lock(&uv__loops_lock);
96 
97   if (uv__loops_size == uv__loops_capacity) {
98     new_capacity = uv__loops_capacity + UV__LOOPS_CHUNK_SIZE;
99     new_loops = uv__realloc(uv__loops, sizeof(uv_loop_t*) * new_capacity);
100     if (!new_loops)
101       goto failed_loops_realloc;
102     uv__loops = new_loops;
103     for (i = uv__loops_capacity; i < new_capacity; ++i)
104       uv__loops[i] = NULL;
105     uv__loops_capacity = new_capacity;
106   }
107   uv__loops[uv__loops_size] = loop;
108   ++uv__loops_size;
109 
110   uv_mutex_unlock(&uv__loops_lock);
111   return 0;
112 
113 failed_loops_realloc:
114   uv_mutex_unlock(&uv__loops_lock);
115   return ERROR_OUTOFMEMORY;
116 }
117 
uv__loops_remove(uv_loop_t * loop)118 static void uv__loops_remove(uv_loop_t* loop) {
119   int loop_index;
120   int smaller_capacity;
121   uv_loop_t** new_loops;
122 
123   uv_mutex_lock(&uv__loops_lock);
124 
125   for (loop_index = 0; loop_index < uv__loops_size; ++loop_index) {
126     if (uv__loops[loop_index] == loop)
127       break;
128   }
129   /* If loop was not found, ignore */
130   if (loop_index == uv__loops_size)
131     goto loop_removed;
132 
133   uv__loops[loop_index] = uv__loops[uv__loops_size - 1];
134   uv__loops[uv__loops_size - 1] = NULL;
135   --uv__loops_size;
136 
137   if (uv__loops_size == 0) {
138     uv__loops_capacity = 0;
139     uv__free(uv__loops);
140     uv__loops = NULL;
141     goto loop_removed;
142   }
143 
144   /* If we didn't grow to big skip downsizing */
145   if (uv__loops_capacity < 4 * UV__LOOPS_CHUNK_SIZE)
146     goto loop_removed;
147 
148   /* Downsize only if more than half of buffer is free */
149   smaller_capacity = uv__loops_capacity / 2;
150   if (uv__loops_size >= smaller_capacity)
151     goto loop_removed;
152   new_loops = uv__realloc(uv__loops, sizeof(uv_loop_t*) * smaller_capacity);
153   if (!new_loops)
154     goto loop_removed;
155   uv__loops = new_loops;
156   uv__loops_capacity = smaller_capacity;
157 
158 loop_removed:
159   uv_mutex_unlock(&uv__loops_lock);
160 }
161 
uv__wake_all_loops(void)162 void uv__wake_all_loops(void) {
163   int i;
164   uv_loop_t* loop;
165 
166   uv_mutex_lock(&uv__loops_lock);
167   for (i = 0; i < uv__loops_size; ++i) {
168     loop = uv__loops[i];
169     assert(loop);
170     if (loop->iocp != INVALID_HANDLE_VALUE)
171       PostQueuedCompletionStatus(loop->iocp, 0, 0, NULL);
172   }
173   uv_mutex_unlock(&uv__loops_lock);
174 }
175 
uv_init(void)176 static void uv_init(void) {
177   /* Tell Windows that we will handle critical errors. */
178   SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX |
179                SEM_NOOPENFILEERRORBOX);
180 
181   /* Tell the CRT to not exit the application when an invalid parameter is
182    * passed. The main issue is that invalid FDs will trigger this behavior.
183    */
184 #if !defined(__MINGW32__) || __MSVCRT_VERSION__ >= 0x800
185   _set_invalid_parameter_handler(uv__crt_invalid_parameter_handler);
186 #endif
187 
188   /* We also need to setup our debug report handler because some CRT
189    * functions (eg _get_osfhandle) raise an assert when called with invalid
190    * FDs even though they return the proper error code in the release build.
191    */
192 #if defined(_DEBUG) && (defined(_MSC_VER) || defined(__MINGW64_VERSION_MAJOR))
193   _CrtSetReportHook(uv__crt_dbg_report_handler);
194 #endif
195 
196   /* Initialize tracking of all uv loops */
197   uv__loops_init();
198 
199   /* Fetch winapi function pointers. This must be done first because other
200    * initialization code might need these function pointers to be loaded.
201    */
202   uv_winapi_init();
203 
204   /* Initialize winsock */
205   uv_winsock_init();
206 
207   /* Initialize FS */
208   uv_fs_init();
209 
210   /* Initialize signal stuff */
211   uv_signals_init();
212 
213   /* Initialize console */
214   uv_console_init();
215 
216   /* Initialize utilities */
217   uv__util_init();
218 
219   /* Initialize system wakeup detection */
220   uv__init_detect_system_wakeup();
221 }
222 
223 
uv_loop_init(uv_loop_t * loop)224 int uv_loop_init(uv_loop_t* loop) {
225   struct heap* timer_heap;
226   int err;
227 
228   /* Initialize libuv itself first */
229   uv__once_init();
230 
231   /* Create an I/O completion port */
232   loop->iocp = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 1);
233   if (loop->iocp == NULL)
234     return uv_translate_sys_error(GetLastError());
235 
236   /* To prevent uninitialized memory access, loop->time must be initialized
237    * to zero before calling uv_update_time for the first time.
238    */
239   loop->time = 0;
240   uv_update_time(loop);
241 
242   QUEUE_INIT(&loop->wq);
243   QUEUE_INIT(&loop->handle_queue);
244   loop->active_reqs.count = 0;
245   loop->active_handles = 0;
246 
247   loop->pending_reqs_tail = NULL;
248 
249   loop->endgame_handles = NULL;
250 
251   loop->timer_heap = timer_heap = uv__malloc(sizeof(*timer_heap));
252   if (timer_heap == NULL) {
253     err = UV_ENOMEM;
254     goto fail_timers_alloc;
255   }
256 
257   heap_init(timer_heap);
258 
259   loop->check_handles = NULL;
260   loop->prepare_handles = NULL;
261   loop->idle_handles = NULL;
262 
263   loop->next_prepare_handle = NULL;
264   loop->next_check_handle = NULL;
265   loop->next_idle_handle = NULL;
266 
267   memset(&loop->poll_peer_sockets, 0, sizeof loop->poll_peer_sockets);
268 
269   loop->active_tcp_streams = 0;
270   loop->active_udp_streams = 0;
271 
272   loop->timer_counter = 0;
273   loop->stop_flag = 0;
274 
275   err = uv_mutex_init(&loop->wq_mutex);
276   if (err)
277     goto fail_mutex_init;
278 
279   err = uv_async_init(loop, &loop->wq_async, uv__work_done);
280   if (err)
281     goto fail_async_init;
282 
283   uv__handle_unref(&loop->wq_async);
284   loop->wq_async.flags |= UV_HANDLE_INTERNAL;
285 
286   err = uv__loops_add(loop);
287   if (err)
288     goto fail_async_init;
289 
290   return 0;
291 
292 fail_async_init:
293   uv_mutex_destroy(&loop->wq_mutex);
294 
295 fail_mutex_init:
296   uv__free(timer_heap);
297   loop->timer_heap = NULL;
298 
299 fail_timers_alloc:
300   CloseHandle(loop->iocp);
301   loop->iocp = INVALID_HANDLE_VALUE;
302 
303   return err;
304 }
305 
306 
uv_update_time(uv_loop_t * loop)307 void uv_update_time(uv_loop_t* loop) {
308   uint64_t new_time = uv__hrtime(1000);
309   assert(new_time >= loop->time);
310   loop->time = new_time;
311 }
312 
313 
uv__once_init(void)314 void uv__once_init(void) {
315   uv_once(&uv_init_guard_, uv_init);
316 }
317 
318 
uv__loop_close(uv_loop_t * loop)319 void uv__loop_close(uv_loop_t* loop) {
320   size_t i;
321 
322   uv__loops_remove(loop);
323 
324   /* Close the async handle without needing an extra loop iteration.
325    * We might have a pending message, but we're just going to destroy the IOCP
326    * soon, so we can just discard it now without the usual risk of a getting
327    * another notification from GetQueuedCompletionStatusEx after calling the
328    * close_cb (which we also skip defining). We'll assert later that queue was
329    * actually empty and all reqs handled. */
330   loop->wq_async.async_sent = 0;
331   loop->wq_async.close_cb = NULL;
332   uv__handle_closing(&loop->wq_async);
333   uv__handle_close(&loop->wq_async);
334 
335   for (i = 0; i < ARRAY_SIZE(loop->poll_peer_sockets); i++) {
336     SOCKET sock = loop->poll_peer_sockets[i];
337     if (sock != 0 && sock != INVALID_SOCKET)
338       closesocket(sock);
339   }
340 
341   uv_mutex_lock(&loop->wq_mutex);
342   assert(QUEUE_EMPTY(&loop->wq) && "thread pool work queue not empty!");
343   assert(!uv__has_active_reqs(loop));
344   uv_mutex_unlock(&loop->wq_mutex);
345   uv_mutex_destroy(&loop->wq_mutex);
346 
347   uv__free(loop->timer_heap);
348   loop->timer_heap = NULL;
349 
350   CloseHandle(loop->iocp);
351 }
352 
353 
uv__loop_configure(uv_loop_t * loop,uv_loop_option option,va_list ap)354 int uv__loop_configure(uv_loop_t* loop, uv_loop_option option, va_list ap) {
355   return UV_ENOSYS;
356 }
357 
358 
uv_backend_fd(const uv_loop_t * loop)359 int uv_backend_fd(const uv_loop_t* loop) {
360   return -1;
361 }
362 
363 
uv_loop_fork(uv_loop_t * loop)364 int uv_loop_fork(uv_loop_t* loop) {
365   return UV_ENOSYS;
366 }
367 
368 
uv_backend_timeout(const uv_loop_t * loop)369 int uv_backend_timeout(const uv_loop_t* loop) {
370   if (loop->stop_flag != 0)
371     return 0;
372 
373   if (!uv__has_active_handles(loop) && !uv__has_active_reqs(loop))
374     return 0;
375 
376   if (loop->pending_reqs_tail)
377     return 0;
378 
379   if (loop->endgame_handles)
380     return 0;
381 
382   if (loop->idle_handles)
383     return 0;
384 
385   return uv__next_timeout(loop);
386 }
387 
388 
uv__poll_wine(uv_loop_t * loop,DWORD timeout)389 static void uv__poll_wine(uv_loop_t* loop, DWORD timeout) {
390   DWORD bytes;
391   ULONG_PTR key;
392   OVERLAPPED* overlapped;
393   uv_req_t* req;
394   int repeat;
395   uint64_t timeout_time;
396 
397   timeout_time = loop->time + timeout;
398 
399   for (repeat = 0; ; repeat++) {
400     GetQueuedCompletionStatus(loop->iocp,
401                               &bytes,
402                               &key,
403                               &overlapped,
404                               timeout);
405 
406     if (overlapped) {
407       /* Package was dequeued */
408       req = uv_overlapped_to_req(overlapped);
409       uv_insert_pending_req(loop, req);
410 
411       /* Some time might have passed waiting for I/O,
412        * so update the loop time here.
413        */
414       uv_update_time(loop);
415     } else if (GetLastError() != WAIT_TIMEOUT) {
416       /* Serious error */
417       uv_fatal_error(GetLastError(), "GetQueuedCompletionStatus");
418     } else if (timeout > 0) {
419       /* GetQueuedCompletionStatus can occasionally return a little early.
420        * Make sure that the desired timeout target time is reached.
421        */
422       uv_update_time(loop);
423       if (timeout_time > loop->time) {
424         timeout = (DWORD)(timeout_time - loop->time);
425         /* The first call to GetQueuedCompletionStatus should return very
426          * close to the target time and the second should reach it, but
427          * this is not stated in the documentation. To make sure a busy
428          * loop cannot happen, the timeout is increased exponentially
429          * starting on the third round.
430          */
431         timeout += repeat ? (1 << (repeat - 1)) : 0;
432         continue;
433       }
434     }
435     break;
436   }
437 }
438 
439 
uv__poll(uv_loop_t * loop,DWORD timeout)440 static void uv__poll(uv_loop_t* loop, DWORD timeout) {
441   BOOL success;
442   uv_req_t* req;
443   OVERLAPPED_ENTRY overlappeds[128];
444   ULONG count;
445   ULONG i;
446   int repeat;
447   uint64_t timeout_time;
448 
449   timeout_time = loop->time + timeout;
450 
451   for (repeat = 0; ; repeat++) {
452     success = GetQueuedCompletionStatusEx(loop->iocp,
453                                           overlappeds,
454                                           ARRAY_SIZE(overlappeds),
455                                           &count,
456                                           timeout,
457                                           FALSE);
458 
459     if (success) {
460       for (i = 0; i < count; i++) {
461         /* Package was dequeued, but see if it is not a empty package
462          * meant only to wake us up.
463          */
464         if (overlappeds[i].lpOverlapped) {
465           req = uv_overlapped_to_req(overlappeds[i].lpOverlapped);
466           uv_insert_pending_req(loop, req);
467         }
468       }
469 
470       /* Some time might have passed waiting for I/O,
471        * so update the loop time here.
472        */
473       uv_update_time(loop);
474     } else if (GetLastError() != WAIT_TIMEOUT) {
475       /* Serious error */
476       uv_fatal_error(GetLastError(), "GetQueuedCompletionStatusEx");
477     } else if (timeout > 0) {
478       /* GetQueuedCompletionStatus can occasionally return a little early.
479        * Make sure that the desired timeout target time is reached.
480        */
481       uv_update_time(loop);
482       if (timeout_time > loop->time) {
483         timeout = (DWORD)(timeout_time - loop->time);
484         /* The first call to GetQueuedCompletionStatus should return very
485          * close to the target time and the second should reach it, but
486          * this is not stated in the documentation. To make sure a busy
487          * loop cannot happen, the timeout is increased exponentially
488          * starting on the third round.
489          */
490         timeout += repeat ? (1 << (repeat - 1)) : 0;
491         continue;
492       }
493     }
494     break;
495   }
496 }
497 
498 
uv__loop_alive(const uv_loop_t * loop)499 static int uv__loop_alive(const uv_loop_t* loop) {
500   return uv__has_active_handles(loop) ||
501          uv__has_active_reqs(loop) ||
502          loop->endgame_handles != NULL;
503 }
504 
505 
uv_loop_alive(const uv_loop_t * loop)506 int uv_loop_alive(const uv_loop_t* loop) {
507     return uv__loop_alive(loop);
508 }
509 
510 
uv_run(uv_loop_t * loop,uv_run_mode mode)511 int uv_run(uv_loop_t *loop, uv_run_mode mode) {
512   DWORD timeout;
513   int r;
514   int ran_pending;
515 
516   r = uv__loop_alive(loop);
517   if (!r)
518     uv_update_time(loop);
519 
520   while (r != 0 && loop->stop_flag == 0) {
521     uv_update_time(loop);
522     uv__run_timers(loop);
523 
524     ran_pending = uv_process_reqs(loop);
525     uv_idle_invoke(loop);
526     uv_prepare_invoke(loop);
527 
528     timeout = 0;
529     if ((mode == UV_RUN_ONCE && !ran_pending) || mode == UV_RUN_DEFAULT)
530       timeout = uv_backend_timeout(loop);
531 
532     if (pGetQueuedCompletionStatusEx)
533       uv__poll(loop, timeout);
534     else
535       uv__poll_wine(loop, timeout);
536 
537 
538     uv_check_invoke(loop);
539     uv_process_endgames(loop);
540 
541     if (mode == UV_RUN_ONCE) {
542       /* UV_RUN_ONCE implies forward progress: at least one callback must have
543        * been invoked when it returns. uv__io_poll() can return without doing
544        * I/O (meaning: no callbacks) when its timeout expires - which means we
545        * have pending timers that satisfy the forward progress constraint.
546        *
547        * UV_RUN_NOWAIT makes no guarantees about progress so it's omitted from
548        * the check.
549        */
550       uv__run_timers(loop);
551     }
552 
553     r = uv__loop_alive(loop);
554     if (mode == UV_RUN_ONCE || mode == UV_RUN_NOWAIT)
555       break;
556   }
557 
558   /* The if statement lets the compiler compile it to a conditional store.
559    * Avoids dirtying a cache line.
560    */
561   if (loop->stop_flag != 0)
562     loop->stop_flag = 0;
563 
564   return r;
565 }
566 
567 
uv_fileno(const uv_handle_t * handle,uv_os_fd_t * fd)568 int uv_fileno(const uv_handle_t* handle, uv_os_fd_t* fd) {
569   uv_os_fd_t fd_out;
570 
571   switch (handle->type) {
572   case UV_TCP:
573     fd_out = (uv_os_fd_t)((uv_tcp_t*) handle)->socket;
574     break;
575 
576   case UV_NAMED_PIPE:
577     fd_out = ((uv_pipe_t*) handle)->handle;
578     break;
579 
580   case UV_TTY:
581     fd_out = ((uv_tty_t*) handle)->handle;
582     break;
583 
584   case UV_UDP:
585     fd_out = (uv_os_fd_t)((uv_udp_t*) handle)->socket;
586     break;
587 
588   case UV_POLL:
589     fd_out = (uv_os_fd_t)((uv_poll_t*) handle)->socket;
590     break;
591 
592   default:
593     return UV_EINVAL;
594   }
595 
596   if (uv_is_closing(handle) || fd_out == INVALID_HANDLE_VALUE)
597     return UV_EBADF;
598 
599   *fd = fd_out;
600   return 0;
601 }
602 
603 
uv__socket_sockopt(uv_handle_t * handle,int optname,int * value)604 int uv__socket_sockopt(uv_handle_t* handle, int optname, int* value) {
605   int r;
606   int len;
607   SOCKET socket;
608 
609   if (handle == NULL || value == NULL)
610     return UV_EINVAL;
611 
612   if (handle->type == UV_TCP)
613     socket = ((uv_tcp_t*) handle)->socket;
614   else if (handle->type == UV_UDP)
615     socket = ((uv_udp_t*) handle)->socket;
616   else
617     return UV_ENOTSUP;
618 
619   len = sizeof(*value);
620 
621   if (*value == 0)
622     r = getsockopt(socket, SOL_SOCKET, optname, (char*) value, &len);
623   else
624     r = setsockopt(socket, SOL_SOCKET, optname, (const char*) value, len);
625 
626   if (r == SOCKET_ERROR)
627     return uv_translate_sys_error(WSAGetLastError());
628 
629   return 0;
630 }
631 
uv_cpumask_size(void)632 int uv_cpumask_size(void) {
633   return (int)(sizeof(DWORD_PTR) * 8);
634 }
635 
uv__getsockpeername(const uv_handle_t * handle,uv__peersockfunc func,struct sockaddr * name,int * namelen,int delayed_error)636 int uv__getsockpeername(const uv_handle_t* handle,
637                         uv__peersockfunc func,
638                         struct sockaddr* name,
639                         int* namelen,
640                         int delayed_error) {
641 
642   int result;
643   uv_os_fd_t fd;
644 
645   result = uv_fileno(handle, &fd);
646   if (result != 0)
647     return result;
648 
649   if (delayed_error)
650     return uv_translate_sys_error(delayed_error);
651 
652   result = func((SOCKET) fd, name, namelen);
653   if (result != 0)
654     return uv_translate_sys_error(WSAGetLastError());
655 
656   return 0;
657 }
658