Rizin
unix-like reverse engineering framework and cli tools
core.c File Reference
#include <assert.h>
#include <errno.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "uv.h"
#include "internal.h"
#include "queue.h"
#include "handle-inl.h"
#include "heap-inl.h"
#include "req-inl.h"

Go to the source code of this file.

Macros

#define UV__LOOPS_CHUNK_SIZE   8
 

Functions

static void uv__crt_invalid_parameter_handler (const wchar_t *expression, const wchar_t *function, const wchar_t *file, unsigned int line, uintptr_t reserved)
 
static void uv__loops_init (void)
 
static int uv__loops_add (uv_loop_t *loop)
 
static void uv__loops_remove (uv_loop_t *loop)
 
void uv__wake_all_loops (void)
 
static void uv_init (void)
 
int uv_loop_init (uv_loop_t *loop)
 
void uv_update_time (uv_loop_t *loop)
 
void uv__once_init (void)
 
void uv__loop_close (uv_loop_t *loop)
 
int uv__loop_configure (uv_loop_t *loop, uv_loop_option option, va_list ap)
 
int uv_backend_fd (const uv_loop_t *loop)
 
int uv_loop_fork (uv_loop_t *loop)
 
int uv_backend_timeout (const uv_loop_t *loop)
 
static void uv__poll_wine (uv_loop_t *loop, DWORD timeout)
 
static void uv__poll (uv_loop_t *loop, DWORD timeout)
 
static int uv__loop_alive (const uv_loop_t *loop)
 
int uv_loop_alive (const uv_loop_t *loop)
 
int uv_run (uv_loop_t *loop, uv_run_mode mode)
 
int uv_fileno (const uv_handle_t *handle, uv_os_fd_t *fd)
 
int uv__socket_sockopt (uv_handle_t *handle, int optname, int *value)
 
int uv_cpumask_size (void)
 
int uv__getsockpeername (const uv_handle_t *handle, uv__peersockfunc func, struct sockaddr *name, int *namelen, int delayed_error)
 

Variables

static uv_once_t uv_init_guard_ = UV_ONCE_INIT
 
UV_THREAD_LOCAL int uv__crt_assert_enabled = FALSE
 
static uv_loop_t ** uv__loops
 
static int uv__loops_size
 
static int uv__loops_capacity
 
static uv_mutex_t uv__loops_lock
 

Macro Definition Documentation

◆ UV__LOOPS_CHUNK_SIZE

#define UV__LOOPS_CHUNK_SIZE   8

Definition at line 84 of file core.c.

Function Documentation

◆ uv__crt_invalid_parameter_handler()

static void uv__crt_invalid_parameter_handler ( const wchar_t *  expression,
const wchar_t *  function,
const wchar_t *  file,
unsigned int  line,
uintptr_t  reserved 
)
static

Definition at line 74 of file core.c.

76  {
77  /* No-op. */
78 }

Referenced by uv_init().

◆ uv__getsockpeername()

int uv__getsockpeername ( const uv_handle_t handle,
uv__peersockfunc  func,
struct sockaddr name,
int namelen,
int  delayed_error 
)

Definition at line 727 of file core.c.

731  {
732 
733  int result;
734  uv_os_fd_t fd;
735 
736  result = uv_fileno(handle, &fd);
737  if (result != 0)
738  return result;
739 
740  if (delayed_error)
741  return uv_translate_sys_error(delayed_error);
742 
743  result = func((SOCKET) fd, name, namelen);
744  if (result != 0)
745  return uv_translate_sys_error(WSAGetLastError());
746 
747  return 0;
748 }
static mcore_handle handle
Definition: asm_mcore.c:8
Definition: z80asm.h:102
int uv_fileno(const uv_handle_t *handle, uv_os_fd_t *fd)
Definition: core.c:767
int uv_translate_sys_error(int sys_errno)
Definition: core.c:1249
int uv_os_fd_t
Definition: unix.h:130
static const z80_opcode fd[]
Definition: z80_tab.h:997

References fd, handle, uv_fileno(), and uv_translate_sys_error().

◆ uv__loop_alive()

static int uv__loop_alive ( const uv_loop_t loop)
static

Definition at line 584 of file core.c.

584  {
585  return uv__has_active_handles(loop) ||
587  loop->endgame_handles != NULL;
588 }
#define NULL
Definition: cris-opc.c:27
uv_loop_t * loop
Definition: main.c:7
#define uv__has_active_handles(loop)
Definition: uv-common.h:237
#define uv__has_active_reqs(loop)
Definition: uv-common.h:221

References loop, NULL, uv__has_active_handles, and uv__has_active_reqs.

Referenced by uv_loop_alive(), and uv_run().

◆ uv__loop_close()

void uv__loop_close ( uv_loop_t loop)

Definition at line 334 of file core.c.

334  {
336  size_t i;
337 
339 
340  /* Close the async handle without needing an extra loop iteration.
341  * We might have a pending message, but we're just going to destroy the IOCP
342  * soon, so we can just discard it now without the usual risk of a getting
343  * another notification from GetQueuedCompletionStatusEx after calling the
344  * close_cb (which we also skip defining). We'll assert later that queue was
345  * actually empty and all reqs handled. */
346  loop->wq_async.async_sent = 0;
347  loop->wq_async.close_cb = NULL;
348  uv__handle_closing(&loop->wq_async);
349  uv__handle_close(&loop->wq_async);
350 
351  for (i = 0; i < ARRAY_SIZE(loop->poll_peer_sockets); i++) {
352  SOCKET sock = loop->poll_peer_sockets[i];
353  if (sock != 0 && sock != INVALID_SOCKET)
354  closesocket(sock);
355  }
356 
357  uv_mutex_lock(&loop->wq_mutex);
358  assert(QUEUE_EMPTY(&loop->wq) && "thread pool work queue not empty!");
360  uv_mutex_unlock(&loop->wq_mutex);
361  uv_mutex_destroy(&loop->wq_mutex);
362 
363  uv__free(loop->timer_heap);
364  loop->timer_heap = NULL;
365 
366  lfields = uv__get_internal_fields(loop);
368  uv__free(lfields);
370 
371  CloseHandle(loop->iocp);
372 }
#define ARRAY_SIZE(a)
lzma_index ** i
Definition: index.h:629
#define uv__handle_close(handle)
Definition: handle-inl.h:76
#define uv__handle_closing(handle)
Definition: handle-inl.h:63
assert(limit<=UINT32_MAX/2)
#define QUEUE_EMPTY(q)
Definition: queue.h:39
uv__loop_metrics_t loop_metrics
Definition: uv-common.h:365
uv_mutex_t lock
Definition: uv-common.h:357
void * internal_fields
Definition: uv.h:1791
static void uv__loops_remove(uv_loop_t *loop)
Definition: core.c:118
void uv__free(void *ptr)
Definition: uv-common.c:81
#define uv__get_internal_fields(loop)
Definition: uv-common.h:336
UV_EXTERN void uv_mutex_lock(uv_mutex_t *handle)
Definition: thread.c:330
UV_EXTERN void uv_mutex_destroy(uv_mutex_t *handle)
Definition: thread.c:324
UV_EXTERN void uv_mutex_unlock(uv_mutex_t *handle)
Definition: thread.c:350

References ARRAY_SIZE, assert(), i, uv_loop_s::internal_fields, uv__loop_metrics_s::lock, loop, uv__loop_internal_fields_s::loop_metrics, NULL, QUEUE_EMPTY, uv__free(), uv__get_internal_fields, uv__handle_close, uv__handle_closing, uv__has_active_reqs, uv__loops_remove(), uv_mutex_destroy(), uv_mutex_lock(), and uv_mutex_unlock().

◆ uv__loop_configure()

int uv__loop_configure ( uv_loop_t loop,
uv_loop_option  option,
va_list  ap 
)

Definition at line 375 of file core.c.

375  {
377 
378  lfields = uv__get_internal_fields(loop);
379  if (option == UV_METRICS_IDLE_TIME) {
380  lfields->flags |= UV_METRICS_IDLE_TIME;
381  return 0;
382  }
383 
384  return UV_ENOSYS;
385 }
Definition: getopt.h:84
@ UV_METRICS_IDLE_TIME
Definition: uv.h:251

References uv__loop_internal_fields_s::flags, loop, uv__get_internal_fields, and UV_METRICS_IDLE_TIME.

◆ uv__loops_add()

static int uv__loops_add ( uv_loop_t loop)
static

Definition at line 91 of file core.c.

91  {
92  uv_loop_t** new_loops;
93  int new_capacity, i;
94 
96 
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  }
108  ++uv__loops_size;
109 
111  return 0;
112 
113 failed_loops_realloc:
115  return ERROR_OUTOFMEMORY;
116 }
Definition: uv.h:1780
static int uv__loops_capacity
Definition: core.c:83
static int uv__loops_size
Definition: core.c:82
#define UV__LOOPS_CHUNK_SIZE
Definition: core.c:84
static uv_mutex_t uv__loops_lock
Definition: core.c:85
static uv_loop_t ** uv__loops
Definition: core.c:81
void * uv__realloc(void *ptr, size_t size)
Definition: uv-common.c:96

References i, loop, NULL, uv__loops, uv__loops_capacity, UV__LOOPS_CHUNK_SIZE, uv__loops_lock, uv__loops_size, uv__realloc(), uv_mutex_lock(), and uv_mutex_unlock().

Referenced by uv_loop_init().

◆ uv__loops_init()

static void uv__loops_init ( void  )
static

Definition at line 87 of file core.c.

87  {
89 }
UV_EXTERN int uv_mutex_init(uv_mutex_t *handle)
Definition: thread.c:282

References uv__loops_lock, and uv_mutex_init().

Referenced by uv_init().

◆ uv__loops_remove()

static void uv__loops_remove ( uv_loop_t loop)
static

Definition at line 118 of file core.c.

118  {
119  int loop_index;
120  int smaller_capacity;
121  uv_loop_t** new_loops;
122 
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];
135  --uv__loops_size;
136 
137  if (uv__loops_size == 0) {
138  uv__loops_capacity = 0;
140  uv__loops = NULL;
141  goto loop_removed;
142  }
143 
144  /* If we didn't grow to big skip downsizing */
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:
160 }

References loop, NULL, uv__free(), uv__loops, uv__loops_capacity, UV__LOOPS_CHUNK_SIZE, uv__loops_lock, uv__loops_size, uv__realloc(), uv_mutex_lock(), and uv_mutex_unlock().

Referenced by uv__loop_close().

◆ uv__once_init()

void uv__once_init ( void  )

Definition at line 329 of file core.c.

329  {
331 }
static void uv_init(void)
Definition: core.c:176
static uv_once_t uv_init_guard_
Definition: core.c:40
UV_EXTERN void uv_once(uv_once_t *guard, void(*callback)(void))
Definition: thread.c:419

References uv_init(), uv_init_guard_, and uv_once().

Referenced by uv__pipe_getname(), uv__random(), uv_cpu_info(), uv_fs_req_init(), uv_get_process_title(), uv_hrtime(), uv_loop_init(), uv_os_gethostname(), uv_os_uname(), uv_pipe_open(), uv_set_process_title(), and uv_tty_init().

◆ uv__poll()

static void uv__poll ( uv_loop_t loop,
DWORD  timeout 
)
static

Definition at line 497 of file core.c.

497  {
498  BOOL success;
499  uv_req_t* req;
500  OVERLAPPED_ENTRY overlappeds[128];
501  ULONG count;
502  ULONG i;
503  int repeat;
504  uint64_t timeout_time;
505  uint64_t user_timeout;
506  int reset_timeout;
507 
508  timeout_time = loop->time + timeout;
509 
511  reset_timeout = 1;
512  user_timeout = timeout;
513  timeout = 0;
514  } else {
515  reset_timeout = 0;
516  }
517 
518  for (repeat = 0; ; repeat++) {
519  /* Only need to set the provider_entry_time if timeout != 0. The function
520  * will return early if the loop isn't configured with UV_METRICS_IDLE_TIME.
521  */
522  if (timeout != 0)
524 
525  success = pGetQueuedCompletionStatusEx(loop->iocp,
526  overlappeds,
527  ARRAY_SIZE(overlappeds),
528  &count,
529  timeout,
530  FALSE);
531 
532  if (reset_timeout != 0) {
533  timeout = user_timeout;
534  reset_timeout = 0;
535  }
536 
537  /* Placed here because on success the loop will break whether there is an
538  * empty package or not, or if GetQueuedCompletionStatus returned early then
539  * the timeout will be updated and the loop will run again. In either case
540  * the idle time will need to be updated.
541  */
543 
544  if (success) {
545  for (i = 0; i < count; i++) {
546  /* Package was dequeued, but see if it is not a empty package
547  * meant only to wake us up.
548  */
549  if (overlappeds[i].lpOverlapped) {
550  req = uv_overlapped_to_req(overlappeds[i].lpOverlapped);
552  }
553  }
554 
555  /* Some time might have passed waiting for I/O,
556  * so update the loop time here.
557  */
559  } else if (GetLastError() != WAIT_TIMEOUT) {
560  /* Serious error */
561  uv_fatal_error(GetLastError(), "GetQueuedCompletionStatusEx");
562  } else if (timeout > 0) {
563  /* GetQueuedCompletionStatus can occasionally return a little early.
564  * Make sure that the desired timeout target time is reached.
565  */
567  if (timeout_time > loop->time) {
568  timeout = (DWORD)(timeout_time - loop->time);
569  /* The first call to GetQueuedCompletionStatus should return very
570  * close to the target time and the second should reach it, but
571  * this is not stated in the documentation. To make sure a busy
572  * loop cannot happen, the timeout is increased exponentially
573  * starting on the third round.
574  */
575  timeout += repeat ? (1 << (repeat - 1)) : 0;
576  continue;
577  }
578  }
579  break;
580  }
581 }
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count static mode const void const struct sockaddr static tolen const char static pathname void static offset struct stat static buf void long static basep static whence static length const void static len static semflg const void static shmflg const struct timespec req
Definition: sflib.h:128
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count static mode const void const struct sockaddr static tolen const char static pathname void count
Definition: sflib.h:98
void uv_fatal_error(const int errorno, const char *syscall)
Definition: error.c:35
#define FALSE
Definition: mybfd.h:102
static void repeat(struct parse *, sopno, int, int)
Definition: regcomp.c:1155
static INLINE void uv_insert_pending_req(uv_loop_t *loop, uv_req_t *req)
Definition: req-inl.h:90
static INLINE uv_req_t * uv_overlapped_to_req(OVERLAPPED *overlapped)
Definition: req-inl.h:85
static struct sockaddr static addrlen static backlog const void static flags void flags
Definition: sfsocketcall.h:123
unsigned long uint64_t
Definition: sftypes.h:28
Definition: uv.h:407
uv_timer_t timeout
Definition: main.c:9
void uv_update_time(uv_loop_t *loop)
Definition: core.c:425
void uv__metrics_update_idle_time(uv_loop_t *loop)
Definition: uv-common.c:872
void uv__metrics_set_provider_entry_time(uv_loop_t *loop)
Definition: uv-common.c:899
sGetQueuedCompletionStatusEx pGetQueuedCompletionStatusEx
Definition: winapi.c:40
ULONG
DWORD

References ARRAY_SIZE, count, DWORD, FALSE, flags, i, loop, pGetQueuedCompletionStatusEx, repeat(), req, timeout, ULONG, uv__get_internal_fields, uv__metrics_set_provider_entry_time(), uv__metrics_update_idle_time(), uv_fatal_error(), uv_insert_pending_req(), UV_METRICS_IDLE_TIME, uv_overlapped_to_req(), and uv_update_time().

Referenced by uv_run().

◆ uv__poll_wine()

static void uv__poll_wine ( uv_loop_t loop,
DWORD  timeout 
)
static

Definition at line 418 of file core.c.

418  {
419  DWORD bytes;
420  ULONG_PTR key;
421  OVERLAPPED* overlapped;
422  uv_req_t* req;
423  int repeat;
424  uint64_t timeout_time;
425  uint64_t user_timeout;
426  int reset_timeout;
427 
428  timeout_time = loop->time + timeout;
429 
431  reset_timeout = 1;
432  user_timeout = timeout;
433  timeout = 0;
434  } else {
435  reset_timeout = 0;
436  }
437 
438  for (repeat = 0; ; repeat++) {
439  /* Only need to set the provider_entry_time if timeout != 0. The function
440  * will return early if the loop isn't configured with UV_METRICS_IDLE_TIME.
441  */
442  if (timeout != 0)
444 
445  GetQueuedCompletionStatus(loop->iocp,
446  &bytes,
447  &key,
448  &overlapped,
449  timeout);
450 
451  if (reset_timeout != 0) {
452  timeout = user_timeout;
453  reset_timeout = 0;
454  }
455 
456  /* Placed here because on success the loop will break whether there is an
457  * empty package or not, or if GetQueuedCompletionStatus returned early then
458  * the timeout will be updated and the loop will run again. In either case
459  * the idle time will need to be updated.
460  */
462 
463  if (overlapped) {
464  /* Package was dequeued */
465  req = uv_overlapped_to_req(overlapped);
467 
468  /* Some time might have passed waiting for I/O,
469  * so update the loop time here.
470  */
472  } else if (GetLastError() != WAIT_TIMEOUT) {
473  /* Serious error */
474  uv_fatal_error(GetLastError(), "GetQueuedCompletionStatus");
475  } else if (timeout > 0) {
476  /* GetQueuedCompletionStatus can occasionally return a little early.
477  * Make sure that the desired timeout target time is reached.
478  */
480  if (timeout_time > loop->time) {
481  timeout = (DWORD)(timeout_time - loop->time);
482  /* The first call to GetQueuedCompletionStatus should return very
483  * close to the target time and the second should reach it, but
484  * this is not stated in the documentation. To make sure a busy
485  * loop cannot happen, the timeout is increased exponentially
486  * starting on the third round.
487  */
488  timeout += repeat ? (1 << (repeat - 1)) : 0;
489  continue;
490  }
491  }
492  break;
493  }
494 }
static ut8 bytes[32]
Definition: asm_arc.c:23
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count static mode const void const struct sockaddr static tolen const char static pathname void static offset struct stat static buf void long static basep static whence static length const void static len key
Definition: sflib.h:118

References bytes, DWORD, flags, key, loop, repeat(), req, timeout, uv__get_internal_fields, uv__metrics_set_provider_entry_time(), uv__metrics_update_idle_time(), uv_fatal_error(), uv_insert_pending_req(), UV_METRICS_IDLE_TIME, uv_overlapped_to_req(), and uv_update_time().

Referenced by uv_run().

◆ uv__socket_sockopt()

int uv__socket_sockopt ( uv_handle_t handle,
int  optname,
int value 
)

Definition at line 695 of file core.c.

695  {
696  int r;
697  int len;
698  SOCKET socket;
699 
700  if (handle == NULL || value == NULL)
701  return UV_EINVAL;
702 
703  if (handle->type == UV_TCP)
704  socket = ((uv_tcp_t*) handle)->socket;
705  else if (handle->type == UV_UDP)
706  socket = ((uv_udp_t*) handle)->socket;
707  else
708  return UV_ENOTSUP;
709 
710  len = sizeof(*value);
711 
712  if (*value == 0)
713  r = getsockopt(socket, SOL_SOCKET, optname, (char*) value, &len);
714  else
715  r = setsockopt(socket, SOL_SOCKET, optname, (const char*) value, len);
716 
717  if (r == SOCKET_ERROR)
718  return uv_translate_sys_error(WSAGetLastError());
719 
720  return 0;
721 }
size_t len
Definition: 6502dis.c:15
static int value
Definition: cmd_api.c:93
#define r
Definition: crypto_rc6.c:12
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd socket
Definition: sflib.h:79
#define SOL_SOCKET
Definition: sftypes.h:427
Definition: uv.h:547
Definition: uv.h:638

References handle, len, NULL, r, socket, SOL_SOCKET, uv_translate_sys_error(), and value.

◆ uv__wake_all_loops()

void uv__wake_all_loops ( void  )

Definition at line 162 of file core.c.

162  {
163  int i;
164  uv_loop_t* loop;
165 
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  }
174 }
#define INVALID_HANDLE_VALUE
Definition: iowin32.c:21

References assert(), i, INVALID_HANDLE_VALUE, loop, NULL, uv__loops, uv__loops_lock, uv__loops_size, uv_mutex_lock(), and uv_mutex_unlock().

Referenced by uv__system_resume_callback().

◆ uv_backend_fd()

int uv_backend_fd ( const uv_loop_t loop)

Definition at line 388 of file core.c.

388  {
389  return -1;
390 }

References loop.

◆ uv_backend_timeout()

int uv_backend_timeout ( const uv_loop_t loop)

Definition at line 398 of file core.c.

398  {
399  if (loop->stop_flag != 0)
400  return 0;
401 
403  return 0;
404 
405  if (loop->pending_reqs_tail)
406  return 0;
407 
408  if (loop->endgame_handles)
409  return 0;
410 
411  if (loop->idle_handles)
412  return 0;
413 
414  return uv__next_timeout(loop);
415 }
unsigned int stop_flag
Definition: uv.h:1793
int uv__next_timeout(const uv_loop_t *loop)
Definition: timer.c:141

References loop, QUEUE_EMPTY, uv_loop_s::stop_flag, uv__has_active_handles, uv__has_active_reqs, and uv__next_timeout().

◆ uv_cpumask_size()

int uv_cpumask_size ( void  )

Definition at line 723 of file core.c.

723  {
724  return (int)(sizeof(DWORD_PTR) * 8);
725 }

◆ uv_fileno()

int uv_fileno ( const uv_handle_t handle,
uv_os_fd_t fd 
)

Definition at line 659 of file core.c.

659  {
660  uv_os_fd_t fd_out;
661 
662  switch (handle->type) {
663  case UV_TCP:
664  fd_out = (uv_os_fd_t)((uv_tcp_t*) handle)->socket;
665  break;
666 
667  case UV_NAMED_PIPE:
668  fd_out = ((uv_pipe_t*) handle)->handle;
669  break;
670 
671  case UV_TTY:
672  fd_out = ((uv_tty_t*) handle)->handle;
673  break;
674 
675  case UV_UDP:
676  fd_out = (uv_os_fd_t)((uv_udp_t*) handle)->socket;
677  break;
678 
679  case UV_POLL:
680  fd_out = (uv_os_fd_t)((uv_poll_t*) handle)->socket;
681  break;
682 
683  default:
684  return UV_EINVAL;
685  }
686 
687  if (uv_is_closing(handle) || fd_out == INVALID_HANDLE_VALUE)
688  return UV_EBADF;
689 
690  *fd = fd_out;
691  return 0;
692 }
Definition: uv.h:767
Definition: uv.h:793
Definition: uv.h:714
int uv_is_closing(const uv_handle_t *handle)
Definition: core.c:323

References fd, handle, INVALID_HANDLE_VALUE, socket, uv__is_closing, uv__stream_fd, and uv_is_closing().

Referenced by on_new_connection().

◆ uv_init()

static void uv_init ( void  )
static

Definition at line 176 of file core.c.

176  {
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 */
221 }
void uv__init_detect_system_wakeup(void)
Definition: detect-wakeup.c:28
static void uv__crt_invalid_parameter_handler(const wchar_t *expression, const wchar_t *function, const wchar_t *file, unsigned int line, uintptr_t reserved)
Definition: core.c:74
static void uv__loops_init(void)
Definition: core.c:87
void uv__util_init(void)
Definition: util.c:79
void uv_winapi_init(void)
Definition: winapi.c:49
void uv_winsock_init(void)
Definition: winsock.c:78
void uv_console_init(void)
Definition: tty.c:166
void uv_signals_init(void)
Definition: signal.c:42
void uv_fs_init(void)
Definition: fs.c:141

References uv__crt_invalid_parameter_handler(), uv__init_detect_system_wakeup(), uv__loops_init(), uv__util_init(), uv_console_init(), uv_fs_init(), uv_signals_init(), uv_winapi_init(), and uv_winsock_init().

Referenced by uv__once_init().

◆ uv_loop_alive()

int uv_loop_alive ( const uv_loop_t loop)

Definition at line 591 of file core.c.

591  {
592  return uv__loop_alive(loop);
593 }
static int uv__loop_alive(const uv_loop_t *loop)
Definition: core.c:584

References loop, and uv__loop_alive().

◆ uv_loop_fork()

int uv_loop_fork ( uv_loop_t loop)

Definition at line 393 of file core.c.

393  {
394  return UV_ENOSYS;
395 }

References err, i, loop, NULL, QUEUE_EMPTY, QUEUE_INSERT_TAIL, uv__async_fork(), uv__io_fork(), uv__signal_loop_fork(), and w.

◆ uv_loop_init()

int uv_loop_init ( uv_loop_t loop)

Definition at line 224 of file core.c.

224  {
226  struct heap* timer_heap;
227  int err;
228 
229  /* Initialize libuv itself first */
230  uv__once_init();
231 
232  /* Create an I/O completion port */
233  loop->iocp = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 1);
234  if (loop->iocp == NULL)
235  return uv_translate_sys_error(GetLastError());
236 
237  lfields = (uv__loop_internal_fields_t*) uv__calloc(1, sizeof(*lfields));
238  if (lfields == NULL)
239  return UV_ENOMEM;
240  loop->internal_fields = lfields;
241 
242  err = uv_mutex_init(&lfields->loop_metrics.lock);
243  if (err)
244  goto fail_metrics_mutex_init;
245 
246  /* To prevent uninitialized memory access, loop->time must be initialized
247  * to zero before calling uv_update_time for the first time.
248  */
249  loop->time = 0;
251 
252  QUEUE_INIT(&loop->wq);
254  loop->active_reqs.count = 0;
255  loop->active_handles = 0;
256 
257  loop->pending_reqs_tail = NULL;
258 
259  loop->endgame_handles = NULL;
260 
261  loop->timer_heap = timer_heap = uv__malloc(sizeof(*timer_heap));
262  if (timer_heap == NULL) {
263  err = UV_ENOMEM;
264  goto fail_timers_alloc;
265  }
266 
267  heap_init(timer_heap);
268 
269  loop->check_handles = NULL;
270  loop->prepare_handles = NULL;
271  loop->idle_handles = NULL;
272 
273  loop->next_prepare_handle = NULL;
274  loop->next_check_handle = NULL;
275  loop->next_idle_handle = NULL;
276 
277  memset(&loop->poll_peer_sockets, 0, sizeof loop->poll_peer_sockets);
278 
279  loop->active_tcp_streams = 0;
280  loop->active_udp_streams = 0;
281 
282  loop->timer_counter = 0;
283  loop->stop_flag = 0;
284 
285  err = uv_mutex_init(&loop->wq_mutex);
286  if (err)
287  goto fail_mutex_init;
288 
289  err = uv_async_init(loop, &loop->wq_async, uv__work_done);
290  if (err)
291  goto fail_async_init;
292 
293  uv__handle_unref(&loop->wq_async);
294  loop->wq_async.flags |= UV_HANDLE_INTERNAL;
295 
297  if (err)
298  goto fail_async_init;
299 
300  return 0;
301 
302 fail_async_init:
303  uv_mutex_destroy(&loop->wq_mutex);
304 
305 fail_mutex_init:
307  loop->timer_heap = NULL;
308 
309 fail_timers_alloc:
311 
312 fail_metrics_mutex_init:
313  uv__free(lfields);
315  CloseHandle(loop->iocp);
316  loop->iocp = INVALID_HANDLE_VALUE;
317 
318  return err;
319 }
static bool err
Definition: armass.c:435
return memset(p, 0, total)
#define QUEUE_INIT(q)
Definition: queue.h:45
Definition: heap-inl.h:40
union uv_loop_s::@400 active_reqs
void * handle_queue[2]
Definition: uv.h:1785
unsigned int count
Definition: uv.h:1788
unsigned int active_handles
Definition: uv.h:1784
static int uv__loops_add(uv_loop_t *loop)
Definition: core.c:91
void uv__once_init(void)
Definition: core.c:329
void uv__work_done(uv_async_t *handle)
Definition: threadpool.c:295
static struct heap * timer_heap(const uv_loop_t *loop)
Definition: timer.c:29
void * uv__malloc(size_t size)
Definition: uv-common.c:75
void * uv__calloc(size_t count, size_t size)
Definition: uv-common.c:92
@ UV_HANDLE_INTERNAL
Definition: uv-common.h:78
#define uv__handle_unref(h)
Definition: uv-common.h:283
UV_EXTERN int uv_async_init(uv_loop_t *, uv_async_t *async, uv_async_cb async_cb)
Definition: async.c:45

References uv_loop_s::active_handles, uv_loop_s::active_reqs, uv_loop_s::count, uv_loop_s::data, err, uv_loop_s::handle_queue, uv_loop_s::internal_fields, INVALID_HANDLE_VALUE, uv__loop_metrics_s::lock, loop, uv__loop_internal_fields_s::loop_metrics, memset(), NULL, QUEUE_INIT, uv_loop_s::stop_flag, timer_heap(), uv__calloc(), uv__free(), uv__handle_unref, uv__loops_add(), uv__malloc(), uv__once_init(), uv__platform_loop_delete(), uv__platform_loop_init(), uv__signal_global_once_init(), uv__signal_loop_cleanup(), uv__work_done(), uv_async_init(), UV_HANDLE_INTERNAL, uv_mutex_destroy(), uv_mutex_init(), uv_rwlock_destroy(), uv_rwlock_init(), uv_signal_init(), uv_translate_sys_error(), and uv_update_time().

Referenced by create_loop(), main(), uv_default_loop(), and uv_loop_new().

◆ uv_run()

int uv_run ( uv_loop_t loop,
uv_run_mode  mode 
)

Definition at line 596 of file core.c.

596  {
597  DWORD timeout;
598  int r;
599  int ran_pending;
600 
601  r = uv__loop_alive(loop);
602  if (!r)
604 
605  while (r != 0 && loop->stop_flag == 0) {
608 
609  ran_pending = uv_process_reqs(loop);
612 
613  timeout = 0;
614  if ((mode == UV_RUN_ONCE && !ran_pending) || mode == UV_RUN_DEFAULT)
616 
619  else
621 
622  /* Run one final update on the provider_idle_time in case uv__poll*
623  * returned because the timeout expired, but no events were received. This
624  * call will be ignored if the provider_entry_time was either never set (if
625  * the timeout == 0) or was already updated b/c an event was received.
626  */
628 
631 
632  if (mode == UV_RUN_ONCE) {
633  /* UV_RUN_ONCE implies forward progress: at least one callback must have
634  * been invoked when it returns. uv__io_poll() can return without doing
635  * I/O (meaning: no callbacks) when its timeout expires - which means we
636  * have pending timers that satisfy the forward progress constraint.
637  *
638  * UV_RUN_NOWAIT makes no guarantees about progress so it's omitted from
639  * the check.
640  */
642  }
643 
644  r = uv__loop_alive(loop);
645  if (mode == UV_RUN_ONCE || mode == UV_RUN_NOWAIT)
646  break;
647  }
648 
649  /* The if statement lets the compiler compile it to a conditional store.
650  * Avoids dirtying a cache line.
651  */
652  if (loop->stop_flag != 0)
653  loop->stop_flag = 0;
654 
655  return r;
656 }
static INLINE void uv_process_endgames(uv_loop_t *loop)
Definition: handle-inl.h:98
const char int mode
Definition: ioapi.h:137
static INLINE int uv_process_reqs(uv_loop_t *loop)
Definition: req-inl.h:141
int uv_backend_timeout(const uv_loop_t *loop)
Definition: core.c:333
static void uv__poll(uv_loop_t *loop, DWORD timeout)
Definition: core.c:497
static void uv__poll_wine(uv_loop_t *loop, DWORD timeout)
Definition: core.c:418
void uv_prepare_invoke(uv_loop_t *loop)
void uv_check_invoke(uv_loop_t *loop)
void uv_idle_invoke(uv_loop_t *loop)
void uv__run_timers(uv_loop_t *loop)
Definition: timer.c:162
@ UV_RUN_NOWAIT
Definition: uv.h:257
@ UV_RUN_ONCE
Definition: uv.h:256
@ UV_RUN_DEFAULT
Definition: uv.h:255

References DWORD, loop, pGetQueuedCompletionStatusEx, r, uv_loop_s::stop_flag, timeout, uv__io_poll(), uv__loop_alive(), uv__metrics_update_idle_time(), uv__poll(), uv__poll_wine(), uv__run_check(), uv__run_closing_handles(), uv__run_idle(), uv__run_pending(), uv__run_prepare(), uv__run_timers(), uv_backend_timeout(), uv_check_invoke(), uv_idle_invoke(), uv_prepare_invoke(), uv_process_endgames(), uv_process_reqs(), UV_RUN_DEFAULT, UV_RUN_NOWAIT, UV_RUN_ONCE, and uv_update_time().

Referenced by main(), thread1_worker(), and thread2_worker().

◆ uv_update_time()

void uv_update_time ( uv_loop_t loop)

Definition at line 322 of file core.c.

322  {
323  uint64_t new_time = uv__hrtime(1000);
324  assert(new_time >= loop->time);
325  loop->time = new_time;
326 }
uint64_t uv__hrtime(uv_clocktype_t type)
Definition: aix-common.c:43

References assert(), loop, and uv__hrtime().

Variable Documentation

◆ uv__crt_assert_enabled

UV_THREAD_LOCAL int uv__crt_assert_enabled = FALSE

Definition at line 69 of file core.c.

◆ uv__loops

uv_loop_t** uv__loops
static

Definition at line 81 of file core.c.

Referenced by uv__loops_add(), uv__loops_remove(), and uv__wake_all_loops().

◆ uv__loops_capacity

int uv__loops_capacity
static

Definition at line 83 of file core.c.

Referenced by uv__loops_add(), and uv__loops_remove().

◆ uv__loops_lock

uv_mutex_t uv__loops_lock
static

Definition at line 85 of file core.c.

Referenced by uv__loops_add(), uv__loops_init(), uv__loops_remove(), and uv__wake_all_loops().

◆ uv__loops_size

int uv__loops_size
static

Definition at line 82 of file core.c.

Referenced by uv__loops_add(), uv__loops_remove(), and uv__wake_all_loops().

◆ uv_init_guard_

uv_once_t uv_init_guard_ = UV_ONCE_INIT
static

Definition at line 40 of file core.c.

Referenced by uv__once_init().