Home | History | Annotate | Line # | Download | only in src
      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 /*
     23  * This file is private to libuv. It provides common functionality to both
     24  * Windows and Unix backends.
     25  */
     26 
     27 #ifndef UV_COMMON_H_
     28 #define UV_COMMON_H_
     29 
     30 #include <assert.h>
     31 #include <stdarg.h>
     32 #include <stddef.h>
     33 #include <stdint.h>
     34 #include <string.h>
     35 
     36 #include "uv.h"
     37 #include "uv/tree.h"
     38 #include "queue.h"
     39 #include "strscpy.h"
     40 
     41 #ifndef _MSC_VER
     42 # include <stdatomic.h>
     43 #endif
     44 
     45 #if EDOM > 0
     46 # define UV__ERR(x) (-(x))
     47 #else
     48 # define UV__ERR(x) (x)
     49 #endif
     50 
     51 #if !defined(snprintf) && defined(_MSC_VER) && _MSC_VER < 1900
     52 extern int snprintf(char*, size_t, const char*, ...);
     53 #endif
     54 
     55 #define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
     56 #define ARRAY_END(a)  ((a) + ARRAY_SIZE(a))
     57 
     58 #define container_of(ptr, type, member) \
     59   ((type *) ((char *) (ptr) - offsetof(type, member)))
     60 
     61 /* C11 defines static_assert to be a macro which calls _Static_assert. */
     62 #if defined(static_assert)
     63 #define STATIC_ASSERT(expr) static_assert(expr, #expr)
     64 #else
     65 #define STATIC_ASSERT(expr)                                                   \
     66   void uv__static_assert(int static_assert_failed[1 - 2 * !(expr)])
     67 #endif
     68 
     69 #ifdef _MSC_VER
     70 #define uv__exchange_int_relaxed(p, v)                                        \
     71   InterlockedExchangeNoFence((LONG volatile*)(p), v)
     72 #else
     73 #define uv__exchange_int_relaxed(p, v)                                        \
     74   atomic_exchange_explicit((_Atomic int*)(p), v, memory_order_relaxed)
     75 #endif
     76 
     77 #define UV__UDP_DGRAM_MAXSIZE (64 * 1024)
     78 
     79 /* Handle flags. Some flags are specific to Windows or UNIX. */
     80 enum {
     81   /* Used by all handles. */
     82   UV_HANDLE_CLOSING                     = 0x00000001,
     83   UV_HANDLE_CLOSED                      = 0x00000002,
     84   UV_HANDLE_ACTIVE                      = 0x00000004,
     85   UV_HANDLE_REF                         = 0x00000008,
     86   UV_HANDLE_INTERNAL                    = 0x00000010,
     87   UV_HANDLE_ENDGAME_QUEUED              = 0x00000020,
     88 
     89   /* Used by streams. */
     90   UV_HANDLE_LISTENING                   = 0x00000040,
     91   UV_HANDLE_CONNECTION                  = 0x00000080,
     92   UV_HANDLE_SHUT                        = 0x00000200,
     93   UV_HANDLE_READ_PARTIAL                = 0x00000400,
     94   UV_HANDLE_READ_EOF                    = 0x00000800,
     95 
     96   /* Used by streams and UDP handles. */
     97   UV_HANDLE_READING                     = 0x00001000,
     98   UV_HANDLE_BOUND                       = 0x00002000,
     99   UV_HANDLE_READABLE                    = 0x00004000,
    100   UV_HANDLE_WRITABLE                    = 0x00008000,
    101   UV_HANDLE_READ_PENDING                = 0x00010000,
    102   UV_HANDLE_SYNC_BYPASS_IOCP            = 0x00020000,
    103   UV_HANDLE_ZERO_READ                   = 0x00040000,
    104   UV_HANDLE_EMULATE_IOCP                = 0x00080000,
    105   UV_HANDLE_BLOCKING_WRITES             = 0x00100000,
    106   UV_HANDLE_CANCELLATION_PENDING        = 0x00200000,
    107 
    108   /* Used by uv_tcp_t and uv_udp_t handles */
    109   UV_HANDLE_IPV6                        = 0x00400000,
    110 
    111   /* Only used by uv_tcp_t handles. */
    112   UV_HANDLE_TCP_NODELAY                 = 0x01000000,
    113   UV_HANDLE_TCP_KEEPALIVE               = 0x02000000,
    114   UV_HANDLE_TCP_SINGLE_ACCEPT           = 0x04000000,
    115   UV_HANDLE_TCP_ACCEPT_STATE_CHANGING   = 0x08000000,
    116   UV_HANDLE_SHARED_TCP_SOCKET           = 0x10000000,
    117 
    118   /* Only used by uv_udp_t handles. */
    119   UV_HANDLE_UDP_PROCESSING              = 0x01000000,
    120   UV_HANDLE_UDP_CONNECTED               = 0x02000000,
    121   UV_HANDLE_UDP_RECVMMSG                = 0x04000000,
    122 
    123   /* Only used by uv_pipe_t handles. */
    124   UV_HANDLE_NON_OVERLAPPED_PIPE         = 0x01000000,
    125   UV_HANDLE_PIPESERVER                  = 0x02000000,
    126 
    127   /* Only used by uv_tty_t handles. */
    128   UV_HANDLE_TTY_READABLE                = 0x01000000,
    129   UV_HANDLE_UNUSED0                     = 0x02000000,
    130   UV_HANDLE_TTY_SAVED_POSITION          = 0x04000000,
    131   UV_HANDLE_TTY_SAVED_ATTRIBUTES        = 0x08000000,
    132 
    133   /* Only used by uv_signal_t handles. */
    134   UV_SIGNAL_ONE_SHOT_DISPATCHED         = 0x01000000,
    135   UV_SIGNAL_ONE_SHOT                    = 0x02000000,
    136 
    137   /* Only used by uv_poll_t handles. */
    138   UV_HANDLE_POLL_SLOW                   = 0x01000000,
    139 
    140   /* Only used by uv_process_t handles. */
    141   UV_HANDLE_REAP                        = 0x10000000
    142 };
    143 
    144 static inline int uv__is_raw_tty_mode(uv_tty_mode_t m) {
    145   return m == UV_TTY_MODE_RAW || m == UV_TTY_MODE_RAW_VT;
    146 }
    147 
    148 int uv__loop_configure(uv_loop_t* loop, uv_loop_option option, va_list ap);
    149 
    150 void uv__loop_close(uv_loop_t* loop);
    151 
    152 int uv__read_start(uv_stream_t* stream,
    153                    uv_alloc_cb alloc_cb,
    154                    uv_read_cb read_cb);
    155 
    156 int uv__tcp_bind(uv_tcp_t* tcp,
    157                  const struct sockaddr* addr,
    158                  unsigned int addrlen,
    159                  unsigned int flags);
    160 
    161 int uv__tcp_connect(uv_connect_t* req,
    162                    uv_tcp_t* handle,
    163                    const struct sockaddr* addr,
    164                    unsigned int addrlen,
    165                    uv_connect_cb cb);
    166 
    167 int uv__udp_init_ex(uv_loop_t* loop,
    168                     uv_udp_t* handle,
    169                     unsigned flags,
    170                     int domain);
    171 
    172 int uv__udp_bind(uv_udp_t* handle,
    173                  const struct sockaddr* addr,
    174                  unsigned int  addrlen,
    175                  unsigned int flags);
    176 
    177 int uv__udp_connect(uv_udp_t* handle,
    178                     const struct sockaddr* addr,
    179                     unsigned int addrlen);
    180 
    181 int uv__udp_disconnect(uv_udp_t* handle);
    182 
    183 int uv__udp_is_connected(uv_udp_t* handle);
    184 
    185 int uv__udp_send(uv_udp_send_t* req,
    186                  uv_udp_t* handle,
    187                  const uv_buf_t bufs[],
    188                  unsigned int nbufs,
    189                  const struct sockaddr* addr,
    190                  unsigned int addrlen,
    191                  uv_udp_send_cb send_cb);
    192 
    193 int uv__udp_try_send(uv_udp_t* handle,
    194                      const uv_buf_t bufs[],
    195                      unsigned int nbufs,
    196                      const struct sockaddr* addr,
    197                      unsigned int addrlen);
    198 
    199 int uv__udp_try_send2(uv_udp_t* handle,
    200                       unsigned int count,
    201                       uv_buf_t* bufs[/*count*/],
    202                       unsigned int nbufs[/*count*/],
    203                       struct sockaddr* addrs[/*count*/]);
    204 
    205 int uv__udp_recv_start(uv_udp_t* handle, uv_alloc_cb alloccb,
    206                        uv_udp_recv_cb recv_cb);
    207 
    208 int uv__udp_recv_stop(uv_udp_t* handle);
    209 
    210 void uv__fs_poll_close(uv_fs_poll_t* handle);
    211 
    212 int uv__getaddrinfo_translate_error(int sys_err);    /* EAI_* error. */
    213 
    214 enum uv__work_kind {
    215   UV__WORK_CPU,
    216   UV__WORK_FAST_IO,
    217   UV__WORK_SLOW_IO
    218 };
    219 
    220 void uv__work_submit(uv_loop_t* loop,
    221                      struct uv__work *w,
    222                      enum uv__work_kind kind,
    223                      void (*work)(struct uv__work *w),
    224                      void (*done)(struct uv__work *w, int status));
    225 
    226 void uv__work_done(uv_async_t* handle);
    227 
    228 size_t uv__count_bufs(const uv_buf_t bufs[], unsigned int nbufs);
    229 
    230 int uv__socket_sockopt(uv_handle_t* handle, int optname, int* value);
    231 
    232 void uv__fs_scandir_cleanup(uv_fs_t* req);
    233 void uv__fs_readdir_cleanup(uv_fs_t* req);
    234 uv_dirent_type_t uv__fs_get_dirent_type(uv__dirent_t* dent);
    235 
    236 int uv__next_timeout(const uv_loop_t* loop);
    237 void uv__run_timers(uv_loop_t* loop);
    238 void uv__timer_close(uv_timer_t* handle);
    239 
    240 void uv__process_title_cleanup(void);
    241 void uv__signal_cleanup(void);
    242 void uv__threadpool_cleanup(void);
    243 
    244 #define uv__has_active_reqs(loop)                                             \
    245   ((loop)->active_reqs.count > 0)
    246 
    247 #define uv__req_register(loop)                                                \
    248   do {                                                                        \
    249     (loop)->active_reqs.count++;                                              \
    250   }                                                                           \
    251   while (0)
    252 
    253 #define uv__req_unregister(loop)                                              \
    254   do {                                                                        \
    255     assert(uv__has_active_reqs(loop));                                        \
    256     (loop)->active_reqs.count--;                                              \
    257   }                                                                           \
    258   while (0)
    259 
    260 #define uv__has_active_handles(loop)                                          \
    261   ((loop)->active_handles > 0)
    262 
    263 #define uv__active_handle_add(h)                                              \
    264   do {                                                                        \
    265     (h)->loop->active_handles++;                                              \
    266   }                                                                           \
    267   while (0)
    268 
    269 #define uv__active_handle_rm(h)                                               \
    270   do {                                                                        \
    271     (h)->loop->active_handles--;                                              \
    272   }                                                                           \
    273   while (0)
    274 
    275 #define uv__is_active(h)                                                      \
    276   (((h)->flags & UV_HANDLE_ACTIVE) != 0)
    277 
    278 #define uv__is_closing(h)                                                     \
    279   (((h)->flags & (UV_HANDLE_CLOSING | UV_HANDLE_CLOSED)) != 0)
    280 
    281 #if defined(_WIN32)
    282 # define uv__is_stream_shutting(h)                                            \
    283   (h->stream.conn.shutdown_req != NULL)
    284 #else
    285 # define uv__is_stream_shutting(h)                                            \
    286   (h->shutdown_req != NULL)
    287 #endif
    288 
    289 #define uv__handle_start(h)                                                   \
    290   do {                                                                        \
    291     if (((h)->flags & UV_HANDLE_ACTIVE) != 0) break;                          \
    292     (h)->flags |= UV_HANDLE_ACTIVE;                                           \
    293     if (((h)->flags & UV_HANDLE_REF) != 0) uv__active_handle_add(h);          \
    294   }                                                                           \
    295   while (0)
    296 
    297 #define uv__handle_stop(h)                                                    \
    298   do {                                                                        \
    299     if (((h)->flags & UV_HANDLE_ACTIVE) == 0) break;                          \
    300     (h)->flags &= ~UV_HANDLE_ACTIVE;                                          \
    301     if (((h)->flags & UV_HANDLE_REF) != 0) uv__active_handle_rm(h);           \
    302   }                                                                           \
    303   while (0)
    304 
    305 #define uv__handle_ref(h)                                                     \
    306   do {                                                                        \
    307     if (((h)->flags & UV_HANDLE_REF) != 0) break;                             \
    308     (h)->flags |= UV_HANDLE_REF;                                              \
    309     if (((h)->flags & UV_HANDLE_CLOSING) != 0) break;                         \
    310     if (((h)->flags & UV_HANDLE_ACTIVE) != 0) uv__active_handle_add(h);       \
    311   }                                                                           \
    312   while (0)
    313 
    314 #define uv__handle_unref(h)                                                   \
    315   do {                                                                        \
    316     if (((h)->flags & UV_HANDLE_REF) == 0) break;                             \
    317     (h)->flags &= ~UV_HANDLE_REF;                                             \
    318     if (((h)->flags & UV_HANDLE_CLOSING) != 0) break;                         \
    319     if (((h)->flags & UV_HANDLE_ACTIVE) != 0) uv__active_handle_rm(h);        \
    320   }                                                                           \
    321   while (0)
    322 
    323 #define uv__has_ref(h)                                                        \
    324   (((h)->flags & UV_HANDLE_REF) != 0)
    325 
    326 #if defined(_WIN32)
    327 # define uv__handle_platform_init(h) ((h)->u.fd = -1)
    328 #else
    329 # define uv__handle_platform_init(h) ((h)->next_closing = NULL)
    330 #endif
    331 
    332 #define uv__handle_init(loop_, h, type_)                                      \
    333   do {                                                                        \
    334     (h)->loop = (loop_);                                                      \
    335     (h)->type = (type_);                                                      \
    336     (h)->flags = UV_HANDLE_REF;  /* Ref the loop when active. */              \
    337     uv__queue_insert_tail(&(loop_)->handle_queue, &(h)->handle_queue);        \
    338     uv__handle_platform_init(h);                                              \
    339   }                                                                           \
    340   while (0)
    341 
    342 /* Note: uses an open-coded version of SET_REQ_SUCCESS() because of
    343  * a circular dependency between src/uv-common.h and src/win/internal.h.
    344  */
    345 #if defined(_WIN32)
    346 # define UV_REQ_INIT(req, typ)                                                \
    347   do {                                                                        \
    348     (req)->type = (typ);                                                      \
    349     (req)->u.io.overlapped.Internal = 0;  /* SET_REQ_SUCCESS() */             \
    350   }                                                                           \
    351   while (0)
    352 #else
    353 # define UV_REQ_INIT(req, typ)                                                \
    354   do {                                                                        \
    355     (req)->type = (typ);                                                      \
    356   }                                                                           \
    357   while (0)
    358 #endif
    359 
    360 #define uv__req_init(loop, req, typ)                                          \
    361   do {                                                                        \
    362     UV_REQ_INIT(req, typ);                                                    \
    363     uv__req_register(loop);                                                   \
    364   }                                                                           \
    365   while (0)
    366 
    367 #define uv__get_internal_fields(loop)                                         \
    368   ((uv__loop_internal_fields_t*) loop->internal_fields)
    369 
    370 #define uv__get_loop_metrics(loop)                                            \
    371   (&uv__get_internal_fields(loop)->loop_metrics)
    372 
    373 #define uv__metrics_inc_loop_count(loop)                                      \
    374   do {                                                                        \
    375     uv__get_loop_metrics(loop)->metrics.loop_count++;                         \
    376   } while (0)
    377 
    378 #define uv__metrics_inc_events(loop, e)                                       \
    379   do {                                                                        \
    380     uv__get_loop_metrics(loop)->metrics.events += (e);                        \
    381   } while (0)
    382 
    383 #define uv__metrics_inc_events_waiting(loop, e)                               \
    384   do {                                                                        \
    385     uv__get_loop_metrics(loop)->metrics.events_waiting += (e);                \
    386   } while (0)
    387 
    388 /* Allocator prototypes */
    389 void *uv__calloc(size_t count, size_t size);
    390 char *uv__strdup(const char* s);
    391 char *uv__strndup(const char* s, size_t n);
    392 void* uv__malloc(size_t size);
    393 void uv__free(void* ptr);
    394 void* uv__realloc(void* ptr, size_t size);
    395 void* uv__reallocf(void* ptr, size_t size);
    396 
    397 typedef struct uv__loop_metrics_s uv__loop_metrics_t;
    398 typedef struct uv__loop_internal_fields_s uv__loop_internal_fields_t;
    399 
    400 struct uv__loop_metrics_s {
    401   uv_metrics_t metrics;
    402   uint64_t provider_entry_time;
    403   uint64_t provider_idle_time;
    404   uv_mutex_t lock;
    405 };
    406 
    407 void uv__metrics_update_idle_time(uv_loop_t* loop);
    408 void uv__metrics_set_provider_entry_time(uv_loop_t* loop);
    409 
    410 #ifdef __linux__
    411 struct uv__iou {
    412   uint32_t* sqhead;
    413   uint32_t* sqtail;
    414   uint32_t sqmask;
    415   uint32_t* sqflags;
    416   uint32_t* cqhead;
    417   uint32_t* cqtail;
    418   uint32_t cqmask;
    419   void* sq;   /* pointer to munmap() on event loop teardown */
    420   void* cqe;  /* pointer to array of struct uv__io_uring_cqe */
    421   void* sqe;  /* pointer to array of struct uv__io_uring_sqe */
    422   size_t sqlen;
    423   size_t cqlen;
    424   size_t maxlen;
    425   size_t sqelen;
    426   int ringfd;
    427   uint32_t in_flight;
    428 };
    429 #endif  /* __linux__ */
    430 
    431 struct uv__loop_internal_fields_s {
    432   unsigned int flags;
    433   uv__loop_metrics_t loop_metrics;
    434   int current_timeout;
    435 #ifdef __linux__
    436   struct uv__iou ctl;
    437   struct uv__iou iou;
    438   void* inv;  /* used by uv__platform_invalidate_fd() */
    439 #endif  /* __linux__ */
    440 };
    441 
    442 #if defined(_WIN32)
    443 # define UV_PTHREAD_MAX_NAMELEN_NP 32767
    444 #elif defined(__APPLE__)
    445 # define UV_PTHREAD_MAX_NAMELEN_NP 64
    446 #elif defined(__NetBSD__) || defined(__illumos__)
    447 # define UV_PTHREAD_MAX_NAMELEN_NP PTHREAD_MAX_NAMELEN_NP
    448 #elif defined (__linux__)
    449 # define UV_PTHREAD_MAX_NAMELEN_NP 16
    450 #elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__DragonFly__)
    451 # define UV_PTHREAD_MAX_NAMELEN_NP (MAXCOMLEN + 1)
    452 #else
    453 # define UV_PTHREAD_MAX_NAMELEN_NP 16
    454 #endif
    455 
    456 /* Open-coded so downstream users don't have to link libm. */
    457 static inline int uv__isinf(double d) {
    458   uint64_t v;
    459 
    460   STATIC_ASSERT(sizeof(v) == sizeof(d));
    461   memcpy(&v, &d, sizeof(v));
    462   return (v << 1 >> 53) == 2047 && !(v << 12);
    463 }
    464 
    465 /* Open-coded so downstream users don't have to link libm. */
    466 static inline int uv__isnan(double d) {
    467   uint64_t v;
    468 
    469   STATIC_ASSERT(sizeof(v) == sizeof(d));
    470   memcpy(&v, &d, sizeof(v));
    471   return (v << 1 >> 53) == 2047 && !!(v << 12);
    472 }
    473 
    474 #endif /* UV_COMMON_H_ */
    475