1e66f31c5Sopenharmony_ci/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. 2e66f31c5Sopenharmony_ci * 3e66f31c5Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a copy 4e66f31c5Sopenharmony_ci * of this software and associated documentation files (the "Software"), to 5e66f31c5Sopenharmony_ci * deal in the Software without restriction, including without limitation the 6e66f31c5Sopenharmony_ci * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7e66f31c5Sopenharmony_ci * sell copies of the Software, and to permit persons to whom the Software is 8e66f31c5Sopenharmony_ci * furnished to do so, subject to the following conditions: 9e66f31c5Sopenharmony_ci * 10e66f31c5Sopenharmony_ci * The above copyright notice and this permission notice shall be included in 11e66f31c5Sopenharmony_ci * all copies or substantial portions of the Software. 12e66f31c5Sopenharmony_ci * 13e66f31c5Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14e66f31c5Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15e66f31c5Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16e66f31c5Sopenharmony_ci * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17e66f31c5Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18e66f31c5Sopenharmony_ci * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19e66f31c5Sopenharmony_ci * IN THE SOFTWARE. 20e66f31c5Sopenharmony_ci */ 21e66f31c5Sopenharmony_ci 22e66f31c5Sopenharmony_ci#include "uv.h" 23e66f31c5Sopenharmony_ci#include "uv/tree.h" 24e66f31c5Sopenharmony_ci#include "uv_log.h" 25e66f31c5Sopenharmony_ci#include "internal.h" 26e66f31c5Sopenharmony_ci#include "heap-inl.h" 27e66f31c5Sopenharmony_ci#include <stdlib.h> 28e66f31c5Sopenharmony_ci#include <string.h> 29e66f31c5Sopenharmony_ci#include <unistd.h> 30e66f31c5Sopenharmony_ci 31e66f31c5Sopenharmony_ciint uv_loop_init(uv_loop_t* loop) { 32e66f31c5Sopenharmony_ci uv__loop_internal_fields_t* lfields; 33e66f31c5Sopenharmony_ci void* saved_data; 34e66f31c5Sopenharmony_ci int err; 35e66f31c5Sopenharmony_ci 36e66f31c5Sopenharmony_ci UV_LOGI("init:%{public}zu", (size_t)loop); 37e66f31c5Sopenharmony_ci saved_data = loop->data; 38e66f31c5Sopenharmony_ci memset(loop, 0, sizeof(*loop)); 39e66f31c5Sopenharmony_ci loop->data = saved_data; 40e66f31c5Sopenharmony_ci 41e66f31c5Sopenharmony_ci lfields = (uv__loop_internal_fields_t*) uv__calloc(1, sizeof(*lfields)); 42e66f31c5Sopenharmony_ci if (lfields == NULL) 43e66f31c5Sopenharmony_ci return UV_ENOMEM; 44e66f31c5Sopenharmony_ci loop->internal_fields = lfields; 45e66f31c5Sopenharmony_ci 46e66f31c5Sopenharmony_ci err = uv_mutex_init(&lfields->loop_metrics.lock); 47e66f31c5Sopenharmony_ci if (err) 48e66f31c5Sopenharmony_ci goto fail_metrics_mutex_init; 49e66f31c5Sopenharmony_ci memset(&lfields->loop_metrics.metrics, 50e66f31c5Sopenharmony_ci 0, 51e66f31c5Sopenharmony_ci sizeof(lfields->loop_metrics.metrics)); 52e66f31c5Sopenharmony_ci 53e66f31c5Sopenharmony_ci heap_init((struct heap*) &loop->timer_heap); 54e66f31c5Sopenharmony_ci uv__queue_init(&loop->wq); 55e66f31c5Sopenharmony_ci#ifdef USE_FFRT 56e66f31c5Sopenharmony_ci uv__loop_internal_fields_t* lfields_qos = uv__get_internal_fields(loop); 57e66f31c5Sopenharmony_ci uv__queue_init(&(lfields_qos->wq_sub[uv_qos_background])); 58e66f31c5Sopenharmony_ci uv__queue_init(&(lfields_qos->wq_sub[uv_qos_utility])); 59e66f31c5Sopenharmony_ci uv__queue_init(&(lfields_qos->wq_sub[uv_qos_default])); 60e66f31c5Sopenharmony_ci uv__queue_init(&(lfields_qos->wq_sub[uv_qos_user_initiated])); 61e66f31c5Sopenharmony_ci#endif 62e66f31c5Sopenharmony_ci 63e66f31c5Sopenharmony_ci uv__queue_init(&loop->idle_handles); 64e66f31c5Sopenharmony_ci uv__queue_init(&loop->async_handles); 65e66f31c5Sopenharmony_ci uv__queue_init(&loop->check_handles); 66e66f31c5Sopenharmony_ci uv__queue_init(&loop->prepare_handles); 67e66f31c5Sopenharmony_ci uv__queue_init(&loop->handle_queue); 68e66f31c5Sopenharmony_ci 69e66f31c5Sopenharmony_ci loop->active_handles = 0; 70e66f31c5Sopenharmony_ci loop->active_reqs.count = 0; 71e66f31c5Sopenharmony_ci loop->nfds = 0; 72e66f31c5Sopenharmony_ci loop->watchers = NULL; 73e66f31c5Sopenharmony_ci loop->nwatchers = 0; 74e66f31c5Sopenharmony_ci uv__queue_init(&loop->pending_queue); 75e66f31c5Sopenharmony_ci uv__queue_init(&loop->watcher_queue); 76e66f31c5Sopenharmony_ci 77e66f31c5Sopenharmony_ci loop->closing_handles = NULL; 78e66f31c5Sopenharmony_ci uv__update_time(loop); 79e66f31c5Sopenharmony_ci loop->async_io_watcher.fd = -1; 80e66f31c5Sopenharmony_ci loop->async_wfd = -1; 81e66f31c5Sopenharmony_ci loop->signal_pipefd[0] = -1; 82e66f31c5Sopenharmony_ci loop->signal_pipefd[1] = -1; 83e66f31c5Sopenharmony_ci loop->backend_fd = -1; 84e66f31c5Sopenharmony_ci loop->emfile_fd = -1; 85e66f31c5Sopenharmony_ci 86e66f31c5Sopenharmony_ci loop->timer_counter = 0; 87e66f31c5Sopenharmony_ci loop->stop_flag = 0; 88e66f31c5Sopenharmony_ci 89e66f31c5Sopenharmony_ci err = uv__platform_loop_init(loop); 90e66f31c5Sopenharmony_ci if (err) 91e66f31c5Sopenharmony_ci goto fail_platform_init; 92e66f31c5Sopenharmony_ci 93e66f31c5Sopenharmony_ci uv__signal_global_once_init(); 94e66f31c5Sopenharmony_ci err = uv__process_init(loop); 95e66f31c5Sopenharmony_ci if (err) 96e66f31c5Sopenharmony_ci goto fail_signal_init; 97e66f31c5Sopenharmony_ci uv__queue_init(&loop->process_handles); 98e66f31c5Sopenharmony_ci 99e66f31c5Sopenharmony_ci err = uv_rwlock_init(&loop->cloexec_lock); 100e66f31c5Sopenharmony_ci if (err) 101e66f31c5Sopenharmony_ci goto fail_rwlock_init; 102e66f31c5Sopenharmony_ci 103e66f31c5Sopenharmony_ci err = uv_mutex_init(&loop->wq_mutex); 104e66f31c5Sopenharmony_ci if (err) 105e66f31c5Sopenharmony_ci goto fail_mutex_init; 106e66f31c5Sopenharmony_ci 107e66f31c5Sopenharmony_ci err = uv_async_init(loop, &loop->wq_async, uv__work_done); 108e66f31c5Sopenharmony_ci if (err) 109e66f31c5Sopenharmony_ci goto fail_async_init; 110e66f31c5Sopenharmony_ci 111e66f31c5Sopenharmony_ci uv__handle_unref(&loop->wq_async); 112e66f31c5Sopenharmony_ci loop->wq_async.flags |= UV_HANDLE_INTERNAL; 113e66f31c5Sopenharmony_ci 114e66f31c5Sopenharmony_ci loop->magic = UV_LOOP_MAGIC; 115e66f31c5Sopenharmony_ci return 0; 116e66f31c5Sopenharmony_ci 117e66f31c5Sopenharmony_cifail_async_init: 118e66f31c5Sopenharmony_ci uv_mutex_destroy(&loop->wq_mutex); 119e66f31c5Sopenharmony_ci 120e66f31c5Sopenharmony_cifail_mutex_init: 121e66f31c5Sopenharmony_ci uv_rwlock_destroy(&loop->cloexec_lock); 122e66f31c5Sopenharmony_ci 123e66f31c5Sopenharmony_cifail_rwlock_init: 124e66f31c5Sopenharmony_ci uv__signal_loop_cleanup(loop); 125e66f31c5Sopenharmony_ci 126e66f31c5Sopenharmony_cifail_signal_init: 127e66f31c5Sopenharmony_ci uv__platform_loop_delete(loop); 128e66f31c5Sopenharmony_ci 129e66f31c5Sopenharmony_cifail_platform_init: 130e66f31c5Sopenharmony_ci uv_mutex_destroy(&lfields->loop_metrics.lock); 131e66f31c5Sopenharmony_ci 132e66f31c5Sopenharmony_cifail_metrics_mutex_init: 133e66f31c5Sopenharmony_ci uv__free(lfields); 134e66f31c5Sopenharmony_ci loop->internal_fields = NULL; 135e66f31c5Sopenharmony_ci 136e66f31c5Sopenharmony_ci uv__free(loop->watchers); 137e66f31c5Sopenharmony_ci loop->nwatchers = 0; 138e66f31c5Sopenharmony_ci return err; 139e66f31c5Sopenharmony_ci} 140e66f31c5Sopenharmony_ci 141e66f31c5Sopenharmony_ci 142e66f31c5Sopenharmony_ciint uv_loop_fork(uv_loop_t* loop) { 143e66f31c5Sopenharmony_ci int err; 144e66f31c5Sopenharmony_ci unsigned int i; 145e66f31c5Sopenharmony_ci uv__io_t* w; 146e66f31c5Sopenharmony_ci 147e66f31c5Sopenharmony_ci err = uv__io_fork(loop); 148e66f31c5Sopenharmony_ci if (err) 149e66f31c5Sopenharmony_ci return err; 150e66f31c5Sopenharmony_ci 151e66f31c5Sopenharmony_ci err = uv__async_fork(loop); 152e66f31c5Sopenharmony_ci if (err) 153e66f31c5Sopenharmony_ci return err; 154e66f31c5Sopenharmony_ci 155e66f31c5Sopenharmony_ci err = uv__signal_loop_fork(loop); 156e66f31c5Sopenharmony_ci if (err) 157e66f31c5Sopenharmony_ci return err; 158e66f31c5Sopenharmony_ci 159e66f31c5Sopenharmony_ci /* Rearm all the watchers that aren't re-queued by the above. */ 160e66f31c5Sopenharmony_ci for (i = 0; i < loop->nwatchers; i++) { 161e66f31c5Sopenharmony_ci w = loop->watchers[i]; 162e66f31c5Sopenharmony_ci if (w == NULL) 163e66f31c5Sopenharmony_ci continue; 164e66f31c5Sopenharmony_ci 165e66f31c5Sopenharmony_ci if (w->pevents != 0 && uv__queue_empty(&w->watcher_queue)) { 166e66f31c5Sopenharmony_ci w->events = 0; /* Force re-registration in uv__io_poll. */ 167e66f31c5Sopenharmony_ci uv__queue_insert_tail(&loop->watcher_queue, &w->watcher_queue); 168e66f31c5Sopenharmony_ci } 169e66f31c5Sopenharmony_ci } 170e66f31c5Sopenharmony_ci 171e66f31c5Sopenharmony_ci return 0; 172e66f31c5Sopenharmony_ci} 173e66f31c5Sopenharmony_ci 174e66f31c5Sopenharmony_ci 175e66f31c5Sopenharmony_civoid uv__loop_close(uv_loop_t* loop) { 176e66f31c5Sopenharmony_ci uv__loop_internal_fields_t* lfields; 177e66f31c5Sopenharmony_ci 178e66f31c5Sopenharmony_ci uv__signal_loop_cleanup(loop); 179e66f31c5Sopenharmony_ci uv__platform_loop_delete(loop); 180e66f31c5Sopenharmony_ci uv__async_stop(loop); 181e66f31c5Sopenharmony_ci 182e66f31c5Sopenharmony_ci if (loop->emfile_fd != -1) { 183e66f31c5Sopenharmony_ci uv__close(loop->emfile_fd); 184e66f31c5Sopenharmony_ci loop->emfile_fd = -1; 185e66f31c5Sopenharmony_ci } 186e66f31c5Sopenharmony_ci 187e66f31c5Sopenharmony_ci if (loop->backend_fd != -1) { 188e66f31c5Sopenharmony_ci#ifdef USE_OHOS_DFX 189e66f31c5Sopenharmony_ci fdsan_close_with_tag(loop->backend_fd, uv__get_addr_tag((void *)&loop->backend_fd)); 190e66f31c5Sopenharmony_ci#else 191e66f31c5Sopenharmony_ci uv__close(loop->backend_fd); 192e66f31c5Sopenharmony_ci#endif 193e66f31c5Sopenharmony_ci UV_LOGI("close:%{public}zu, backend_fd:%{public}d", (size_t)loop, loop->backend_fd); 194e66f31c5Sopenharmony_ci loop->backend_fd = -1; 195e66f31c5Sopenharmony_ci } 196e66f31c5Sopenharmony_ci 197e66f31c5Sopenharmony_ci uv_mutex_lock(&loop->wq_mutex); 198e66f31c5Sopenharmony_ci#ifndef USE_FFRT 199e66f31c5Sopenharmony_ci assert(uv__queue_empty(&loop->wq) && "thread pool work queue not empty!"); 200e66f31c5Sopenharmony_ci#endif 201e66f31c5Sopenharmony_ci assert(!uv__has_active_reqs(loop)); 202e66f31c5Sopenharmony_ci uv_mutex_unlock(&loop->wq_mutex); 203e66f31c5Sopenharmony_ci uv_mutex_destroy(&loop->wq_mutex); 204e66f31c5Sopenharmony_ci 205e66f31c5Sopenharmony_ci /* 206e66f31c5Sopenharmony_ci * Note that all thread pool stuff is finished at this point and 207e66f31c5Sopenharmony_ci * it is safe to just destroy rw lock 208e66f31c5Sopenharmony_ci */ 209e66f31c5Sopenharmony_ci uv_rwlock_destroy(&loop->cloexec_lock); 210e66f31c5Sopenharmony_ci 211e66f31c5Sopenharmony_ci#if 0 212e66f31c5Sopenharmony_ci assert(uv__queue_empty(&loop->pending_queue)); 213e66f31c5Sopenharmony_ci assert(uv__queue_empty(&loop->watcher_queue)); 214e66f31c5Sopenharmony_ci assert(loop->nfds == 0); 215e66f31c5Sopenharmony_ci#endif 216e66f31c5Sopenharmony_ci 217e66f31c5Sopenharmony_ci uv__free(loop->watchers); 218e66f31c5Sopenharmony_ci loop->watchers = NULL; 219e66f31c5Sopenharmony_ci loop->nwatchers = 0; 220e66f31c5Sopenharmony_ci 221e66f31c5Sopenharmony_ci lfields = uv__get_internal_fields(loop); 222e66f31c5Sopenharmony_ci uv_mutex_destroy(&lfields->loop_metrics.lock); 223e66f31c5Sopenharmony_ci uv__free(lfields); 224e66f31c5Sopenharmony_ci loop->internal_fields = NULL; 225e66f31c5Sopenharmony_ci loop->magic = ~UV_LOOP_MAGIC; 226e66f31c5Sopenharmony_ci} 227e66f31c5Sopenharmony_ci 228e66f31c5Sopenharmony_ci 229e66f31c5Sopenharmony_ciint uv__loop_configure(uv_loop_t* loop, uv_loop_option option, va_list ap) { 230e66f31c5Sopenharmony_ci uv__loop_internal_fields_t* lfields; 231e66f31c5Sopenharmony_ci 232e66f31c5Sopenharmony_ci lfields = uv__get_internal_fields(loop); 233e66f31c5Sopenharmony_ci if (option == UV_METRICS_IDLE_TIME) { 234e66f31c5Sopenharmony_ci lfields->flags |= UV_METRICS_IDLE_TIME; 235e66f31c5Sopenharmony_ci return 0; 236e66f31c5Sopenharmony_ci } 237e66f31c5Sopenharmony_ci 238e66f31c5Sopenharmony_ci if (option != UV_LOOP_BLOCK_SIGNAL) 239e66f31c5Sopenharmony_ci return UV_ENOSYS; 240e66f31c5Sopenharmony_ci 241e66f31c5Sopenharmony_ci if (va_arg(ap, int) != SIGPROF) 242e66f31c5Sopenharmony_ci return UV_EINVAL; 243e66f31c5Sopenharmony_ci 244e66f31c5Sopenharmony_ci loop->flags |= UV_LOOP_BLOCK_SIGPROF; 245e66f31c5Sopenharmony_ci return 0; 246e66f31c5Sopenharmony_ci} 247