11cb0ef41Sopenharmony_ci/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. 21cb0ef41Sopenharmony_ci * 31cb0ef41Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a copy 41cb0ef41Sopenharmony_ci * of this software and associated documentation files (the "Software"), to 51cb0ef41Sopenharmony_ci * deal in the Software without restriction, including without limitation the 61cb0ef41Sopenharmony_ci * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 71cb0ef41Sopenharmony_ci * sell copies of the Software, and to permit persons to whom the Software is 81cb0ef41Sopenharmony_ci * furnished to do so, subject to the following conditions: 91cb0ef41Sopenharmony_ci * 101cb0ef41Sopenharmony_ci * The above copyright notice and this permission notice shall be included in 111cb0ef41Sopenharmony_ci * all copies or substantial portions of the Software. 121cb0ef41Sopenharmony_ci * 131cb0ef41Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 141cb0ef41Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 151cb0ef41Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 161cb0ef41Sopenharmony_ci * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 171cb0ef41Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 181cb0ef41Sopenharmony_ci * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 191cb0ef41Sopenharmony_ci * IN THE SOFTWARE. 201cb0ef41Sopenharmony_ci */ 211cb0ef41Sopenharmony_ci 221cb0ef41Sopenharmony_ci#include "uv.h" 231cb0ef41Sopenharmony_ci#include "uv/tree.h" 241cb0ef41Sopenharmony_ci#include "internal.h" 251cb0ef41Sopenharmony_ci#include "heap-inl.h" 261cb0ef41Sopenharmony_ci#include <stdlib.h> 271cb0ef41Sopenharmony_ci#include <string.h> 281cb0ef41Sopenharmony_ci#include <unistd.h> 291cb0ef41Sopenharmony_ci 301cb0ef41Sopenharmony_ciint uv_loop_init(uv_loop_t* loop) { 311cb0ef41Sopenharmony_ci uv__loop_internal_fields_t* lfields; 321cb0ef41Sopenharmony_ci void* saved_data; 331cb0ef41Sopenharmony_ci int err; 341cb0ef41Sopenharmony_ci 351cb0ef41Sopenharmony_ci 361cb0ef41Sopenharmony_ci saved_data = loop->data; 371cb0ef41Sopenharmony_ci memset(loop, 0, sizeof(*loop)); 381cb0ef41Sopenharmony_ci loop->data = saved_data; 391cb0ef41Sopenharmony_ci 401cb0ef41Sopenharmony_ci lfields = (uv__loop_internal_fields_t*) uv__calloc(1, sizeof(*lfields)); 411cb0ef41Sopenharmony_ci if (lfields == NULL) 421cb0ef41Sopenharmony_ci return UV_ENOMEM; 431cb0ef41Sopenharmony_ci loop->internal_fields = lfields; 441cb0ef41Sopenharmony_ci 451cb0ef41Sopenharmony_ci err = uv_mutex_init(&lfields->loop_metrics.lock); 461cb0ef41Sopenharmony_ci if (err) 471cb0ef41Sopenharmony_ci goto fail_metrics_mutex_init; 481cb0ef41Sopenharmony_ci 491cb0ef41Sopenharmony_ci heap_init((struct heap*) &loop->timer_heap); 501cb0ef41Sopenharmony_ci QUEUE_INIT(&loop->wq); 511cb0ef41Sopenharmony_ci QUEUE_INIT(&loop->idle_handles); 521cb0ef41Sopenharmony_ci QUEUE_INIT(&loop->async_handles); 531cb0ef41Sopenharmony_ci QUEUE_INIT(&loop->check_handles); 541cb0ef41Sopenharmony_ci QUEUE_INIT(&loop->prepare_handles); 551cb0ef41Sopenharmony_ci QUEUE_INIT(&loop->handle_queue); 561cb0ef41Sopenharmony_ci 571cb0ef41Sopenharmony_ci loop->active_handles = 0; 581cb0ef41Sopenharmony_ci loop->active_reqs.count = 0; 591cb0ef41Sopenharmony_ci loop->nfds = 0; 601cb0ef41Sopenharmony_ci loop->watchers = NULL; 611cb0ef41Sopenharmony_ci loop->nwatchers = 0; 621cb0ef41Sopenharmony_ci QUEUE_INIT(&loop->pending_queue); 631cb0ef41Sopenharmony_ci QUEUE_INIT(&loop->watcher_queue); 641cb0ef41Sopenharmony_ci 651cb0ef41Sopenharmony_ci loop->closing_handles = NULL; 661cb0ef41Sopenharmony_ci uv__update_time(loop); 671cb0ef41Sopenharmony_ci loop->async_io_watcher.fd = -1; 681cb0ef41Sopenharmony_ci loop->async_wfd = -1; 691cb0ef41Sopenharmony_ci loop->signal_pipefd[0] = -1; 701cb0ef41Sopenharmony_ci loop->signal_pipefd[1] = -1; 711cb0ef41Sopenharmony_ci loop->backend_fd = -1; 721cb0ef41Sopenharmony_ci loop->emfile_fd = -1; 731cb0ef41Sopenharmony_ci 741cb0ef41Sopenharmony_ci loop->timer_counter = 0; 751cb0ef41Sopenharmony_ci loop->stop_flag = 0; 761cb0ef41Sopenharmony_ci 771cb0ef41Sopenharmony_ci err = uv__platform_loop_init(loop); 781cb0ef41Sopenharmony_ci if (err) 791cb0ef41Sopenharmony_ci goto fail_platform_init; 801cb0ef41Sopenharmony_ci 811cb0ef41Sopenharmony_ci uv__signal_global_once_init(); 821cb0ef41Sopenharmony_ci err = uv_signal_init(loop, &loop->child_watcher); 831cb0ef41Sopenharmony_ci if (err) 841cb0ef41Sopenharmony_ci goto fail_signal_init; 851cb0ef41Sopenharmony_ci 861cb0ef41Sopenharmony_ci uv__handle_unref(&loop->child_watcher); 871cb0ef41Sopenharmony_ci loop->child_watcher.flags |= UV_HANDLE_INTERNAL; 881cb0ef41Sopenharmony_ci QUEUE_INIT(&loop->process_handles); 891cb0ef41Sopenharmony_ci 901cb0ef41Sopenharmony_ci err = uv_rwlock_init(&loop->cloexec_lock); 911cb0ef41Sopenharmony_ci if (err) 921cb0ef41Sopenharmony_ci goto fail_rwlock_init; 931cb0ef41Sopenharmony_ci 941cb0ef41Sopenharmony_ci err = uv_mutex_init(&loop->wq_mutex); 951cb0ef41Sopenharmony_ci if (err) 961cb0ef41Sopenharmony_ci goto fail_mutex_init; 971cb0ef41Sopenharmony_ci 981cb0ef41Sopenharmony_ci err = uv_async_init(loop, &loop->wq_async, uv__work_done); 991cb0ef41Sopenharmony_ci if (err) 1001cb0ef41Sopenharmony_ci goto fail_async_init; 1011cb0ef41Sopenharmony_ci 1021cb0ef41Sopenharmony_ci uv__handle_unref(&loop->wq_async); 1031cb0ef41Sopenharmony_ci loop->wq_async.flags |= UV_HANDLE_INTERNAL; 1041cb0ef41Sopenharmony_ci 1051cb0ef41Sopenharmony_ci return 0; 1061cb0ef41Sopenharmony_ci 1071cb0ef41Sopenharmony_cifail_async_init: 1081cb0ef41Sopenharmony_ci uv_mutex_destroy(&loop->wq_mutex); 1091cb0ef41Sopenharmony_ci 1101cb0ef41Sopenharmony_cifail_mutex_init: 1111cb0ef41Sopenharmony_ci uv_rwlock_destroy(&loop->cloexec_lock); 1121cb0ef41Sopenharmony_ci 1131cb0ef41Sopenharmony_cifail_rwlock_init: 1141cb0ef41Sopenharmony_ci uv__signal_loop_cleanup(loop); 1151cb0ef41Sopenharmony_ci 1161cb0ef41Sopenharmony_cifail_signal_init: 1171cb0ef41Sopenharmony_ci uv__platform_loop_delete(loop); 1181cb0ef41Sopenharmony_ci 1191cb0ef41Sopenharmony_cifail_platform_init: 1201cb0ef41Sopenharmony_ci uv_mutex_destroy(&lfields->loop_metrics.lock); 1211cb0ef41Sopenharmony_ci 1221cb0ef41Sopenharmony_cifail_metrics_mutex_init: 1231cb0ef41Sopenharmony_ci uv__free(lfields); 1241cb0ef41Sopenharmony_ci loop->internal_fields = NULL; 1251cb0ef41Sopenharmony_ci 1261cb0ef41Sopenharmony_ci uv__free(loop->watchers); 1271cb0ef41Sopenharmony_ci loop->nwatchers = 0; 1281cb0ef41Sopenharmony_ci return err; 1291cb0ef41Sopenharmony_ci} 1301cb0ef41Sopenharmony_ci 1311cb0ef41Sopenharmony_ci 1321cb0ef41Sopenharmony_ciint uv_loop_fork(uv_loop_t* loop) { 1331cb0ef41Sopenharmony_ci int err; 1341cb0ef41Sopenharmony_ci unsigned int i; 1351cb0ef41Sopenharmony_ci uv__io_t* w; 1361cb0ef41Sopenharmony_ci 1371cb0ef41Sopenharmony_ci err = uv__io_fork(loop); 1381cb0ef41Sopenharmony_ci if (err) 1391cb0ef41Sopenharmony_ci return err; 1401cb0ef41Sopenharmony_ci 1411cb0ef41Sopenharmony_ci err = uv__async_fork(loop); 1421cb0ef41Sopenharmony_ci if (err) 1431cb0ef41Sopenharmony_ci return err; 1441cb0ef41Sopenharmony_ci 1451cb0ef41Sopenharmony_ci err = uv__signal_loop_fork(loop); 1461cb0ef41Sopenharmony_ci if (err) 1471cb0ef41Sopenharmony_ci return err; 1481cb0ef41Sopenharmony_ci 1491cb0ef41Sopenharmony_ci /* Rearm all the watchers that aren't re-queued by the above. */ 1501cb0ef41Sopenharmony_ci for (i = 0; i < loop->nwatchers; i++) { 1511cb0ef41Sopenharmony_ci w = loop->watchers[i]; 1521cb0ef41Sopenharmony_ci if (w == NULL) 1531cb0ef41Sopenharmony_ci continue; 1541cb0ef41Sopenharmony_ci 1551cb0ef41Sopenharmony_ci if (w->pevents != 0 && QUEUE_EMPTY(&w->watcher_queue)) { 1561cb0ef41Sopenharmony_ci w->events = 0; /* Force re-registration in uv__io_poll. */ 1571cb0ef41Sopenharmony_ci QUEUE_INSERT_TAIL(&loop->watcher_queue, &w->watcher_queue); 1581cb0ef41Sopenharmony_ci } 1591cb0ef41Sopenharmony_ci } 1601cb0ef41Sopenharmony_ci 1611cb0ef41Sopenharmony_ci return 0; 1621cb0ef41Sopenharmony_ci} 1631cb0ef41Sopenharmony_ci 1641cb0ef41Sopenharmony_ci 1651cb0ef41Sopenharmony_civoid uv__loop_close(uv_loop_t* loop) { 1661cb0ef41Sopenharmony_ci uv__loop_internal_fields_t* lfields; 1671cb0ef41Sopenharmony_ci 1681cb0ef41Sopenharmony_ci uv__signal_loop_cleanup(loop); 1691cb0ef41Sopenharmony_ci uv__platform_loop_delete(loop); 1701cb0ef41Sopenharmony_ci uv__async_stop(loop); 1711cb0ef41Sopenharmony_ci 1721cb0ef41Sopenharmony_ci if (loop->emfile_fd != -1) { 1731cb0ef41Sopenharmony_ci uv__close(loop->emfile_fd); 1741cb0ef41Sopenharmony_ci loop->emfile_fd = -1; 1751cb0ef41Sopenharmony_ci } 1761cb0ef41Sopenharmony_ci 1771cb0ef41Sopenharmony_ci if (loop->backend_fd != -1) { 1781cb0ef41Sopenharmony_ci uv__close(loop->backend_fd); 1791cb0ef41Sopenharmony_ci loop->backend_fd = -1; 1801cb0ef41Sopenharmony_ci } 1811cb0ef41Sopenharmony_ci 1821cb0ef41Sopenharmony_ci uv_mutex_lock(&loop->wq_mutex); 1831cb0ef41Sopenharmony_ci assert(QUEUE_EMPTY(&loop->wq) && "thread pool work queue not empty!"); 1841cb0ef41Sopenharmony_ci assert(!uv__has_active_reqs(loop)); 1851cb0ef41Sopenharmony_ci uv_mutex_unlock(&loop->wq_mutex); 1861cb0ef41Sopenharmony_ci uv_mutex_destroy(&loop->wq_mutex); 1871cb0ef41Sopenharmony_ci 1881cb0ef41Sopenharmony_ci /* 1891cb0ef41Sopenharmony_ci * Note that all thread pool stuff is finished at this point and 1901cb0ef41Sopenharmony_ci * it is safe to just destroy rw lock 1911cb0ef41Sopenharmony_ci */ 1921cb0ef41Sopenharmony_ci uv_rwlock_destroy(&loop->cloexec_lock); 1931cb0ef41Sopenharmony_ci 1941cb0ef41Sopenharmony_ci#if 0 1951cb0ef41Sopenharmony_ci assert(QUEUE_EMPTY(&loop->pending_queue)); 1961cb0ef41Sopenharmony_ci assert(QUEUE_EMPTY(&loop->watcher_queue)); 1971cb0ef41Sopenharmony_ci assert(loop->nfds == 0); 1981cb0ef41Sopenharmony_ci#endif 1991cb0ef41Sopenharmony_ci 2001cb0ef41Sopenharmony_ci uv__free(loop->watchers); 2011cb0ef41Sopenharmony_ci loop->watchers = NULL; 2021cb0ef41Sopenharmony_ci loop->nwatchers = 0; 2031cb0ef41Sopenharmony_ci 2041cb0ef41Sopenharmony_ci lfields = uv__get_internal_fields(loop); 2051cb0ef41Sopenharmony_ci uv_mutex_destroy(&lfields->loop_metrics.lock); 2061cb0ef41Sopenharmony_ci uv__free(lfields); 2071cb0ef41Sopenharmony_ci loop->internal_fields = NULL; 2081cb0ef41Sopenharmony_ci} 2091cb0ef41Sopenharmony_ci 2101cb0ef41Sopenharmony_ci 2111cb0ef41Sopenharmony_ciint uv__loop_configure(uv_loop_t* loop, uv_loop_option option, va_list ap) { 2121cb0ef41Sopenharmony_ci uv__loop_internal_fields_t* lfields; 2131cb0ef41Sopenharmony_ci 2141cb0ef41Sopenharmony_ci lfields = uv__get_internal_fields(loop); 2151cb0ef41Sopenharmony_ci if (option == UV_METRICS_IDLE_TIME) { 2161cb0ef41Sopenharmony_ci lfields->flags |= UV_METRICS_IDLE_TIME; 2171cb0ef41Sopenharmony_ci return 0; 2181cb0ef41Sopenharmony_ci } 2191cb0ef41Sopenharmony_ci 2201cb0ef41Sopenharmony_ci if (option != UV_LOOP_BLOCK_SIGNAL) 2211cb0ef41Sopenharmony_ci return UV_ENOSYS; 2221cb0ef41Sopenharmony_ci 2231cb0ef41Sopenharmony_ci if (va_arg(ap, int) != SIGPROF) 2241cb0ef41Sopenharmony_ci return UV_EINVAL; 2251cb0ef41Sopenharmony_ci 2261cb0ef41Sopenharmony_ci loop->flags |= UV_LOOP_BLOCK_SIGPROF; 2271cb0ef41Sopenharmony_ci return 0; 2281cb0ef41Sopenharmony_ci} 229