1e41f4b71Sopenharmony_ci# libuv
2e41f4b71Sopenharmony_ci
3e41f4b71Sopenharmony_ci## Introduction
4e41f4b71Sopenharmony_ci
5e41f4b71Sopenharmony_ci[libuv](http://libuv.org/) is a cross-platform library that implements asynchronous I/O based on event loops. It applies to network programming and file system operations. It is one of the core libraries of Node.js and has been widely used by other software projects.
6e41f4b71Sopenharmony_ci
7e41f4b71Sopenharmony_ci## Supported Capabilities
8e41f4b71Sopenharmony_ci
9e41f4b71Sopenharmony_ci- Event-driven asynchronous I/O across platforms.
10e41f4b71Sopenharmony_ci
11e41f4b71Sopenharmony_ci- Support for standard library interfaces.
12e41f4b71Sopenharmony_ci
13e41f4b71Sopenharmony_ci
14e41f4b71Sopenharmony_ci## Available APIs
15e41f4b71Sopenharmony_ci
16e41f4b71Sopenharmony_ciFor details, see [API documentation](http://docs.libuv.org/en/v1.x/api.html).
17e41f4b71Sopenharmony_ci
18e41f4b71Sopenharmony_ci## Background of Introducing libuv to OpenHarmony
19e41f4b71Sopenharmony_ci
20e41f4b71Sopenharmony_ciOpenHarmony introduced Node-API of Node.js in its earlier versions to facilitate Node.js developers to extend their JavaScript APIs with OpenHarmony. It also introduced libuv of Node.js to implement event loops.
21e41f4b71Sopenharmony_ci
22e41f4b71Sopenharmony_ci### Evolution Trend
23e41f4b71Sopenharmony_ci
24e41f4b71Sopenharmony_ciTo address the scheduling issues caused when the application main thread has an event loop that contains **uvloop**, we plan to normalize the event loops in the application model to allow only one task queue in the application main loop with task priorities controlled.
25e41f4b71Sopenharmony_ci
26e41f4b71Sopenharmony_ciAvoid using the NDK of libuv to perform operations on the application main loop obtained by **napi_get_uv_event_loop** (deprecated in API version 12). This may cause various problems and large amount of workload to address compatibility issues.
27e41f4b71Sopenharmony_ci
28e41f4b71Sopenharmony_ciIf you want to implement interaction with the main thread cyclically, for example, inserting a task, use [APIs provided by Node-API](../../napi/napi-data-types-interfaces.md).
29e41f4b71Sopenharmony_ci
30e41f4b71Sopenharmony_ciOpenHarmony will continue to provide capabilities of interacting with the main thread and extending JS APIs through Node-API for a long period of time, but shields the event loops used in the implementation layer. Although **napi_get_uv_event_loop** is deprecated in API version 12, the main functional APIs of Node-API will be maintained for a long time and provide the same native behavior of Node-API, so that the developers who are familiar with the node.js extension mechanism can easily expand their code to OpenHarmony.
31e41f4b71Sopenharmony_ci
32e41f4b71Sopenharmony_ciIf you are familiar with libuv and can handle memory management and multithreading problems, you can use libuv to develop your services on OpenHarmony. Unless otherwise required, you do not need to import the libuv library to your application project.
33e41f4b71Sopenharmony_ci
34e41f4b71Sopenharmony_ci### Current Problems and Solutions
35e41f4b71Sopenharmony_ci
36e41f4b71Sopenharmony_ciAccording to the existing mechanism, only one event loop can exist in a thread. To ensure proper running of the main event loop of the system application, the main event loop listens for the FD events in the JS environment and executes `uv_run` only when an FD event is reported. As a result, certain functions that depend on **uvloop** cannot take effect.
37e41f4b71Sopenharmony_ci
38e41f4b71Sopenharmony_ciCommon scenarios and solutions are as follows:
39e41f4b71Sopenharmony_ci
40e41f4b71Sopenharmony_ci#### Scenario 1: The JS main thread throws an async task to a worker thread for execution, and executes the result returned by the JS code.
41e41f4b71Sopenharmony_ci
42e41f4b71Sopenharmony_ci**Example (incorrect)**
43e41f4b71Sopenharmony_ci
44e41f4b71Sopenharmony_ciCall **napi_get_uv_event_loop()** to obtain the system loop, and use libuv NDK APIs to implement related functions.
45e41f4b71Sopenharmony_ci
46e41f4b71Sopenharmony_ci```cpp
47e41f4b71Sopenharmony_ci#include "napi/native_api.h"
48e41f4b71Sopenharmony_ci#include "uv.h"
49e41f4b71Sopenharmony_ci#define LOG_DOMAIN 0X0202
50e41f4b71Sopenharmony_ci#define LOG_TAG "MyTag"
51e41f4b71Sopenharmony_ci#include <hilog/log.h>
52e41f4b71Sopenharmony_ci#include <thread>
53e41f4b71Sopenharmony_ci#include <sys/eventfd.h>
54e41f4b71Sopenharmony_ci#include <unistd.h>
55e41f4b71Sopenharmony_ci
56e41f4b71Sopenharmony_cistatic void execute(uv_work_t *work) {
57e41f4b71Sopenharmony_ci    OH_LOG_INFO(LOG_APP, "ohos in execute");
58e41f4b71Sopenharmony_ci}
59e41f4b71Sopenharmony_ci
60e41f4b71Sopenharmony_cistatic void complete(uv_work_t *work, int status) {
61e41f4b71Sopenharmony_ci    OH_LOG_INFO(LOG_APP, "ohos in complete"); 
62e41f4b71Sopenharmony_ci    delete work;
63e41f4b71Sopenharmony_ci}
64e41f4b71Sopenharmony_cistatic napi_value Add(napi_env env, napi_callback_info info)
65e41f4b71Sopenharmony_ci{
66e41f4b71Sopenharmony_ci    napi_value work_name;
67e41f4b71Sopenharmony_ci    uv_loop_s *loop = nullptr;
68e41f4b71Sopenharmony_ci    /* Obtain the uv_loop of the application JS main thread. */
69e41f4b71Sopenharmony_ci    napi_get_uv_event_loop(env, &loop);
70e41f4b71Sopenharmony_ci    uv_work_t *work = new uv_work_t;
71e41f4b71Sopenharmony_ci    int ret = uv_queue_work(loop, work, execute, complete);
72e41f4b71Sopenharmony_ci    if (ret != 0) {
73e41f4b71Sopenharmony_ci        OH_LOG_INFO(LOG_APP, "delete work");
74e41f4b71Sopenharmony_ci        delete work;
75e41f4b71Sopenharmony_ci    }
76e41f4b71Sopenharmony_ci    return 0;
77e41f4b71Sopenharmony_ci}
78e41f4b71Sopenharmony_ci
79e41f4b71Sopenharmony_ciEXTERN_C_START
80e41f4b71Sopenharmony_cistatic napi_value Init(napi_env env, napi_value exports){
81e41f4b71Sopenharmony_ci    napi_property_descriptor desc[] = {{"add", nullptr, Add, nullptr, nullptr, nullptr, napi_default, nullptr}};
82e41f4b71Sopenharmony_ci    napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
83e41f4b71Sopenharmony_ci    return exports;
84e41f4b71Sopenharmony_ciEXTERN_C_END
85e41f4b71Sopenharmony_ci    
86e41f4b71Sopenharmony_cistatic napi_module demoModule = {
87e41f4b71Sopenharmony_ci    .nm_version = 1,
88e41f4b71Sopenharmony_ci    .nm_flags = 0,
89e41f4b71Sopenharmony_ci    .nm_filename = nullptr,
90e41f4b71Sopenharmony_ci    .nm_register_func = Init,
91e41f4b71Sopenharmony_ci    .nm_modname = "entry",
92e41f4b71Sopenharmony_ci    .nm_priv = ((void *)0),
93e41f4b71Sopenharmony_ci    .reserved = {0},
94e41f4b71Sopenharmony_ci};
95e41f4b71Sopenharmony_ci
96e41f4b71Sopenharmony_ciextern "C" __attribute__((constructor)) void RegisterEntryModule(void){
97e41f4b71Sopenharmony_ci    napi_module_register(&demoModule);
98e41f4b71Sopenharmony_ci}
99e41f4b71Sopenharmony_ci```
100e41f4b71Sopenharmony_ci
101e41f4b71Sopenharmony_ci**Example (correct)**:
102e41f4b71Sopenharmony_ci
103e41f4b71Sopenharmony_ciUse **napi_create_async_work** and **napi_queue_async_work** together.
104e41f4b71Sopenharmony_ci
105e41f4b71Sopenharmony_ci```cpp
106e41f4b71Sopenharmony_ci#include "napi/native_api.h"
107e41f4b71Sopenharmony_ci#include "uv.h"
108e41f4b71Sopenharmony_ci#define LOG_DOMAIN 0X0202
109e41f4b71Sopenharmony_ci#define LOG_TAG "MyTag"
110e41f4b71Sopenharmony_ci#include <hilog/log.h>
111e41f4b71Sopenharmony_ci#include <thread>
112e41f4b71Sopenharmony_ci#include <sys/eventfd.h>
113e41f4b71Sopenharmony_ci#include <unistd.h>
114e41f4b71Sopenharmony_ciuv_loop_t *loop;
115e41f4b71Sopenharmony_cinapi_value jsCb;
116e41f4b71Sopenharmony_ciint fd = -1;
117e41f4b71Sopenharmony_ci
118e41f4b71Sopenharmony_cistatic napi_value Add(napi_env env, napi_callback_info info)
119e41f4b71Sopenharmony_ci{
120e41f4b71Sopenharmony_ci    napi_value work_name;
121e41f4b71Sopenharmony_ci    napi_async_work work;
122e41f4b71Sopenharmony_ci    napi_create_string_utf8(env, "ohos", NAPI_AUTO_LENGTH, &work_name);
123e41f4b71Sopenharmony_ci    /* The fourth parameter specifies the work task of the asynchronous thread, and the fifth parameter is the callback of the main thread. */
124e41f4b71Sopenharmony_ci    napi_create_async_work(env, nullptr, work_name, [](napi_env env, void* data){
125e41f4b71Sopenharmony_ci        OH_LOG_INFO(LOG_APP, "ohos in execute");
126e41f4b71Sopenharmony_ci    }, [](napi_env env, napi_status status, void *data){
127e41f4b71Sopenharmony_ci        /* The specific implementation is skipped. */
128e41f4b71Sopenharmony_ci        OH_LOG_INFO(LOG_APP, "ohos in complete");
129e41f4b71Sopenharmony_ci        napi_delete_async_work(env, (napi_async_work)data);
130e41f4b71Sopenharmony_ci    }, nullptr, &work);
131e41f4b71Sopenharmony_ci    /* Call napi_queue_async_work to trigger an async task. */
132e41f4b71Sopenharmony_ci    napi_queue_async_work(env, work);
133e41f4b71Sopenharmony_ci    return 0;
134e41f4b71Sopenharmony_ci}
135e41f4b71Sopenharmony_ci
136e41f4b71Sopenharmony_ciEXTERN_C_START
137e41f4b71Sopenharmony_cistatic napi_value Init(napi_env env, napi_value exports){
138e41f4b71Sopenharmony_ci    napi_property_descriptor desc[] = {{"add", nullptr, Add, nullptr, nullptr, nullptr, napi_default, nullptr}};
139e41f4b71Sopenharmony_ci    napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
140e41f4b71Sopenharmony_ci    return exports;
141e41f4b71Sopenharmony_ciEXTERN_C_END
142e41f4b71Sopenharmony_ci    
143e41f4b71Sopenharmony_cistatic napi_module demoModule = {
144e41f4b71Sopenharmony_ci    .nm_version = 1,
145e41f4b71Sopenharmony_ci    .nm_flags = 0,
146e41f4b71Sopenharmony_ci    .nm_filename = nullptr,
147e41f4b71Sopenharmony_ci    .nm_register_func = Init,
148e41f4b71Sopenharmony_ci    .nm_modname = "entry",
149e41f4b71Sopenharmony_ci    .nm_priv = ((void *)0),
150e41f4b71Sopenharmony_ci    .reserved = {0},
151e41f4b71Sopenharmony_ci};
152e41f4b71Sopenharmony_ci
153e41f4b71Sopenharmony_ciextern "C" __attribute__((constructor)) void RegisterEntryModule(void){
154e41f4b71Sopenharmony_ci    napi_module_register(&demoModule);
155e41f4b71Sopenharmony_ci}
156e41f4b71Sopenharmony_ci```
157e41f4b71Sopenharmony_ci
158e41f4b71Sopenharmony_ci#### Scenario 2: The API does not work when the native side throws an FD event to the main loop of the application.
159e41f4b71Sopenharmony_ci
160e41f4b71Sopenharmony_ciThe main loop of the application receives only FD events, and executes **uv_run** only after **backend_fd** in **uvloop** is triggered. That means **uv_run** will never be executed if no FD event is triggered when **uv** APIs are called in the main loop of the application. As a result, calling libuv APIs does not take effect.
161e41f4b71Sopenharmony_ci
162e41f4b71Sopenharmony_ci**Example (incorrect)**
163e41f4b71Sopenharmony_ci
164e41f4b71Sopenharmony_ciIn the following example, calling **uv_poll_start** in OpenHarmony in the same way as in native libuv does not take effect.
165e41f4b71Sopenharmony_ci
166e41f4b71Sopenharmony_ci```cpp
167e41f4b71Sopenharmony_ci#include "napi/native_api.h"
168e41f4b71Sopenharmony_ci#include "uv.h"
169e41f4b71Sopenharmony_ci#define LOG_DOMAIN 0X0202
170e41f4b71Sopenharmony_ci#define LOG_TAG "MyTag"
171e41f4b71Sopenharmony_ci#include <hilog/log.h>
172e41f4b71Sopenharmony_ci#include <thread>
173e41f4b71Sopenharmony_ci#include <sys/eventfd.h>
174e41f4b71Sopenharmony_ci#include <unistd.h>
175e41f4b71Sopenharmony_ciuv_loop_t *loop;
176e41f4b71Sopenharmony_cinapi_value jsCb;
177e41f4b71Sopenharmony_ciint fd = -1;
178e41f4b71Sopenharmony_civoid poll_handler(uv_poll_t* handle,int status, int events){
179e41f4b71Sopenharmony_ci    OH_LOG_INFO(LOG_APP, "ohos poll print");
180e41f4b71Sopenharmony_ci}
181e41f4b71Sopenharmony_cistatic napi_value TestClose(napi_env env, napi_callback_info info){
182e41f4b71Sopenharmony_ci    std::thread::id this_id = std::this_thread::get_id();
183e41f4b71Sopenharmony_ci    OH_LOG_INFO(LOG_APP, "ohos thread id : %{public}ld\n", this_id);
184e41f4b71Sopenharmony_ci    size_t argc = 1;
185e41f4b71Sopenharmony_ci    napi_value workBname;
186e41f4b71Sopenharmony_ci    
187e41f4b71Sopenharmony_ci    napi_create_string_utf8(env, "test", NAPI_AUTO_LENGTH, &workBname);
188e41f4b71Sopenharmony_ci    
189e41f4b71Sopenharmony_ci    napi_get_cb_info(env, info, &argc, &jsCb, nullptr, nullptr);
190e41f4b71Sopenharmony_ci    // Obtain the event loop.
191e41f4b71Sopenharmony_ci    napi_get_uv_event_loop(env, &loop);
192e41f4b71Sopenharmony_ci    // Create an eventfd.
193e41f4b71Sopenharmony_ci    fd = eventfd(0, 0);
194e41f4b71Sopenharmony_ci    OH_LOG_INFO(LOG_APP, "fd is %{public}d\n",fd);
195e41f4b71Sopenharmony_ci    uv_poll_t* poll_handle = new uv_poll_t;
196e41f4b71Sopenharmony_ci    // Initialize a poll handle and associate it with eventfd.
197e41f4b71Sopenharmony_ci    uv_poll_init(loop, poll_handle, fd);
198e41f4b71Sopenharmony_ci    // Start to listen for the poll event.
199e41f4b71Sopenharmony_ci    uv_poll_start(poll_handle, UV_READABLE, poll_handler);
200e41f4b71Sopenharmony_ci    // Create a new thread and write data to eventfd.
201e41f4b71Sopenharmony_ci    std::thread mythread([](){
202e41f4b71Sopenharmony_ci        for (int i = 0; i < 8; i++){
203e41f4b71Sopenharmony_ci            int value = 10;
204e41f4b71Sopenharmony_ci            int ret = eventfd_write(fd, value);
205e41f4b71Sopenharmony_ci            if (ret == -1){
206e41f4b71Sopenharmony_ci                OH_LOG_INFO(LOG_APP, "write failed!\n");
207e41f4b71Sopenharmony_ci                continue;
208e41f4b71Sopenharmony_ci            }
209e41f4b71Sopenharmony_ci        }
210e41f4b71Sopenharmony_ci    });
211e41f4b71Sopenharmony_ci    mythread.detach();
212e41f4b71Sopenharmony_ci    return 0;
213e41f4b71Sopenharmony_ci}
214e41f4b71Sopenharmony_ciEXTERN_C_START
215e41f4b71Sopenharmony_cistatic napi_value Init(napi_env env, napi_value exports){
216e41f4b71Sopenharmony_ci    napi_property_descriptor desc[] = {{"testClose", nullptr, TestClose, nullptr, nullptr, nullptr, napi_default, nullptr}};
217e41f4b71Sopenharmony_ci    napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
218e41f4b71Sopenharmony_ci    return exports;
219e41f4b71Sopenharmony_ci}
220e41f4b71Sopenharmony_ciEXTERN_C_END
221e41f4b71Sopenharmony_ci    
222e41f4b71Sopenharmony_cistatic napi_module demoModule = {
223e41f4b71Sopenharmony_ci    .nm_version = 1,
224e41f4b71Sopenharmony_ci    .nm_flags = 0,
225e41f4b71Sopenharmony_ci    .nm_filename = nullptr,
226e41f4b71Sopenharmony_ci    .nm_register_func = Init,
227e41f4b71Sopenharmony_ci    .nm_modname = "entry",
228e41f4b71Sopenharmony_ci    .nm_priv = ((void *)0),
229e41f4b71Sopenharmony_ci    .reserved = {0},
230e41f4b71Sopenharmony_ci};
231e41f4b71Sopenharmony_ci
232e41f4b71Sopenharmony_ciextern "C" __attribute__((constructor)) void RegisterEntryModule(void){
233e41f4b71Sopenharmony_ci    napi_module_register(&demoModule);
234e41f4b71Sopenharmony_ci}
235e41f4b71Sopenharmony_ci```
236e41f4b71Sopenharmony_ci
237e41f4b71Sopenharmony_ciThe process is as follows:
238e41f4b71Sopenharmony_ci
239e41f4b71Sopenharmony_ci1. Use **napi_get_uv_event_loop** to obtain **uvloop** of the application main thread.
240e41f4b71Sopenharmony_ci2. Create an **eventfd** instance.
241e41f4b71Sopenharmony_ci3. Initialize **uv_poll_t**, and start the handle for it to take effect. Trigger the callback **poll_handler** when the **eventfd** instance is readable.
242e41f4b71Sopenharmony_ci4. Create a thread and write data to **eventfd**.
243e41f4b71Sopenharmony_ci
244e41f4b71Sopenharmony_ciAfter the preceding code is executed, data cannot be properly printed for **poll_handler**. This is because the main thread of the application executes **uv_run** based on the FD rather than in UV_RUN_DEFAULT mode. Although **event_handler** listens for **backend_fd** in **uvloop**, the FD is not added to **backend_fd** through **epoll_ctl** when **uv_poll_start** is executed. The **epoll_ctl** function is executed only when **uv__io_poll** in **uv_run** is executed the next time. Therefore, if no **backend_fd** event is triggered in the application process, the libuv APIs may not work as expected.
245e41f4b71Sopenharmony_ci
246e41f4b71Sopenharmony_ci**Workaround**
247e41f4b71Sopenharmony_ci
248e41f4b71Sopenharmony_ciIn the current system version, avoid using **napi_get_uv_event_loop** directly to obtain **uvloop** of the application main thread to develop service logic. If libuv must be used to implement service functions, after **uv_xxx_start** is called, use **uv_async_send** to trigger the main thread of the application to execute **uv_run**. In this way, **uv_xxx_start** can be properly executed.
249e41f4b71Sopenharmony_ci
250e41f4b71Sopenharmony_ciModify the code as follows:
251e41f4b71Sopenharmony_ci
252e41f4b71Sopenharmony_ci```cpp
253e41f4b71Sopenharmony_ci#include "napi/native_api.h"
254e41f4b71Sopenharmony_ci#include "uv.h"
255e41f4b71Sopenharmony_ci#define LOG_DOMAIN 0x0202
256e41f4b71Sopenharmony_ci#define LOG_TAG "MyTag"
257e41f4b71Sopenharmony_ci#include <hilog/log.h>
258e41f4b71Sopenharmony_ci#include <thread>
259e41f4b71Sopenharmony_ci#include <sys/eventfd.h>
260e41f4b71Sopenharmony_ci#include <unistd.h>
261e41f4b71Sopenharmony_ciuv_loop_t *loop;
262e41f4b71Sopenharmony_cinapi_value jsCb;
263e41f4b71Sopenharmony_ciint fd = -1;
264e41f4b71Sopenharmony_civoid poll_handler(uv_poll_t* handle,int status, int events){
265e41f4b71Sopenharmony_ci    OH_LOG_INFO(LOG_APP, "ohos poll print");
266e41f4b71Sopenharmony_ci}
267e41f4b71Sopenharmony_cistatic napi_value TestClose(napi_env env, napi_callback_info info){
268e41f4b71Sopenharmony_ci    std::thread::id this_id = std::this_thread::get_id();
269e41f4b71Sopenharmony_ci    OH_LOG_INFO(LOG_APP, "ohos thread id : %{public}ld\n", this_id);
270e41f4b71Sopenharmony_ci    size_t argc = 1;
271e41f4b71Sopenharmony_ci    napi_value workBName;
272e41f4b71Sopenharmony_ci    
273e41f4b71Sopenharmony_ci    napi_create_string_utf8(env, "test", NAPI_AUTO_LENGTH, &workBName);
274e41f4b71Sopenharmony_ci    
275e41f4b71Sopenharmony_ci    napi_get_cb_info(env, info, &argc, &jsCb, nullptr, nullptr);
276e41f4b71Sopenharmony_ci
277e41f4b71Sopenharmony_ci    napi_get_uv_event_loop(env, &loop);
278e41f4b71Sopenharmony_ci
279e41f4b71Sopenharmony_ci    fd = eventfd(0, 0);
280e41f4b71Sopenharmony_ci    OH_LOG_INFO(LOG_APP, "fd is %{public}d\n",fd);
281e41f4b71Sopenharmony_ci    uv_poll_t* poll_handle = new uv_poll_t;
282e41f4b71Sopenharmony_ci    uv_poll_init(loop, poll_handle, fd);
283e41f4b71Sopenharmony_ci    uv_poll_start(poll_handle, UV_READABLE, poll_handler);
284e41f4b71Sopenharmony_ci
285e41f4b71Sopenharmony_ci    // Trigger an FD event to enable the main thread to execute uv_run.
286e41f4b71Sopenharmony_ci    uv_async_send(&loop->wq_async);
287e41f4b71Sopenharmony_ci    
288e41f4b71Sopenharmony_ci    std::thread mythread([](){
289e41f4b71Sopenharmony_ci        for (int i = 0; i < 8; i++){
290e41f4b71Sopenharmony_ci            int value = 10;
291e41f4b71Sopenharmony_ci            int ret = eventfd_write(fd, value);
292e41f4b71Sopenharmony_ci            if (ret == -1){
293e41f4b71Sopenharmony_ci                OH_LOG_INFO(LOG_APP, "write failed!\n");
294e41f4b71Sopenharmony_ci                continue;
295e41f4b71Sopenharmony_ci            }
296e41f4b71Sopenharmony_ci        }
297e41f4b71Sopenharmony_ci    });
298e41f4b71Sopenharmony_ci    mythread.detach();
299e41f4b71Sopenharmony_ci    return 0;
300e41f4b71Sopenharmony_ci}
301e41f4b71Sopenharmony_ci
302e41f4b71Sopenharmony_ciEXTERN_C_START
303e41f4b71Sopenharmony_cistatic napi_value Init(napi_env env, napi_value exports){
304e41f4b71Sopenharmony_ci    napi_property_descriptor desc[] = {{"testClose", nullptr, TestClose, nullptr, nullptr, nullptr, napi_default, nullptr}};
305e41f4b71Sopenharmony_ci    napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
306e41f4b71Sopenharmony_ci    return exports;
307e41f4b71Sopenharmony_ci}
308e41f4b71Sopenharmony_ciEXTERN_C_END
309e41f4b71Sopenharmony_ci    
310e41f4b71Sopenharmony_cistatic napi_module demoModule = {
311e41f4b71Sopenharmony_ci    .nm_version = 1,
312e41f4b71Sopenharmony_ci    .nm_flags = 0,
313e41f4b71Sopenharmony_ci    .nm_filename = nullptr,
314e41f4b71Sopenharmony_ci    .nm_register_func = Init,
315e41f4b71Sopenharmony_ci    .nm_modname = "entry",
316e41f4b71Sopenharmony_ci    .nm_priv = ((void *)0),
317e41f4b71Sopenharmony_ci    .reserved = {0},
318e41f4b71Sopenharmony_ci};
319e41f4b71Sopenharmony_ci
320e41f4b71Sopenharmony_ciextern "C" __attribute__((constructor)) void RegisterEntryModule(void){
321e41f4b71Sopenharmony_ci    napi_module_register(&demoModule);
322e41f4b71Sopenharmony_ci}
323e41f4b71Sopenharmony_ci```
324e41f4b71Sopenharmony_ci
325e41f4b71Sopenharmony_ci## Using libuv
326e41f4b71Sopenharmony_ci
327e41f4b71Sopenharmony_ciAll the APIs that depend on **uv_run** in the libuv NDK do not work as expected in the application main loop of the current system, and may cause freezing or loss of frames. You are advised not to directly use libuv NDK APIs in the JS main thread. You can use Node-API to implement async task execution and communication with the main thread using thread-safe functions.
328e41f4b71Sopenharmony_ci
329e41f4b71Sopenharmony_ci### Mappings Between libuv APIs and Node-API APIs
330e41f4b71Sopenharmony_ci
331e41f4b71Sopenharmony_ciInstead of using libuv APIs, you can use the equivalent Node-API provided by OpenHarmony, which includes async work APIs and thread-safe APIs.
332e41f4b71Sopenharmony_ci
333e41f4b71Sopenharmony_ci#### Asynchronous Work APIs
334e41f4b71Sopenharmony_ci
335e41f4b71Sopenharmony_cilibuv provides the **uv_queue_work** API to perform a time-consuming operation in an async thread and return the result to the main thread for processing through a callback.
336e41f4b71Sopenharmony_ci
337e41f4b71Sopenharmony_ciYou can use [napi_async_work](../../napi/use-napi-asynchronous-task.md) APIs of Node-API to implement async operations.
338e41f4b71Sopenharmony_ci
339e41f4b71Sopenharmony_ciThe related APIs are as follows:
340e41f4b71Sopenharmony_ci
341e41f4b71Sopenharmony_ci```cpp
342e41f4b71Sopenharmony_ci// Create a work object that executes logic asynchronously.
343e41f4b71Sopenharmony_ci// env: pointer to the current execution environment.
344e41f4b71Sopenharmony_ci// async_resource: (optional) resource object used to trace async operations.
345e41f4b71Sopenharmony_ci// async_resource_name: (optional) name of the resource object. The value is a string.
346e41f4b71Sopenharmony_ci// execute: callback invoked to perform an async operation in another thread.
347e41f4b71Sopenharmony_ci// complete: callback to be invoked when the async operation is complete.
348e41f4b71Sopenharmony_ci// data: pointer to the customized data to be passed to the execute and complete callbacks.
349e41f4b71Sopenharmony_ci// result: pointer to the async work object created.
350e41f4b71Sopenharmony_cinapi_status napi_create_async_work(napi_env env,
351e41f4b71Sopenharmony_ci                                  napi_value async_resource,
352e41f4b71Sopenharmony_ci                                  napi_value async_resource_name,
353e41f4b71Sopenharmony_ci                                   napi_async_execute_callback execute,
354e41f4b71Sopenharmony_ci                                 napi_async_complete_callback complete,
355e41f4b71Sopenharmony_ci                                  void* data,
356e41f4b71Sopenharmony_ci                                  napi_async_work* result);
357e41f4b71Sopenharmony_ci
358e41f4b71Sopenharmony_ci// Add an async work object to the queue so that it can be scheduled for execution.
359e41f4b71Sopenharmony_ci// env: pointer to the current execution environment.
360e41f4b71Sopenharmony_ci// work: pointer to the async work object to add.
361e41f4b71Sopenharmony_cinapi_status napi_queue_async_work(napi_env env, napi_async_work work);
362e41f4b71Sopenharmony_ci
363e41f4b71Sopenharmony_ci// Delete an async work object.
364e41f4b71Sopenharmony_ci// env: pointer to the current execution environment.
365e41f4b71Sopenharmony_ci// work: pointer to the async work object to delete.
366e41f4b71Sopenharmony_cinapi_status napi_delete_async_work(napi_env env, napi_async_work work);
367e41f4b71Sopenharmony_ci```
368e41f4b71Sopenharmony_ci
369e41f4b71Sopenharmony_ci#### Thread-safe APIs for Cross-Thread Sharing and Invocation
370e41f4b71Sopenharmony_ci
371e41f4b71Sopenharmony_ciWhen you want to pass a callback to the application main thread, you can use the libuv **uv_async_t** handle, which is used for inter-thread communication, and the following functions:
372e41f4b71Sopenharmony_ci
373e41f4b71Sopenharmony_ci- uv_async_init()
374e41f4b71Sopenharmony_ci- uv_async_send()
375e41f4b71Sopenharmony_ci
376e41f4b71Sopenharmony_ciThe equivalent Node-API APIs are [napi_threadsafe_function](../../napi/use-napi-thread-safety.md) APIs.
377e41f4b71Sopenharmony_ci
378e41f4b71Sopenharmony_ci 
379e41f4b71Sopenharmony_ci
380e41f4b71Sopenharmony_ci```cpp
381e41f4b71Sopenharmony_ci// Create a thread-safe function.
382e41f4b71Sopenharmony_ci// env: pointer to the current execution environment.
383e41f4b71Sopenharmony_ci// func: pointer to the JavaScript function to create.
384e41f4b71Sopenharmony_ci// resource_name: pointer to the resource name.
385e41f4b71Sopenharmony_ci// max_queue_size: maximum size of the queue.
386e41f4b71Sopenharmony_ci// initial_thread_count: number of initial threads.
387e41f4b71Sopenharmony_ci// callback: callback.
388e41f4b71Sopenharmony_ci// result: pointer to the operation result. 
389e41f4b71Sopenharmony_cinapi_status napi_create_threadsafe_function(napi_env env,
390e41f4b71Sopenharmony_ci                                           napi_value func,
391e41f4b71Sopenharmony_ci                                           const char* resource_name,
392e41f4b71Sopenharmony_ci                                            size_t max_queue_size,
393e41f4b71Sopenharmony_ci                                           size_t initial_thread_count,
394e41f4b71Sopenharmony_ci                                           void* context,
395e41f4b71Sopenharmony_ci                                           napi_threadsafe_function_call_js call_js_func,
396e41f4b71Sopenharmony_ci                                           napi_threadsafe_function_finalize finalize,
397e41f4b71Sopenharmony_ci                                           napi_threadsafe_function* result);
398e41f4b71Sopenharmony_ci
399e41f4b71Sopenharmony_ci// Acquire a thread-safe function.
400e41f4b71Sopenharmony_ci// function: pointer to the thread-safe function to acquire.
401e41f4b71Sopenharmony_cinapi_status napi_acquire_threadsafe_function(napi_threadsafe_function function);
402e41f4b71Sopenharmony_ci
403e41f4b71Sopenharmony_ci// Call a thread-safe function.
404e41f4b71Sopenharmony_ci// function: pointer to the thread-safe function to call.
405e41f4b71Sopenharmony_ci// data: pointer to the user data. 
406e41f4b71Sopenharmony_cinapi_status napi_call_threadsafe_function(napi_threadsafe_function function, void* data);
407e41f4b71Sopenharmony_ci
408e41f4b71Sopenharmony_ci// Release a thread-safe function.
409e41f4b71Sopenharmony_ci// function: pointer to the thread-safe function to release.
410e41f4b71Sopenharmony_cinapi_status napi_release_threadsafe_function(napi_threadsafe_function function);
411e41f4b71Sopenharmony_ci
412e41f4b71Sopenharmony_ci```
413e41f4b71Sopenharmony_ci
414e41f4b71Sopenharmony_ciIf you need to use other libuv APIs to implement service functions, read on to discover basic libuv concepts and common APIs to be used in OpenHarmony, which are helpful to prevent application crashes when using libuv APIs. You can also learn about the APIs that can be used in the application main thread and those cannot.
415e41f4b71Sopenharmony_ci
416e41f4b71Sopenharmony_ci### Available APIs
417e41f4b71Sopenharmony_ci
418e41f4b71Sopenharmony_ci|  API Type   |  API   |
419e41f4b71Sopenharmony_ci| ---- | ---- |
420e41f4b71Sopenharmony_ci|  [Loop](#event-loops-in-libuv)  |  uv_loop_init    |
421e41f4b71Sopenharmony_ci| [Loop](#event-loops-in-libuv) |   uv_loop_close   |
422e41f4b71Sopenharmony_ci| [Loop](#event-loops-in-libuv) |  uv_default_loop    |
423e41f4b71Sopenharmony_ci| [Loop](#event-loops-in-libuv) |   uv_run   |
424e41f4b71Sopenharmony_ci| [Loop](#event-loops-in-libuv) |    uv_loop_alive  |
425e41f4b71Sopenharmony_ci| [Loop](#event-loops-in-libuv) |  uv_stop    |
426e41f4b71Sopenharmony_ci|   [Handle](#handles-and-requests-in-libuv)  |  uv_poll\_\* |
427e41f4b71Sopenharmony_ci|   [Handle](#handles-and-requests-in-libuv)  |  uv_timer\_\* |
428e41f4b71Sopenharmony_ci|   [Handle](#handles-and-requests-in-libuv)  |  uv_async\_\* |
429e41f4b71Sopenharmony_ci|   [Handle](#handles-and-requests-in-libuv)  |   uv_signal\_\*   |
430e41f4b71Sopenharmony_ci|   [Handle](#handles-and-requests-in-libuv)  |   uv_fs\_\*  |
431e41f4b71Sopenharmony_ci|   [Request](#handles-and-requests-in-libuv)  |  uv_random    |
432e41f4b71Sopenharmony_ci|   [Request](#handles-and-requests-in-libuv)  |  uv_getaddrinfo    |
433e41f4b71Sopenharmony_ci|   [Request](#handles-and-requests-in-libuv)  |  uv_getnameinfo    |
434e41f4b71Sopenharmony_ci|   [Request](#handles-and-requests-in-libuv)  |  uv_queue_work    |
435e41f4b71Sopenharmony_ci|   [Inter-Thread communication](#inter-thread-communication)  |  uv_async_init    |
436e41f4b71Sopenharmony_ci|   [Inter-Thread communication](#inter-thread-communication)  |  uv_async_send    |
437e41f4b71Sopenharmony_ci|   [Thread pool](#thread-pool)  |  uv_queue_work    |
438e41f4b71Sopenharmony_ci
439e41f4b71Sopenharmony_ci### Thread-Safe Functions
440e41f4b71Sopenharmony_ci
441e41f4b71Sopenharmony_ciA large number of async works are involved in libuv. Improper use of libuv APIs may cause multithreading issues. The following lists the common thread-safe and non-thread-safe functions in libuv. If a non-thread-safe function is called in multithreading programming, you need to add a lock or ensure correct execution timing of the code. Otherwise, the application may crash.
442e41f4b71Sopenharmony_ci
443e41f4b71Sopenharmony_ciThread-safe functions include the following:
444e41f4b71Sopenharmony_ci
445e41f4b71Sopenharmony_ci- **uv_async_init()**: initializes an async handle, which is used to wake up the main event loop thread from another thread and trigger a callback.
446e41f4b71Sopenharmony_ci- **uv_async_send()**: sends a signal to an async handle. This API can be called in any thread.
447e41f4b71Sopenharmony_ci- **uv_thread_create()**: creates a thread and executes the specified function. This API can be called in any thread.
448e41f4b71Sopenharmony_ci- **uv_fs\_\*()**: performs file system operations (*\** indicates the specific function name.)
449e41f4b71Sopenharmony_ci- **uv_poll\_\*()**: performs operations on polling events (*\** indicates the specific function name.)
450e41f4b71Sopenharmony_ci- Lock-related APIs, such as **uv\_mutex\_lock()** and **uv\_mutex\_unlock()**.
451e41f4b71Sopenharmony_ci
452e41f4b71Sopenharmony_ci> **NOTE**
453e41f4b71Sopenharmony_ci>
454e41f4b71Sopenharmony_ci> - Even if the function like **uv_xxx_init** is implemented in a thread-safe manner, avoid calling it by multiple threads at the same time. Otherwise, resource contention may occur. The best way is to call the function in an event loop thread.
455e41f4b71Sopenharmony_ci> - The callback invoked after **uv_async_send()** is triggered asynchronously. If **uv_async_send()** is called multiple times, libuv ensures that at least one callback is executed. As a result, if **uv_async_send()** is called for the same handle for multiple times, the callback processing may be different from your expectations.
456e41f4b71Sopenharmony_ci
457e41f4b71Sopenharmony_ci
458e41f4b71Sopenharmony_ci
459e41f4b71Sopenharmony_ciNon-thread-safe functions include the following:
460e41f4b71Sopenharmony_ci
461e41f4b71Sopenharmony_ci- **uv\_os\_unsetenv()**: deletes an environment variable.
462e41f4b71Sopenharmony_ci- **uv\_os\_setenv()**: sets an environment variable.
463e41f4b71Sopenharmony_ci- **uv\_os\_getenv()**: obtains an environment variable.
464e41f4b71Sopenharmony_ci- **uv\_os\_environ(**): retrieves all environment variables.
465e41f4b71Sopenharmony_ci- **uv\_os\_tmpdir()**: obtains the temporary directory.
466e41f4b71Sopenharmony_ci- **uv\_os\_homedir()**: obtains the home directory.
467e41f4b71Sopenharmony_ci
468e41f4b71Sopenharmony_ci### Event Loops in libuv
469e41f4b71Sopenharmony_ci
470e41f4b71Sopenharmony_ciAs a core concept in libuv, an event loop manages all resources of the entire event loop and runs through the lifecycle of the entire event loop. Generally, the thread where **uv_run** is located is the main thread of the event loop.
471e41f4b71Sopenharmony_ci
472e41f4b71Sopenharmony_ci#### Event Loop Running Modes
473e41f4b71Sopenharmony_ci
474e41f4b71Sopenharmony_ci- **UV_RUN_DEFAULT**: runs the event loop until there are no active handles or requests. This is the default mode.
475e41f4b71Sopenharmony_ci- **UV_RUN_ONCE**: polls for I/O once. If there is a callback in **pending_queue**, execute the callback and then skip **uv__io_poll**. In this mode, there is an event to occur in the loop by default.
476e41f4b71Sopenharmony_ci
477e41f4b71Sopenharmony_ci- **UV_RUN_NOWAIT**: polls for I/O once but do not block if there are no pending callbacks. In this mode, **uv__io_poll** is executed once and **pending_queue** is not executed.
478e41f4b71Sopenharmony_ci
479e41f4b71Sopenharmony_ci#### Common APIs
480e41f4b71Sopenharmony_ci
481e41f4b71Sopenharmony_ci```cpp
482e41f4b71Sopenharmony_ciint uv_loop_init(uv_loop_t* loop);
483e41f4b71Sopenharmony_ci```
484e41f4b71Sopenharmony_ci
485e41f4b71Sopenharmony_ci   Initializes a loop.
486e41f4b71Sopenharmony_ci
487e41f4b71Sopenharmony_ci```cpp
488e41f4b71Sopenharmony_ciint uv_loop_close(uv_loop_t* loop);
489e41f4b71Sopenharmony_ci```
490e41f4b71Sopenharmony_ci
491e41f4b71Sopenharmony_ci  Closes a loop. The operation is successful only after all handles and requests in the loop are closed. Otherwise, **UV_EBUSY** is returned.
492e41f4b71Sopenharmony_ci
493e41f4b71Sopenharmony_ci```cpp
494e41f4b71Sopenharmony_ciuv_loop_t* uv_default_loop(void);
495e41f4b71Sopenharmony_ci```
496e41f4b71Sopenharmony_ci
497e41f4b71Sopenharmony_ci  Creates a process-level loop. In OpenHarmony, libuv loops still exist in the application main loop and other JS worker threads. You are not advised to use this API to create loops and implement service functions. When the loop mechanism normalization is complete, you can use this API to create loops.
498e41f4b71Sopenharmony_ci
499e41f4b71Sopenharmony_ci```cpp
500e41f4b71Sopenharmony_ciint uv_run(uv_loop_t* loop, uv_run_mode mode);
501e41f4b71Sopenharmony_ci```
502e41f4b71Sopenharmony_ci
503e41f4b71Sopenharmony_ci  Runs an event loop. For details about the running mode, see [Event Loop Running Modes](#event-loop-running-modes).
504e41f4b71Sopenharmony_ci
505e41f4b71Sopenharmony_ci```cpp
506e41f4b71Sopenharmony_ciint uv_loop_alive(uv_loop_t loop);
507e41f4b71Sopenharmony_ci```
508e41f4b71Sopenharmony_ci
509e41f4b71Sopenharmony_ci  Checks whether a loop is active.
510e41f4b71Sopenharmony_ci
511e41f4b71Sopenharmony_ci```cpp
512e41f4b71Sopenharmony_civoid uv_stop(uv_loop_t* loop);
513e41f4b71Sopenharmony_ci```
514e41f4b71Sopenharmony_ci
515e41f4b71Sopenharmony_ci  Stops an event loop. The event loop stops only in the next iteration of the loop. If this API is called before an I/O operation, **uv__io_poll** will be skipped instead of being blocked.
516e41f4b71Sopenharmony_ci
517e41f4b71Sopenharmony_ci> **Tips**
518e41f4b71Sopenharmony_ci>
519e41f4b71Sopenharmony_ci> Pay special attention to the use of **uv_stop**. Before **uv_stop** is called, ensure that the handles of all threads related to the loop are closed. 
520e41f4b71Sopenharmony_ci
521e41f4b71Sopenharmony_ciThe sample code is as follows:
522e41f4b71Sopenharmony_ci
523e41f4b71Sopenharmony_ci```cpp
524e41f4b71Sopenharmony_ciint stop_loop(uv_loop_t* loop)
525e41f4b71Sopenharmony_ci{
526e41f4b71Sopenharmony_ci    uv_stop(loop);
527e41f4b71Sopenharmony_ci    auto const ensure_close = [](uv_handle_t* handle, void*) {
528e41f4b71Sopenharmony_ci        if (uv_is_closing(handle)) {
529e41f4b71Sopenharmony_ci            return;
530e41f4b71Sopenharmony_ci        } else {
531e41f4b71Sopenharmony_ci            uv_close(handle, nullptr);
532e41f4b71Sopenharmony_ci        }
533e41f4b71Sopenharmony_ci    };
534e41f4b71Sopenharmony_ci    // Traverse all handles. Call ensure_close to close the active handle.
535e41f4b71Sopenharmony_ci    uv_walk(loop, ensure_close, nullptr);
536e41f4b71Sopenharmony_ci
537e41f4b71Sopenharmony_ci    // Continue to run uv_run until there is no active handle or request in the loop.
538e41f4b71Sopenharmony_ci    while(true) {
539e41f4b71Sopenharmony_ci        if (uv_run(loop, UV_RUN_DEFAULT) == 0) {
540e41f4b71Sopenharmony_ci            break;
541e41f4b71Sopenharmony_ci        }
542e41f4b71Sopenharmony_ci    }
543e41f4b71Sopenharmony_ci
544e41f4b71Sopenharmony_ci    // Check the loop status.
545e41f4b71Sopenharmony_ci    if (uv_loop_alive(loop) != 0) {
546e41f4b71Sopenharmony_ci        return -1;
547e41f4b71Sopenharmony_ci    }
548e41f4b71Sopenharmony_ci    return 0;
549e41f4b71Sopenharmony_ci}
550e41f4b71Sopenharmony_ci```
551e41f4b71Sopenharmony_ci
552e41f4b71Sopenharmony_ci### Handles and Requests in libuv
553e41f4b71Sopenharmony_ci
554e41f4b71Sopenharmony_ciA handle indicates a persistent object, which is usually mounted to the corresponding **handle_queue** in a loop. If a handle is active, **uv_run** will process the callback in the handle each time.
555e41f4b71Sopenharmony_ci
556e41f4b71Sopenharmony_ciA request indicates a temporary request. A request triggers only one callback.
557e41f4b71Sopenharmony_ci
558e41f4b71Sopenharmony_ciThe commonly used handles and requests in OpenHarmony include the following:
559e41f4b71Sopenharmony_ci
560e41f4b71Sopenharmony_ci```cpp
561e41f4b71Sopenharmony_ci/* Handle types. */
562e41f4b71Sopenharmony_citypedef struct uv_handle_s uv_handle_t;
563e41f4b71Sopenharmony_citypedef struct uv_timer_s uv_timer_t;
564e41f4b71Sopenharmony_citypedef struct uv_async_s uv_async_t;
565e41f4b71Sopenharmony_citypedef struct uv_signal_s uv_signal_t;
566e41f4b71Sopenharmony_ci
567e41f4b71Sopenharmony_ci/* Request types. */
568e41f4b71Sopenharmony_citypedef struct uv_req_s uv_req_t;
569e41f4b71Sopenharmony_citypedef struct uv_work_s uv_work_t;
570e41f4b71Sopenharmony_citypedef struct uv_fs_s uv_fs_t;
571e41f4b71Sopenharmony_ci```
572e41f4b71Sopenharmony_ci
573e41f4b71Sopenharmony_ci> **NOTE**
574e41f4b71Sopenharmony_ci>
575e41f4b71Sopenharmony_ci> In handles, **uv_xxx_t** inherits from **uv_handle_t**. In requests, **uv_work_t** inherits from **uv_req_t**.
576e41f4b71Sopenharmony_ci
577e41f4b71Sopenharmony_ciIt is critical to understand the handles in libuv and manage its lifecycle. Observe the following when using a handle:
578e41f4b71Sopenharmony_ci
579e41f4b71Sopenharmony_ci1. Perform the handle initialization in the event loop thread.
580e41f4b71Sopenharmony_ci2. If the handle needs to be initialized in a worker thread due to service requirements, use an atomic variable to check whether the initialization is complete before the handle is used.
581e41f4b71Sopenharmony_ci3. For the handle that is no longer used, call **uv_close** to remove it from the loop.
582e41f4b71Sopenharmony_ci
583e41f4b71Sopenharmony_ciNote that **uv_close** is used to close a handle asynchronously. Its prototype is as follows:
584e41f4b71Sopenharmony_ci
585e41f4b71Sopenharmony_ci```cpp
586e41f4b71Sopenharmony_civoid uv_close(uv_handle_t* handle, uv_close_cb close_cb)
587e41f4b71Sopenharmony_ci```
588e41f4b71Sopenharmony_ci
589e41f4b71Sopenharmony_ci  **handle**: pointer to the handle to close.
590e41f4b71Sopenharmony_ci
591e41f4b71Sopenharmony_ci **close_cb**: function used to process the handle. This function is used to perform operations such as memory management.
592e41f4b71Sopenharmony_ci
593e41f4b71Sopenharmony_ciAfter **uv_close** is called, the handle to be closed is added to the **closing_handles** queue in the loop, and waits for the loop thread to run **uv__run_closing_handles**. Finally, the **close_cb** callback is executed in the next iteration of the loop. Therefore, operations such as memory release should be performed in **close_cb**. Improper use of the **close** API that is executed asynchronously may cause multithreading issues. You need to ensure correct timing of **uv_close** and ensure that all the handles are closed before **close_cb** is executed.  
594e41f4b71Sopenharmony_ci
595e41f4b71Sopenharmony_ci> **Tips**
596e41f4b71Sopenharmony_ci>
597e41f4b71Sopenharmony_ci> The following rule of thumb in the official libuv documentation (http://libuv.org/) needs to be observed:
598e41f4b71Sopenharmony_ci>
599e41f4b71Sopenharmony_ci> If a handle of type **uv_foo_t** has a **uv_foo_start()** function, then it's active from the moment that function is called. Likewise, **uv_foo_stop()** deactivates the handle again.
600e41f4b71Sopenharmony_ci
601e41f4b71Sopenharmony_ciFor the libuv request that is dynamically requested, release it in the callback of the loop thread. The following uses **uv_work_t** as an example.
602e41f4b71Sopenharmony_ci
603e41f4b71Sopenharmony_ci```cpp
604e41f4b71Sopenharmony_ciuv_work_t* work = new uv_work_t;
605e41f4b71Sopenharmony_ciuv_queue_work(loop, work, [](uv_work_t* req) {
606e41f4b71Sopenharmony_ci    // Asynchronous operation
607e41f4b71Sopenharmony_ci}, [](uv_work_t* req, int status) {
608e41f4b71Sopenharmony_ci    // Callback
609e41f4b71Sopenharmony_ci    delete req;
610e41f4b71Sopenharmony_ci});
611e41f4b71Sopenharmony_ci```
612e41f4b71Sopenharmony_ci
613e41f4b71Sopenharmony_ci### Inter-Thread Communication
614e41f4b71Sopenharmony_ci
615e41f4b71Sopenharmony_ciSo far, you have learn about the basic concepts of libuv. Now let's dive into the inter-thread communication in libuv.
616e41f4b71Sopenharmony_ci
617e41f4b71Sopenharmony_ciThe inter-thread communication of libuv is implemented based on the **uv_async_t** handle. The related APIs are as follows:
618e41f4b71Sopenharmony_ci
619e41f4b71Sopenharmony_ci```cpp
620e41f4b71Sopenharmony_ciint uv_async_init(uv_loop_t* loop, uv_async_t* handle, uv_async_cb async_cb)
621e41f4b71Sopenharmony_ci```
622e41f4b71Sopenharmony_ci
623e41f4b71Sopenharmony_ciInitializes a handle.
624e41f4b71Sopenharmony_ci
625e41f4b71Sopenharmony_ci- **loop**: pointer to the event loop.
626e41f4b71Sopenharmony_ci- **handle**: pointer to the handle for inter-thread communication.
627e41f4b71Sopenharmony_ci- **async_cb**: callback to be invoked.
628e41f4b71Sopenharmony_ci
629e41f4b71Sopenharmony_ci  The API returns **0** if the operation is successful; returns an error code if the operation fails.
630e41f4b71Sopenharmony_ci
631e41f4b71Sopenharmony_ci```cpp
632e41f4b71Sopenharmony_ciint uv_async_send(uv_async_t* handle)
633e41f4b71Sopenharmony_ci```
634e41f4b71Sopenharmony_ci
635e41f4b71Sopenharmony_ci  Wakes up the event loop and calls the async handle's callback.
636e41f4b71Sopenharmony_ci
637e41f4b71Sopenharmony_ci   **handle**: pointer to the handle for inter-thread communication.
638e41f4b71Sopenharmony_ci
639e41f4b71Sopenharmony_ci  The API returns **0** if the operation is successful; returns an error code if the operation fails.
640e41f4b71Sopenharmony_ci
641e41f4b71Sopenharmony_ci> **NOTE**
642e41f4b71Sopenharmony_ci>
643e41f4b71Sopenharmony_ci> **uv_async_t** remains active after **uv_async_init** is called till it is closed by **uv_close**.
644e41f4b71Sopenharmony_ci> **uv_async_t** is executed in the sequence defined by **uv_async_init** instead of **uv_async_send**. Therefore, it is necessary to manage the timing according to the initialization sequence.
645e41f4b71Sopenharmony_ci
646e41f4b71Sopenharmony_ci![](./figures/libuv-inter-thread-communication.png)
647e41f4b71Sopenharmony_ci
648e41f4b71Sopenharmony_ci
649e41f4b71Sopenharmony_ci
650e41f4b71Sopenharmony_ciExample:
651e41f4b71Sopenharmony_ci
652e41f4b71Sopenharmony_ci```cpp
653e41f4b71Sopenharmony_ci#include <bits/stdc++.h>
654e41f4b71Sopenharmony_ci#include "uv.h"
655e41f4b71Sopenharmony_ci
656e41f4b71Sopenharmony_ciuv_loop_t* loop = nullptr;
657e41f4b71Sopenharmony_ciuv_async_t* async = nullptr;
658e41f4b71Sopenharmony_civoid async_handler(uv_async_t* handle)
659e41f4b71Sopenharmony_ci{
660e41f4b71Sopenharmony_ci    printf("ohos async print\n");
661e41f4b71Sopenharmony_ci}
662e41f4b71Sopenharmony_ci
663e41f4b71Sopenharmony_ciint main()
664e41f4b71Sopenharmony_ci{
665e41f4b71Sopenharmony_ci    loop = uv_default_loop();
666e41f4b71Sopenharmony_ci    async = new uv_async_t;
667e41f4b71Sopenharmony_ci    uv_async_init(loop, async, async_handler);
668e41f4b71Sopenharmony_ci    std::thread subThread([]() {
669e41f4b71Sopenharmony_ci        for (int i = 0; i < 10; i++) {
670e41f4b71Sopenharmony_ci            usleep(100);
671e41f4b71Sopenharmony_ci            printf("%dth: subThread triggered\n", i);
672e41f4b71Sopenharmony_ci            uv_async_send(async);
673e41f4b71Sopenharmony_ci        }
674e41f4b71Sopenharmony_ci        // Call uv_close to close the async handle and release the memory in the main loop.
675e41f4b71Sopenharmony_ci        uv_close((uv_handle_t*)async, [](uv_handle_t* handle) {
676e41f4b71Sopenharmony_ci            printf("delete async\n");
677e41f4b71Sopenharmony_ci            delete (uv_async_t*)handle;
678e41f4b71Sopenharmony_ci        });
679e41f4b71Sopenharmony_ci        uv_stop(loop);
680e41f4b71Sopenharmony_ci    });
681e41f4b71Sopenharmony_ci    subThread.detach();
682e41f4b71Sopenharmony_ci    return uv_run(loop, UV_RUN_DEFAULT);
683e41f4b71Sopenharmony_ci}
684e41f4b71Sopenharmony_ci```
685e41f4b71Sopenharmony_ci
686e41f4b71Sopenharmony_ciThe sample code describes only a simple scenario. The procedure is as follows:
687e41f4b71Sopenharmony_ci
688e41f4b71Sopenharmony_ci1. Initialize the async handle in the main thread.
689e41f4b71Sopenharmony_ci2. Create a worker thread and trigger **uv_async_send** every 100 milliseconds. After **uv_async_send** is called 10 times, call **uv_close** to close the async handle.
690e41f4b71Sopenharmony_ci3. Run the event loop on the main thread.
691e41f4b71Sopenharmony_ci
692e41f4b71Sopenharmony_ciAs indicated by the following information, each time **uv_async_send** is called, the main thread executes the callback.
693e41f4b71Sopenharmony_ci
694e41f4b71Sopenharmony_ci```
695e41f4b71Sopenharmony_ci0th:subThread triggered
696e41f4b71Sopenharmony_ciohos async print
697e41f4b71Sopenharmony_ci1th:subThread triggered
698e41f4b71Sopenharmony_ciohos async print
699e41f4b71Sopenharmony_ci2th:subThread triggered
700e41f4b71Sopenharmony_ciohos async print
701e41f4b71Sopenharmony_ci3th:subThread triggered
702e41f4b71Sopenharmony_ciohos async print
703e41f4b71Sopenharmony_ci4th:subThread triggered
704e41f4b71Sopenharmony_ciohos async print
705e41f4b71Sopenharmony_ci5th:subThread triggered
706e41f4b71Sopenharmony_ciohos async print
707e41f4b71Sopenharmony_ci6th:subThread triggered
708e41f4b71Sopenharmony_ciohos async print
709e41f4b71Sopenharmony_ci7th:subThread triggered
710e41f4b71Sopenharmony_ciohos async print
711e41f4b71Sopenharmony_ci8th:subThread triggered
712e41f4b71Sopenharmony_ciohos async print
713e41f4b71Sopenharmony_ci9th:subThread triggered
714e41f4b71Sopenharmony_cidelete async
715e41f4b71Sopenharmony_ci```
716e41f4b71Sopenharmony_ci
717e41f4b71Sopenharmony_ci### Thread Pool
718e41f4b71Sopenharmony_ci
719e41f4b71Sopenharmony_ciThe thread pool in libuv uses the member variable **wq_async** in **uv_loop_t** to control the communication between the main thread and worker threads. The core API is as follows:
720e41f4b71Sopenharmony_ci
721e41f4b71Sopenharmony_ci```cpp
722e41f4b71Sopenharmony_ciint uv_queue_work(uv_loop_t* loop,
723e41f4b71Sopenharmony_ci                  uv_work_t* req,
724e41f4b71Sopenharmony_ci                  uv_work_cb work_cb,
725e41f4b71Sopenharmony_ci                  uv_after_work_cb after_work_cb)
726e41f4b71Sopenharmony_ci```
727e41f4b71Sopenharmony_ci
728e41f4b71Sopenharmony_ciInitializes a work request which will run the given **work_cb** in a thread from the thread pool.
729e41f4b71Sopenharmony_ci
730e41f4b71Sopenharmony_ci**work_cb**: task submitted to the worker thread.
731e41f4b71Sopenharmony_ci
732e41f4b71Sopenharmony_ci**after_work_cb**: callback to be executed by the loop thread.
733e41f4b71Sopenharmony_ci
734e41f4b71Sopenharmony_ci> **NOTE**
735e41f4b71Sopenharmony_ci>
736e41f4b71Sopenharmony_ci> **after work_cb** is called after **work_cb** is complete. It is triggered by an FD event triggered by **uv_async_send(loop->wq_async)** and executed in the next iteration of the loop thread. The **uv_work_t** lifecycle ends only when **after_work_cb** is executed.
737e41f4b71Sopenharmony_ci
738e41f4b71Sopenharmony_ciThe following figure illustrates a simplified workflow of the libuv thread pool. The default pending flag of the handle is 1. The number of worker threads is an example only.
739e41f4b71Sopenharmony_ci
740e41f4b71Sopenharmony_ci![](./figures/libuv-thread-pool.png)
741e41f4b71Sopenharmony_ci
742e41f4b71Sopenharmony_ci### Use of libuv in OpenHarmony
743e41f4b71Sopenharmony_ci
744e41f4b71Sopenharmony_ciCurrently, libuv threads are used in the main thread, JS Worker thread, TaskWorker thread in the Taskpool, and IPC thread of OpenHarmony. Except the main thread, which uses **eventhandler** as the main loop, other threads use the **UV_RUN_DEFAULT** mode in libuv as the event main loop of the calling thread to execute tasks. In the main thread, **eventhandler** triggers task execution by an FD event. **eventhandler** listens for **backend_fd** in **uv_loop**. Once an FD event is triggered in the loop, **eventhandler** calls **uv_run** to execute tasks in libuv.
745e41f4b71Sopenharmony_ci
746e41f4b71Sopenharmony_ciAs a result, all the uv APIs that are not triggered by an FD event in the main thread are not responded in a timely manner. The uv APIs on the JS worker threads work as expected.
747e41f4b71Sopenharmony_ci
748e41f4b71Sopenharmony_ciIn addition, in the application main thread, all async tasks are eventually executed through libuv. However, in the current system, [the libuv thread pool has been incorporated to the FFRT](https://gitee.com/openharmony/third_party_libuv/wikis/06-Wiki-%E6%8A%80%E6%9C%AF%E8%B5%84%E6%BA%90/%20libuv%E5%B7%A5%E4%BD%9C%E7%BA%BF%E7%A8%8B%E6%8E%A5%E5%85%A5FFRT%E6%96%B9%E6%A1%88%E5%88%86%E6%9E%90). Any async task thrown to the libuv thread will be scheduled by the FFRT thread. The callbacks of the application main thread are also inserted into the **eventhandler** queue by **PostTask()**. This means that after the async task in an FFRT thread is complete, the callback of the main thread is not triggered by **uv_async_send**. 
749e41f4b71Sopenharmony_ci
750e41f4b71Sopenharmony_ciThe following figure shows the process.
751e41f4b71Sopenharmony_ci
752e41f4b71Sopenharmony_ci![](./figures/libuv-ffrt.png)
753e41f4b71Sopenharmony_ci
754e41f4b71Sopenharmony_ciThe following types of requests can be processed as expected in the application main loop:
755e41f4b71Sopenharmony_ci
756e41f4b71Sopenharmony_ci- uv_random_t
757e41f4b71Sopenharmony_ci
758e41f4b71Sopenharmony_ci  Function prototype:
759e41f4b71Sopenharmony_ci  
760e41f4b71Sopenharmony_ci  ```cpp
761e41f4b71Sopenharmony_ci  /**
762e41f4b71Sopenharmony_ci  * Add a work request to an event loop queue.
763e41f4b71Sopenharmony_ci  * 
764e41f4b71Sopenharmony_ci  * @param loop indicates the pointer to the event loop.
765e41f4b71Sopenharmony_ci  * @param req indicates the pointer to the request.
766e41f4b71Sopenharmony_ci  * @param buf indicates the buffer for storing the random number.
767e41f4b71Sopenharmony_ci  * @param buflen indicates the length of the buffer.
768e41f4b71Sopenharmony_ci  * @param flags indicates the options for generating the random number.
769e41f4b71Sopenharmony_ci  * @param cb indicates the callback used to return the random number generated.
770e41f4b71Sopenharmony_ci  *
771e41f4b71Sopenharmony_ci  * @return Returns 0 if the operation is successful; returns an error code otherwise.
772e41f4b71Sopenharmony_ci  */
773e41f4b71Sopenharmony_ci  int uv_random(uv_loop_t* loop,
774e41f4b71Sopenharmony_ci               uv_random_t* req,
775e41f4b71Sopenharmony_ci               void* buf,
776e41f4b71Sopenharmony_ci               size_t buflen,
777e41f4b71Sopenharmony_ci               unsigned flags,
778e41f4b71Sopenharmony_ci               uv_random_cb cb);
779e41f4b71Sopenharmony_ci  ```
780e41f4b71Sopenharmony_ci  
781e41f4b71Sopenharmony_ci- uv_work_t
782e41f4b71Sopenharmony_ci
783e41f4b71Sopenharmony_ci    Function prototype:
784e41f4b71Sopenharmony_ci
785e41f4b71Sopenharmony_ci    ```cpp
786e41f4b71Sopenharmony_ci    /**
787e41f4b71Sopenharmony_ci    * Add a work request to an event loop queue.
788e41f4b71Sopenharmony_ci    * 
789e41f4b71Sopenharmony_ci    * work_cb will be called by a new thread in the next iteration of the event loop.
790e41f4b71Sopenharmony_ci    * When work_cb is complete, after_work_cb will be called on the event loop thread.
791e41f4b71Sopenharmony_ci    * 
792e41f4b71Sopenharmony_ci    * @param loop indicates the pointer to the event loop.
793e41f4b71Sopenharmony_ci    * @param req indicates the pointer to the work request.
794e41f4b71Sopenharmony_ci    * @param work_cb indicates the callback to be executed on a new thread.
795e41f4b71Sopenharmony_ci    * @param after_work_cb indicates the callback to be invoked on the event loop thread.
796e41f4b71Sopenharmony_ci    *
797e41f4b71Sopenharmony_ci    * @return Returns 0 if the operation is successful; returns -1 otherwise.
798e41f4b71Sopenharmony_ci    */
799e41f4b71Sopenharmony_ci    int uv_queue_work(uv_loop_t* loop,
800e41f4b71Sopenharmony_ci                      uv_work_t* req,
801e41f4b71Sopenharmony_ci                      uv_work_cb work_cb,
802e41f4b71Sopenharmony_ci                      uv_after_work_cb after_work_cb);
803e41f4b71Sopenharmony_ci    ```
804e41f4b71Sopenharmony_ci
805e41f4b71Sopenharmony_ci- uv_fs_t
806e41f4b71Sopenharmony_ci
807e41f4b71Sopenharmony_ci    All async APIs provided by the file class can work as expected in the application main thread. Common APIs include the following:
808e41f4b71Sopenharmony_ci
809e41f4b71Sopenharmony_ci    ```cpp
810e41f4b71Sopenharmony_ci    /**
811e41f4b71Sopenharmony_ci    * Read a file asynchronously.
812e41f4b71Sopenharmony_ci    *
813e41f4b71Sopenharmony_ci    * @param loop indicates the pointer to the event loop.
814e41f4b71Sopenharmony_ci    * @param req indicates the pointer to the file operation request.
815e41f4b71Sopenharmony_ci    * @param file indicates the file descriptor.
816e41f4b71Sopenharmony_ci    * @param bufs indicates an array of buffers for storing the data read.
817e41f4b71Sopenharmony_ci    * @param nbufs indicates the number of buffers.
818e41f4b71Sopenharmony_ci    * @param off indicates the offset in the file from which data is read.
819e41f4b71Sopenharmony_ci    * @param cb indicates the callback to be invoked when the read operation is complete.
820e41f4b71Sopenharmony_ci    * @return Returns 0 if the operation is successful; returns -1 otherwise.
821e41f4b71Sopenharmony_ci    */
822e41f4b71Sopenharmony_ci    int uv_fs_read(uv_loop_t* loop, uv_fs_t* req,
823e41f4b71Sopenharmony_ci                  uv_file file, 
824e41f4b71Sopenharmony_ci                  const uv_buf_t bufs[],
825e41f4b71Sopenharmony_ci                  unsigned int nbufs,
826e41f4b71Sopenharmony_ci                  int64_t off,
827e41f4b71Sopenharmony_ci                  uv_fs_cb cb);
828e41f4b71Sopenharmony_ci    
829e41f4b71Sopenharmony_ci    /**
830e41f4b71Sopenharmony_ci    * Open a file asynchronously.
831e41f4b71Sopenharmony_ci    *
832e41f4b71Sopenharmony_ci    * @param loop indicates the pointer to the event loop.
833e41f4b71Sopenharmony_ci    * @param req indicates the pointer to the file operation request.
834e41f4b71Sopenharmony_ci    *  * @param path indicates the pointer to the path of the file to open.
835e41f4b71Sopenharmony_ci    * @param flags indicates the modes for opening the file.
836e41f4b71Sopenharmony_ci    *  * @param mode indicates the permission on the file.
837e41f4b71Sopenharmony_ci    * @param cb indicates the callback to be invoked when the file is opened.
838e41f4b71Sopenharmony_ci    *
839e41f4b71Sopenharmony_ci    * @return Returns 0 if the operation is successful; returns -1 otherwise.
840e41f4b71Sopenharmony_ci    */
841e41f4b71Sopenharmony_ci    int uv_fs_open(uv_loop_t* loop, 
842e41f4b71Sopenharmony_ci                   uv_fs_t* req,
843e41f4b71Sopenharmony_ci                   const char* path,
844e41f4b71Sopenharmony_ci                   int flags,
845e41f4b71Sopenharmony_ci                   int mode,
846e41f4b71Sopenharmony_ci                   uv_fs_cb cb);
847e41f4b71Sopenharmony_ci    
848e41f4b71Sopenharmony_ci    /**
849e41f4b71Sopenharmony_ci    * Sends data from a file to another asynchronously.
850e41f4b71Sopenharmony_ci    *
851e41f4b71Sopenharmony_ci    * @param loop indicates the pointer to the event loop.
852e41f4b71Sopenharmony_ci    * @param req indicates the pointer to the file operation request.
853e41f4b71Sopenharmony_ci    * @param out_fd indicates the file descriptor of the destination file.
854e41f4b71Sopenharmony_ci    * @param in_fd indicates the file descriptor of the source file.
855e41f4b71Sopenharmony_ci    * @param off indicates the offset in the source file from which data is sent.
856e41f4b71Sopenharmony_ci    * @param len indicates the length of the data to be sent.
857e41f4b71Sopenharmony_ci    * @param cb indicates the callback to be invoked when the data is sent.
858e41f4b71Sopenharmony_ci    *
859e41f4b71Sopenharmony_ci    * @return Returns 0 if the operation is successful; returns -1 otherwise.
860e41f4b71Sopenharmony_ci    */
861e41f4b71Sopenharmony_ci    int uv_fs_sendfile(uv_loop_t* loop,
862e41f4b71Sopenharmony_ci                       uv_fs_t* req,
863e41f4b71Sopenharmony_ci                       uv_file out_fd,
864e41f4b71Sopenharmony_ci                       uv_file in_fd,
865e41f4b71Sopenharmony_ci                       int64_t off,
866e41f4b71Sopenharmony_ci                       size_t len,
867e41f4b71Sopenharmony_ci                       uv_fs_cb cb);
868e41f4b71Sopenharmony_ci    
869e41f4b71Sopenharmony_ci    /**
870e41f4b71Sopenharmony_ci    * Write data to a file asynchronously.
871e41f4b71Sopenharmony_ci    *
872e41f4b71Sopenharmony_ci    * @param loop indicates the pointer to the event loop.
873e41f4b71Sopenharmony_ci    * @param req indicates the pointer to the file operation request.
874e41f4b71Sopenharmony_ci    * @param file indicates the file descriptor.
875e41f4b71Sopenharmony_ci    * * @param data indicates an array of buffers for storing the data to be written.
876e41f4b71Sopenharmony_ci    * @param nbufs indicates the number of buffers.
877e41f4b71Sopenharmony_ci    * @param off indicates the offset in the file from which data is written.
878e41f4b71Sopenharmony_ci    * @param cb indicates the callback to be invoked when the write operation is complete.
879e41f4b71Sopenharmony_ci    *
880e41f4b71Sopenharmony_ci    * @return Returns 0 if the operation is successful; returns -1 otherwise.
881e41f4b71Sopenharmony_ci    */
882e41f4b71Sopenharmony_ci    int uv_fs_write(uv_loop_t* loop, 
883e41f4b71Sopenharmony_ci                    uv_fs_t* req,
884e41f4b71Sopenharmony_ci                    uv_file file,
885e41f4b71Sopenharmony_ci                    const uv_buf_t bufs[],
886e41f4b71Sopenharmony_ci                    unsigned int nbufs,
887e41f4b71Sopenharmony_ci                    int64_t off,
888e41f4b71Sopenharmony_ci                    uv_fs_cb cb);
889e41f4b71Sopenharmony_ci    
890e41f4b71Sopenharmony_ci    /**
891e41f4b71Sopenharmony_ci    * Copy a file asynchronously.
892e41f4b71Sopenharmony_ci    *
893e41f4b71Sopenharmony_ci    * @param loop indicates the pointer to the event loop.
894e41f4b71Sopenharmony_ci    * @param req indicates the pointer to the file operation request.
895e41f4b71Sopenharmony_ci    * @param path indicates the pointer to the path of the file to copy.
896e41f4b71Sopenharmony_ci    * @param new_path indicates the pointer to the destination path.
897e41f4b71Sopenharmony_ci    * @param flags indicates the options for the copy operation.
898e41f4b71Sopenharmony_ci    * @param cb indicates the callback to be invoked when the copy operation is complete.
899e41f4b71Sopenharmony_ci    *
900e41f4b71Sopenharmony_ci    * @return Returns 0 if the operation is successful; returns -1 otherwise.
901e41f4b71Sopenharmony_ci    */
902e41f4b71Sopenharmony_ci    int uv_fs_copyfile(uv_loop_t* loop,
903e41f4b71Sopenharmony_ci                       uv_fs_t* req,
904e41f4b71Sopenharmony_ci                       const char* path,
905e41f4b71Sopenharmony_ci                       const char* new_path
906e41f4b71Sopenharmony_ci                       int flags,
907e41f4b71Sopenharmony_ci                       uv_fs_cb cb);
908e41f4b71Sopenharmony_ci    ```
909e41f4b71Sopenharmony_ci
910e41f4b71Sopenharmony_ci- uv_getaddrinfo_t
911e41f4b71Sopenharmony_ci
912e41f4b71Sopenharmony_ci     Function prototype:
913e41f4b71Sopenharmony_ci
914e41f4b71Sopenharmony_ci     ```cpp
915e41f4b71Sopenharmony_ci     /**
916e41f4b71Sopenharmony_ci     * Obtain address information asynchronously.
917e41f4b71Sopenharmony_ci     *
918e41f4b71Sopenharmony_ci     * @param loop indicates the pointer to the event loop.
919e41f4b71Sopenharmony_ci     * @param req indicates the pointer to the request for obtaining address information.
920e41f4b71Sopenharmony_ci     * @param cb indicates the callback to be invoked when the address information is obtained.
921e41f4b71Sopenharmony_ci     * @param hostname indicates the pointer to the host name to resolve.
922e41f4b71Sopenharmony_ci     * @param service indicates the pointer to the service name.
923e41f4b71Sopenharmony_ci     * @param hints indicates the pointer to the address information with additional address type constraints.
924e41f4b71Sopenharmony_ci     *
925e41f4b71Sopenharmony_ci     * @return Returns 0 if the operation is successful; returns -1 otherwise.
926e41f4b71Sopenharmony_ci     */
927e41f4b71Sopenharmony_ci     int uv_getaddrinfo(uv_loop_t* loop,
928e41f4b71Sopenharmony_ci                        uv_getaddrinfo_t* req,
929e41f4b71Sopenharmony_ci                        uv_getaddrinfo_cb cb,
930e41f4b71Sopenharmony_ci                        const char* hostname,
931e41f4b71Sopenharmony_ci                        const char* service,
932e41f4b71Sopenharmony_ci                        const struct addrinfo* hints);
933e41f4b71Sopenharmony_ci     ```
934e41f4b71Sopenharmony_ci
935e41f4b71Sopenharmony_ci- uv_getnameinfo_t
936e41f4b71Sopenharmony_ci
937e41f4b71Sopenharmony_ci     Function prototype:
938e41f4b71Sopenharmony_ci
939e41f4b71Sopenharmony_ci     ```cpp
940e41f4b71Sopenharmony_ci     /**
941e41f4b71Sopenharmony_ci     * Obtain name information asynchronously.
942e41f4b71Sopenharmony_ci     *
943e41f4b71Sopenharmony_ci     * @param loop indicates the pointer to the event loop.
944e41f4b71Sopenharmony_ci     * @param req indicates the pointer to the request.
945e41f4b71Sopenharmony_ci     * @param cb indicates the callback to be invoked when the name information is obtained.
946e41f4b71Sopenharmony_ci     * @param addr indicates the pointer to the address information to resolve.
947e41f4b71Sopenharmony_ci     * @param flags indicates the flags for controlling the behavior of the lookup.
948e41f4b71Sopenharmony_ci     *
949e41f4b71Sopenharmony_ci     * @return Returns 0 if the operation is successful; returns -1 otherwise.
950e41f4b71Sopenharmony_ci     */
951e41f4b71Sopenharmony_ci     int uv_getnameinfo(uv_loop_t* loop,
952e41f4b71Sopenharmony_ci                        uv_getnameinfo_t* req,
953e41f4b71Sopenharmony_ci                        uv_getnameinfo_cb getnameinfo_cb,
954e41f4b71Sopenharmony_ci                        const struct sockaddr* addr,
955e41f4b71Sopenharmony_ci                        int flags);
956e41f4b71Sopenharmony_ci     ```
957e41f4b71Sopenharmony_ci
958e41f4b71Sopenharmony_ciThe following APIs do not work as expected in the application main thread:
959e41f4b71Sopenharmony_ci
960e41f4b71Sopenharmony_ci- **Idle** handle
961e41f4b71Sopenharmony_ci- **prepare** handle
962e41f4b71Sopenharmony_ci- **check** handle
963e41f4b71Sopenharmony_ci- signal-related functions
964e41f4b71Sopenharmony_ci- Functions related to TCP and UDP
965e41f4b71Sopenharmony_ci
966e41f4b71Sopenharmony_ci## Case Study
967e41f4b71Sopenharmony_ci
968e41f4b71Sopenharmony_ci[Cause of Incorrect Triggering Time of the Timer Callback in the Main Thread of libuv](https://gitee.com/openharmony/third_party_libuv/wikis/06-Wiki-%E6%8A%80%E6%9C%AF%E8%B5%84%E6%BA%90/libuv%E4%B8%AD%E4%B8%BB%E7%BA%BF%E7%A8%8Btimer%E5%9B%9E%E8%B0%83%E4%BA%8B%E4%BB%B6%E8%A7%A6%E5%8F%91%E6%97%B6%E9%97%B4%E4%B8%8D%E6%AD%A3%E7%A1%AE%E5%8E%9F%E5%9B%A0)
969e41f4b71Sopenharmony_ci
970e41f4b71Sopenharmony_ci[Incorporating libuv Worker Threads to the FFRT](https://gitee.com/openharmony/third_party_libuv/wikis/06-Wiki-%E6%8A%80%E6%9C%AF%E8%B5%84%E6%BA%90/%20libuv%E5%B7%A5%E4%BD%9C%E7%BA%BF%E7%A8%8B%E6%8E%A5%E5%85%A5FFRT%E6%96%B9%E6%A1%88%E5%88%86%E6%9E%90)
971e41f4b71Sopenharmony_ci
972e41f4b71Sopenharmony_ci[FAQs for QoS-Aware libuv and Node-API Async API Improvements](https://gitee.com/openharmony/third_party_libuv/wikis/06-Wiki-%E6%8A%80%E6%9C%AF%E8%B5%84%E6%BA%90/QoS%E6%84%9F%E7%9F%A5%E7%9A%84libuv%E3%80%81napi%E5%BC%82%E6%AD%A5%E6%8E%A5%E5%8F%A3%E6%95%B4%E6%94%B9FAQ)
973