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 "task.h" 24e66f31c5Sopenharmony_ci 25e66f31c5Sopenharmony_ci#ifdef _WIN32 26e66f31c5Sopenharmony_ci# define putenv _putenv 27e66f31c5Sopenharmony_ci#endif 28e66f31c5Sopenharmony_ci 29e66f31c5Sopenharmony_ci#define INIT_CANCEL_INFO(ci, what) \ 30e66f31c5Sopenharmony_ci do { \ 31e66f31c5Sopenharmony_ci (ci)->reqs = (what); \ 32e66f31c5Sopenharmony_ci (ci)->nreqs = ARRAY_SIZE(what); \ 33e66f31c5Sopenharmony_ci (ci)->stride = sizeof((what)[0]); \ 34e66f31c5Sopenharmony_ci } \ 35e66f31c5Sopenharmony_ci while (0) 36e66f31c5Sopenharmony_ci 37e66f31c5Sopenharmony_cistruct cancel_info { 38e66f31c5Sopenharmony_ci void* reqs; 39e66f31c5Sopenharmony_ci unsigned nreqs; 40e66f31c5Sopenharmony_ci unsigned stride; 41e66f31c5Sopenharmony_ci uv_timer_t timer_handle; 42e66f31c5Sopenharmony_ci}; 43e66f31c5Sopenharmony_ci 44e66f31c5Sopenharmony_cistruct random_info { 45e66f31c5Sopenharmony_ci uv_random_t random_req; 46e66f31c5Sopenharmony_ci char buf[1]; 47e66f31c5Sopenharmony_ci}; 48e66f31c5Sopenharmony_ci 49e66f31c5Sopenharmony_cistatic unsigned fs_cb_called; 50e66f31c5Sopenharmony_cistatic unsigned done_cb_called; 51e66f31c5Sopenharmony_cistatic unsigned done2_cb_called; 52e66f31c5Sopenharmony_cistatic unsigned timer_cb_called; 53e66f31c5Sopenharmony_cistatic uv_work_t pause_reqs[4]; 54e66f31c5Sopenharmony_cistatic uv_sem_t pause_sems[ARRAY_SIZE(pause_reqs)]; 55e66f31c5Sopenharmony_ci 56e66f31c5Sopenharmony_ci 57e66f31c5Sopenharmony_cistatic void work_cb(uv_work_t* req) { 58e66f31c5Sopenharmony_ci uv_sem_wait(pause_sems + (req - pause_reqs)); 59e66f31c5Sopenharmony_ci} 60e66f31c5Sopenharmony_ci 61e66f31c5Sopenharmony_ci 62e66f31c5Sopenharmony_cistatic void done_cb(uv_work_t* req, int status) { 63e66f31c5Sopenharmony_ci uv_sem_destroy(pause_sems + (req - pause_reqs)); 64e66f31c5Sopenharmony_ci} 65e66f31c5Sopenharmony_ci 66e66f31c5Sopenharmony_ci 67e66f31c5Sopenharmony_cistatic void saturate_threadpool(void) { 68e66f31c5Sopenharmony_ci uv_loop_t* loop; 69e66f31c5Sopenharmony_ci char buf[64]; 70e66f31c5Sopenharmony_ci size_t i; 71e66f31c5Sopenharmony_ci 72e66f31c5Sopenharmony_ci snprintf(buf, 73e66f31c5Sopenharmony_ci sizeof(buf), 74e66f31c5Sopenharmony_ci "UV_THREADPOOL_SIZE=%lu", 75e66f31c5Sopenharmony_ci (unsigned long)ARRAY_SIZE(pause_reqs)); 76e66f31c5Sopenharmony_ci putenv(buf); 77e66f31c5Sopenharmony_ci 78e66f31c5Sopenharmony_ci loop = uv_default_loop(); 79e66f31c5Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(pause_reqs); i += 1) { 80e66f31c5Sopenharmony_ci ASSERT_OK(uv_sem_init(pause_sems + i, 0)); 81e66f31c5Sopenharmony_ci ASSERT_OK(uv_queue_work(loop, pause_reqs + i, work_cb, done_cb)); 82e66f31c5Sopenharmony_ci } 83e66f31c5Sopenharmony_ci} 84e66f31c5Sopenharmony_ci 85e66f31c5Sopenharmony_ci 86e66f31c5Sopenharmony_cistatic void unblock_threadpool(void) { 87e66f31c5Sopenharmony_ci size_t i; 88e66f31c5Sopenharmony_ci 89e66f31c5Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(pause_reqs); i += 1) 90e66f31c5Sopenharmony_ci uv_sem_post(pause_sems + i); 91e66f31c5Sopenharmony_ci} 92e66f31c5Sopenharmony_ci 93e66f31c5Sopenharmony_ci 94e66f31c5Sopenharmony_cistatic int known_broken(uv_req_t* req) { 95e66f31c5Sopenharmony_ci if (req->type != UV_FS) 96e66f31c5Sopenharmony_ci return 0; 97e66f31c5Sopenharmony_ci 98e66f31c5Sopenharmony_ci#ifdef __linux__ 99e66f31c5Sopenharmony_ci /* TODO(bnoordhuis) make cancellation work with io_uring */ 100e66f31c5Sopenharmony_ci switch (((uv_fs_t*) req)->fs_type) { 101e66f31c5Sopenharmony_ci case UV_FS_CLOSE: 102e66f31c5Sopenharmony_ci case UV_FS_FDATASYNC: 103e66f31c5Sopenharmony_ci case UV_FS_FSTAT: 104e66f31c5Sopenharmony_ci case UV_FS_FSYNC: 105e66f31c5Sopenharmony_ci case UV_FS_LINK: 106e66f31c5Sopenharmony_ci case UV_FS_LSTAT: 107e66f31c5Sopenharmony_ci case UV_FS_MKDIR: 108e66f31c5Sopenharmony_ci case UV_FS_OPEN: 109e66f31c5Sopenharmony_ci case UV_FS_READ: 110e66f31c5Sopenharmony_ci case UV_FS_RENAME: 111e66f31c5Sopenharmony_ci case UV_FS_STAT: 112e66f31c5Sopenharmony_ci case UV_FS_SYMLINK: 113e66f31c5Sopenharmony_ci case UV_FS_WRITE: 114e66f31c5Sopenharmony_ci case UV_FS_UNLINK: 115e66f31c5Sopenharmony_ci return 1; 116e66f31c5Sopenharmony_ci default: /* Squelch -Wswitch warnings. */ 117e66f31c5Sopenharmony_ci break; 118e66f31c5Sopenharmony_ci } 119e66f31c5Sopenharmony_ci#endif 120e66f31c5Sopenharmony_ci 121e66f31c5Sopenharmony_ci return 0; 122e66f31c5Sopenharmony_ci} 123e66f31c5Sopenharmony_ci 124e66f31c5Sopenharmony_ci 125e66f31c5Sopenharmony_cistatic void fs_cb(uv_fs_t* req) { 126e66f31c5Sopenharmony_ci ASSERT_NE(known_broken((uv_req_t*) req) || \ 127e66f31c5Sopenharmony_ci req->result == UV_ECANCELED, 0); 128e66f31c5Sopenharmony_ci uv_fs_req_cleanup(req); 129e66f31c5Sopenharmony_ci fs_cb_called++; 130e66f31c5Sopenharmony_ci} 131e66f31c5Sopenharmony_ci 132e66f31c5Sopenharmony_ci 133e66f31c5Sopenharmony_cistatic void getaddrinfo_cb(uv_getaddrinfo_t* req, 134e66f31c5Sopenharmony_ci int status, 135e66f31c5Sopenharmony_ci struct addrinfo* res) { 136e66f31c5Sopenharmony_ci ASSERT_EQ(status, UV_EAI_CANCELED); 137e66f31c5Sopenharmony_ci ASSERT_NULL(res); 138e66f31c5Sopenharmony_ci uv_freeaddrinfo(res); /* Should not crash. */ 139e66f31c5Sopenharmony_ci} 140e66f31c5Sopenharmony_ci 141e66f31c5Sopenharmony_ci 142e66f31c5Sopenharmony_cistatic void getnameinfo_cb(uv_getnameinfo_t* handle, 143e66f31c5Sopenharmony_ci int status, 144e66f31c5Sopenharmony_ci const char* hostname, 145e66f31c5Sopenharmony_ci const char* service) { 146e66f31c5Sopenharmony_ci ASSERT_EQ(status, UV_EAI_CANCELED); 147e66f31c5Sopenharmony_ci ASSERT_NULL(hostname); 148e66f31c5Sopenharmony_ci ASSERT_NULL(service); 149e66f31c5Sopenharmony_ci} 150e66f31c5Sopenharmony_ci 151e66f31c5Sopenharmony_ci 152e66f31c5Sopenharmony_cistatic void work2_cb(uv_work_t* req) { 153e66f31c5Sopenharmony_ci ASSERT(0 && "work2_cb called"); 154e66f31c5Sopenharmony_ci} 155e66f31c5Sopenharmony_ci 156e66f31c5Sopenharmony_ci 157e66f31c5Sopenharmony_cistatic void done2_cb(uv_work_t* req, int status) { 158e66f31c5Sopenharmony_ci ASSERT_EQ(status, UV_ECANCELED); 159e66f31c5Sopenharmony_ci done2_cb_called++; 160e66f31c5Sopenharmony_ci} 161e66f31c5Sopenharmony_ci 162e66f31c5Sopenharmony_ci 163e66f31c5Sopenharmony_cistatic void timer_cb(uv_timer_t* handle) { 164e66f31c5Sopenharmony_ci struct cancel_info* ci; 165e66f31c5Sopenharmony_ci uv_req_t* req; 166e66f31c5Sopenharmony_ci unsigned i; 167e66f31c5Sopenharmony_ci 168e66f31c5Sopenharmony_ci ci = container_of(handle, struct cancel_info, timer_handle); 169e66f31c5Sopenharmony_ci 170e66f31c5Sopenharmony_ci for (i = 0; i < ci->nreqs; i++) { 171e66f31c5Sopenharmony_ci req = (uv_req_t*) ((char*) ci->reqs + i * ci->stride); 172e66f31c5Sopenharmony_ci ASSERT(known_broken(req) || 0 == uv_cancel(req)); 173e66f31c5Sopenharmony_ci } 174e66f31c5Sopenharmony_ci 175e66f31c5Sopenharmony_ci uv_close((uv_handle_t*) &ci->timer_handle, NULL); 176e66f31c5Sopenharmony_ci unblock_threadpool(); 177e66f31c5Sopenharmony_ci timer_cb_called++; 178e66f31c5Sopenharmony_ci} 179e66f31c5Sopenharmony_ci 180e66f31c5Sopenharmony_ci 181e66f31c5Sopenharmony_cistatic void nop_done_cb(uv_work_t* req, int status) { 182e66f31c5Sopenharmony_ci ASSERT_EQ(status, UV_ECANCELED); 183e66f31c5Sopenharmony_ci done_cb_called++; 184e66f31c5Sopenharmony_ci} 185e66f31c5Sopenharmony_ci 186e66f31c5Sopenharmony_ci 187e66f31c5Sopenharmony_cistatic void nop_random_cb(uv_random_t* req, int status, void* buf, size_t len) { 188e66f31c5Sopenharmony_ci struct random_info* ri; 189e66f31c5Sopenharmony_ci 190e66f31c5Sopenharmony_ci ri = container_of(req, struct random_info, random_req); 191e66f31c5Sopenharmony_ci 192e66f31c5Sopenharmony_ci ASSERT_EQ(status, UV_ECANCELED); 193e66f31c5Sopenharmony_ci ASSERT_PTR_EQ(buf, (void*) ri->buf); 194e66f31c5Sopenharmony_ci ASSERT_EQ(len, sizeof(ri->buf)); 195e66f31c5Sopenharmony_ci 196e66f31c5Sopenharmony_ci done_cb_called++; 197e66f31c5Sopenharmony_ci} 198e66f31c5Sopenharmony_ci 199e66f31c5Sopenharmony_ci 200e66f31c5Sopenharmony_ciTEST_IMPL(threadpool_cancel_getaddrinfo) { 201e66f31c5Sopenharmony_ci uv_getaddrinfo_t reqs[4]; 202e66f31c5Sopenharmony_ci struct cancel_info ci; 203e66f31c5Sopenharmony_ci struct addrinfo hints; 204e66f31c5Sopenharmony_ci uv_loop_t* loop; 205e66f31c5Sopenharmony_ci int r; 206e66f31c5Sopenharmony_ci 207e66f31c5Sopenharmony_ci INIT_CANCEL_INFO(&ci, reqs); 208e66f31c5Sopenharmony_ci loop = uv_default_loop(); 209e66f31c5Sopenharmony_ci saturate_threadpool(); 210e66f31c5Sopenharmony_ci 211e66f31c5Sopenharmony_ci r = uv_getaddrinfo(loop, reqs + 0, getaddrinfo_cb, "fail", NULL, NULL); 212e66f31c5Sopenharmony_ci ASSERT_OK(r); 213e66f31c5Sopenharmony_ci 214e66f31c5Sopenharmony_ci r = uv_getaddrinfo(loop, reqs + 1, getaddrinfo_cb, NULL, "fail", NULL); 215e66f31c5Sopenharmony_ci ASSERT_OK(r); 216e66f31c5Sopenharmony_ci 217e66f31c5Sopenharmony_ci r = uv_getaddrinfo(loop, reqs + 2, getaddrinfo_cb, "fail", "fail", NULL); 218e66f31c5Sopenharmony_ci ASSERT_OK(r); 219e66f31c5Sopenharmony_ci 220e66f31c5Sopenharmony_ci r = uv_getaddrinfo(loop, reqs + 3, getaddrinfo_cb, "fail", NULL, &hints); 221e66f31c5Sopenharmony_ci ASSERT_OK(r); 222e66f31c5Sopenharmony_ci 223e66f31c5Sopenharmony_ci ASSERT_OK(uv_timer_init(loop, &ci.timer_handle)); 224e66f31c5Sopenharmony_ci ASSERT_OK(uv_timer_start(&ci.timer_handle, timer_cb, 10, 0)); 225e66f31c5Sopenharmony_ci ASSERT_OK(uv_run(loop, UV_RUN_DEFAULT)); 226e66f31c5Sopenharmony_ci ASSERT_EQ(1, timer_cb_called); 227e66f31c5Sopenharmony_ci 228e66f31c5Sopenharmony_ci MAKE_VALGRIND_HAPPY(loop); 229e66f31c5Sopenharmony_ci return 0; 230e66f31c5Sopenharmony_ci} 231e66f31c5Sopenharmony_ci 232e66f31c5Sopenharmony_ci 233e66f31c5Sopenharmony_ciTEST_IMPL(threadpool_cancel_getnameinfo) { 234e66f31c5Sopenharmony_ci uv_getnameinfo_t reqs[4]; 235e66f31c5Sopenharmony_ci struct sockaddr_in addr4; 236e66f31c5Sopenharmony_ci struct cancel_info ci; 237e66f31c5Sopenharmony_ci uv_loop_t* loop; 238e66f31c5Sopenharmony_ci int r; 239e66f31c5Sopenharmony_ci 240e66f31c5Sopenharmony_ci r = uv_ip4_addr("127.0.0.1", 80, &addr4); 241e66f31c5Sopenharmony_ci ASSERT_OK(r); 242e66f31c5Sopenharmony_ci 243e66f31c5Sopenharmony_ci INIT_CANCEL_INFO(&ci, reqs); 244e66f31c5Sopenharmony_ci loop = uv_default_loop(); 245e66f31c5Sopenharmony_ci saturate_threadpool(); 246e66f31c5Sopenharmony_ci 247e66f31c5Sopenharmony_ci r = uv_getnameinfo(loop, reqs + 0, getnameinfo_cb, (const struct sockaddr*)&addr4, 0); 248e66f31c5Sopenharmony_ci ASSERT_OK(r); 249e66f31c5Sopenharmony_ci 250e66f31c5Sopenharmony_ci r = uv_getnameinfo(loop, reqs + 1, getnameinfo_cb, (const struct sockaddr*)&addr4, 0); 251e66f31c5Sopenharmony_ci ASSERT_OK(r); 252e66f31c5Sopenharmony_ci 253e66f31c5Sopenharmony_ci r = uv_getnameinfo(loop, reqs + 2, getnameinfo_cb, (const struct sockaddr*)&addr4, 0); 254e66f31c5Sopenharmony_ci ASSERT_OK(r); 255e66f31c5Sopenharmony_ci 256e66f31c5Sopenharmony_ci r = uv_getnameinfo(loop, reqs + 3, getnameinfo_cb, (const struct sockaddr*)&addr4, 0); 257e66f31c5Sopenharmony_ci ASSERT_OK(r); 258e66f31c5Sopenharmony_ci 259e66f31c5Sopenharmony_ci ASSERT_OK(uv_timer_init(loop, &ci.timer_handle)); 260e66f31c5Sopenharmony_ci ASSERT_OK(uv_timer_start(&ci.timer_handle, timer_cb, 10, 0)); 261e66f31c5Sopenharmony_ci ASSERT_OK(uv_run(loop, UV_RUN_DEFAULT)); 262e66f31c5Sopenharmony_ci ASSERT_EQ(1, timer_cb_called); 263e66f31c5Sopenharmony_ci 264e66f31c5Sopenharmony_ci MAKE_VALGRIND_HAPPY(loop); 265e66f31c5Sopenharmony_ci return 0; 266e66f31c5Sopenharmony_ci} 267e66f31c5Sopenharmony_ci 268e66f31c5Sopenharmony_ci 269e66f31c5Sopenharmony_ciTEST_IMPL(threadpool_cancel_random) { 270e66f31c5Sopenharmony_ci struct random_info req; 271e66f31c5Sopenharmony_ci uv_loop_t* loop; 272e66f31c5Sopenharmony_ci 273e66f31c5Sopenharmony_ci saturate_threadpool(); 274e66f31c5Sopenharmony_ci loop = uv_default_loop(); 275e66f31c5Sopenharmony_ci ASSERT_OK(uv_random(loop, 276e66f31c5Sopenharmony_ci &req.random_req, 277e66f31c5Sopenharmony_ci &req.buf, 278e66f31c5Sopenharmony_ci sizeof(req.buf), 279e66f31c5Sopenharmony_ci 0, 280e66f31c5Sopenharmony_ci nop_random_cb)); 281e66f31c5Sopenharmony_ci ASSERT_OK(uv_cancel((uv_req_t*) &req)); 282e66f31c5Sopenharmony_ci ASSERT_OK(done_cb_called); 283e66f31c5Sopenharmony_ci unblock_threadpool(); 284e66f31c5Sopenharmony_ci ASSERT_OK(uv_run(loop, UV_RUN_DEFAULT)); 285e66f31c5Sopenharmony_ci ASSERT_EQ(1, done_cb_called); 286e66f31c5Sopenharmony_ci 287e66f31c5Sopenharmony_ci MAKE_VALGRIND_HAPPY(loop); 288e66f31c5Sopenharmony_ci return 0; 289e66f31c5Sopenharmony_ci} 290e66f31c5Sopenharmony_ci 291e66f31c5Sopenharmony_ci 292e66f31c5Sopenharmony_ciTEST_IMPL(threadpool_cancel_work) { 293e66f31c5Sopenharmony_ci struct cancel_info ci; 294e66f31c5Sopenharmony_ci uv_work_t reqs[16]; 295e66f31c5Sopenharmony_ci uv_loop_t* loop; 296e66f31c5Sopenharmony_ci unsigned i; 297e66f31c5Sopenharmony_ci 298e66f31c5Sopenharmony_ci INIT_CANCEL_INFO(&ci, reqs); 299e66f31c5Sopenharmony_ci loop = uv_default_loop(); 300e66f31c5Sopenharmony_ci saturate_threadpool(); 301e66f31c5Sopenharmony_ci 302e66f31c5Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(reqs); i++) 303e66f31c5Sopenharmony_ci ASSERT_OK(uv_queue_work(loop, reqs + i, work2_cb, done2_cb)); 304e66f31c5Sopenharmony_ci 305e66f31c5Sopenharmony_ci ASSERT_OK(uv_timer_init(loop, &ci.timer_handle)); 306e66f31c5Sopenharmony_ci ASSERT_OK(uv_timer_start(&ci.timer_handle, timer_cb, 10, 0)); 307e66f31c5Sopenharmony_ci ASSERT_OK(uv_run(loop, UV_RUN_DEFAULT)); 308e66f31c5Sopenharmony_ci ASSERT_EQ(1, timer_cb_called); 309e66f31c5Sopenharmony_ci ASSERT_EQ(ARRAY_SIZE(reqs), done2_cb_called); 310e66f31c5Sopenharmony_ci 311e66f31c5Sopenharmony_ci MAKE_VALGRIND_HAPPY(loop); 312e66f31c5Sopenharmony_ci return 0; 313e66f31c5Sopenharmony_ci} 314e66f31c5Sopenharmony_ci 315e66f31c5Sopenharmony_ci 316e66f31c5Sopenharmony_ciTEST_IMPL(threadpool_cancel_fs) { 317e66f31c5Sopenharmony_ci struct cancel_info ci; 318e66f31c5Sopenharmony_ci uv_fs_t reqs[26]; 319e66f31c5Sopenharmony_ci uv_loop_t* loop; 320e66f31c5Sopenharmony_ci unsigned n; 321e66f31c5Sopenharmony_ci uv_buf_t iov; 322e66f31c5Sopenharmony_ci 323e66f31c5Sopenharmony_ci INIT_CANCEL_INFO(&ci, reqs); 324e66f31c5Sopenharmony_ci loop = uv_default_loop(); 325e66f31c5Sopenharmony_ci saturate_threadpool(); 326e66f31c5Sopenharmony_ci iov = uv_buf_init(NULL, 0); 327e66f31c5Sopenharmony_ci 328e66f31c5Sopenharmony_ci /* Needs to match ARRAY_SIZE(fs_reqs). */ 329e66f31c5Sopenharmony_ci n = 0; 330e66f31c5Sopenharmony_ci ASSERT_OK(uv_fs_chmod(loop, reqs + n++, "/", 0, fs_cb)); 331e66f31c5Sopenharmony_ci ASSERT_OK(uv_fs_chown(loop, reqs + n++, "/", 0, 0, fs_cb)); 332e66f31c5Sopenharmony_ci ASSERT_OK(uv_fs_close(loop, reqs + n++, 0, fs_cb)); 333e66f31c5Sopenharmony_ci ASSERT_OK(uv_fs_fchmod(loop, reqs + n++, 0, 0, fs_cb)); 334e66f31c5Sopenharmony_ci ASSERT_OK(uv_fs_fchown(loop, reqs + n++, 0, 0, 0, fs_cb)); 335e66f31c5Sopenharmony_ci ASSERT_OK(uv_fs_fdatasync(loop, reqs + n++, 0, fs_cb)); 336e66f31c5Sopenharmony_ci ASSERT_OK(uv_fs_fstat(loop, reqs + n++, 0, fs_cb)); 337e66f31c5Sopenharmony_ci ASSERT_OK(uv_fs_fsync(loop, reqs + n++, 0, fs_cb)); 338e66f31c5Sopenharmony_ci ASSERT_OK(uv_fs_ftruncate(loop, reqs + n++, 0, 0, fs_cb)); 339e66f31c5Sopenharmony_ci ASSERT_OK(uv_fs_futime(loop, reqs + n++, 0, 0, 0, fs_cb)); 340e66f31c5Sopenharmony_ci ASSERT_OK(uv_fs_link(loop, reqs + n++, "/", "/", fs_cb)); 341e66f31c5Sopenharmony_ci ASSERT_OK(uv_fs_lstat(loop, reqs + n++, "/", fs_cb)); 342e66f31c5Sopenharmony_ci ASSERT_OK(uv_fs_mkdir(loop, reqs + n++, "/", 0, fs_cb)); 343e66f31c5Sopenharmony_ci ASSERT_OK(uv_fs_open(loop, reqs + n++, "/", 0, 0, fs_cb)); 344e66f31c5Sopenharmony_ci ASSERT_OK(uv_fs_read(loop, reqs + n++, -1, &iov, 1, 0, fs_cb)); 345e66f31c5Sopenharmony_ci ASSERT_OK(uv_fs_scandir(loop, reqs + n++, "/", 0, fs_cb)); 346e66f31c5Sopenharmony_ci ASSERT_OK(uv_fs_readlink(loop, reqs + n++, "/", fs_cb)); 347e66f31c5Sopenharmony_ci ASSERT_OK(uv_fs_realpath(loop, reqs + n++, "/", fs_cb)); 348e66f31c5Sopenharmony_ci ASSERT_OK(uv_fs_rename(loop, reqs + n++, "/", "/", fs_cb)); 349e66f31c5Sopenharmony_ci ASSERT_OK(uv_fs_mkdir(loop, reqs + n++, "/", 0, fs_cb)); 350e66f31c5Sopenharmony_ci ASSERT_OK(uv_fs_sendfile(loop, reqs + n++, 0, 0, 0, 0, fs_cb)); 351e66f31c5Sopenharmony_ci ASSERT_OK(uv_fs_stat(loop, reqs + n++, "/", fs_cb)); 352e66f31c5Sopenharmony_ci ASSERT_OK(uv_fs_symlink(loop, reqs + n++, "/", "/", 0, fs_cb)); 353e66f31c5Sopenharmony_ci ASSERT_OK(uv_fs_unlink(loop, reqs + n++, "/", fs_cb)); 354e66f31c5Sopenharmony_ci ASSERT_OK(uv_fs_utime(loop, reqs + n++, "/", 0, 0, fs_cb)); 355e66f31c5Sopenharmony_ci ASSERT_OK(uv_fs_write(loop, reqs + n++, -1, &iov, 1, 0, fs_cb)); 356e66f31c5Sopenharmony_ci ASSERT_EQ(n, ARRAY_SIZE(reqs)); 357e66f31c5Sopenharmony_ci 358e66f31c5Sopenharmony_ci ASSERT_OK(uv_timer_init(loop, &ci.timer_handle)); 359e66f31c5Sopenharmony_ci ASSERT_OK(uv_timer_start(&ci.timer_handle, timer_cb, 10, 0)); 360e66f31c5Sopenharmony_ci ASSERT_OK(uv_run(loop, UV_RUN_DEFAULT)); 361e66f31c5Sopenharmony_ci ASSERT_EQ(n, fs_cb_called); 362e66f31c5Sopenharmony_ci ASSERT_EQ(1, timer_cb_called); 363e66f31c5Sopenharmony_ci 364e66f31c5Sopenharmony_ci 365e66f31c5Sopenharmony_ci MAKE_VALGRIND_HAPPY(loop); 366e66f31c5Sopenharmony_ci return 0; 367e66f31c5Sopenharmony_ci} 368e66f31c5Sopenharmony_ci 369e66f31c5Sopenharmony_ci 370e66f31c5Sopenharmony_ciTEST_IMPL(threadpool_cancel_single) { 371e66f31c5Sopenharmony_ci uv_loop_t* loop; 372e66f31c5Sopenharmony_ci uv_work_t req; 373e66f31c5Sopenharmony_ci 374e66f31c5Sopenharmony_ci saturate_threadpool(); 375e66f31c5Sopenharmony_ci loop = uv_default_loop(); 376e66f31c5Sopenharmony_ci ASSERT_OK(uv_queue_work(loop, &req, (uv_work_cb) abort, nop_done_cb)); 377e66f31c5Sopenharmony_ci ASSERT_OK(uv_cancel((uv_req_t*) &req)); 378e66f31c5Sopenharmony_ci ASSERT_OK(done_cb_called); 379e66f31c5Sopenharmony_ci unblock_threadpool(); 380e66f31c5Sopenharmony_ci ASSERT_OK(uv_run(loop, UV_RUN_DEFAULT)); 381e66f31c5Sopenharmony_ci ASSERT_EQ(1, done_cb_called); 382e66f31c5Sopenharmony_ci 383e66f31c5Sopenharmony_ci MAKE_VALGRIND_HAPPY(loop); 384e66f31c5Sopenharmony_ci return 0; 385e66f31c5Sopenharmony_ci} 386e66f31c5Sopenharmony_ci 387e66f31c5Sopenharmony_ci 388e66f31c5Sopenharmony_cistatic void after_busy_cb(uv_work_t* req, int status) { 389e66f31c5Sopenharmony_ci ASSERT_OK(status); 390e66f31c5Sopenharmony_ci done_cb_called++; 391e66f31c5Sopenharmony_ci} 392e66f31c5Sopenharmony_ci 393e66f31c5Sopenharmony_cistatic void busy_cb(uv_work_t* req) { 394e66f31c5Sopenharmony_ci uv_sem_post((uv_sem_t*) req->data); 395e66f31c5Sopenharmony_ci /* Assume that calling uv_cancel() takes less than 10ms. */ 396e66f31c5Sopenharmony_ci uv_sleep(10); 397e66f31c5Sopenharmony_ci} 398e66f31c5Sopenharmony_ci 399e66f31c5Sopenharmony_ciTEST_IMPL(threadpool_cancel_when_busy) { 400e66f31c5Sopenharmony_ci uv_sem_t sem_lock; 401e66f31c5Sopenharmony_ci uv_work_t req; 402e66f31c5Sopenharmony_ci 403e66f31c5Sopenharmony_ci req.data = &sem_lock; 404e66f31c5Sopenharmony_ci 405e66f31c5Sopenharmony_ci ASSERT_OK(uv_sem_init(&sem_lock, 0)); 406e66f31c5Sopenharmony_ci ASSERT_OK(uv_queue_work(uv_default_loop(), &req, busy_cb, after_busy_cb)); 407e66f31c5Sopenharmony_ci 408e66f31c5Sopenharmony_ci uv_sem_wait(&sem_lock); 409e66f31c5Sopenharmony_ci 410e66f31c5Sopenharmony_ci ASSERT_EQ(uv_cancel((uv_req_t*) &req), UV_EBUSY); 411e66f31c5Sopenharmony_ci ASSERT_OK(uv_run(uv_default_loop(), UV_RUN_DEFAULT)); 412e66f31c5Sopenharmony_ci ASSERT_EQ(1, done_cb_called); 413e66f31c5Sopenharmony_ci 414e66f31c5Sopenharmony_ci uv_sem_destroy(&sem_lock); 415e66f31c5Sopenharmony_ci 416e66f31c5Sopenharmony_ci MAKE_VALGRIND_HAPPY(uv_default_loop()); 417e66f31c5Sopenharmony_ci return 0; 418e66f31c5Sopenharmony_ci} 419