1d4afb5ceSopenharmony_ci/* 2d4afb5ceSopenharmony_ci * libwebsockets - small server side websockets and web server implementation 3d4afb5ceSopenharmony_ci * 4d4afb5ceSopenharmony_ci * Copyright (C) 2010 - 2020 Andy Green <andy@warmcat.com> 5d4afb5ceSopenharmony_ci * 6d4afb5ceSopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a copy 7d4afb5ceSopenharmony_ci * of this software and associated documentation files (the "Software"), to 8d4afb5ceSopenharmony_ci * deal in the Software without restriction, including without limitation the 9d4afb5ceSopenharmony_ci * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 10d4afb5ceSopenharmony_ci * sell copies of the Software, and to permit persons to whom the Software is 11d4afb5ceSopenharmony_ci * furnished to do so, subject to the following conditions: 12d4afb5ceSopenharmony_ci * 13d4afb5ceSopenharmony_ci * The above copyright notice and this permission notice shall be included in 14d4afb5ceSopenharmony_ci * all copies or substantial portions of the Software. 15d4afb5ceSopenharmony_ci * 16d4afb5ceSopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17d4afb5ceSopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18d4afb5ceSopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19d4afb5ceSopenharmony_ci * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20d4afb5ceSopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21d4afb5ceSopenharmony_ci * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 22d4afb5ceSopenharmony_ci * IN THE SOFTWARE. 23d4afb5ceSopenharmony_ci */ 24d4afb5ceSopenharmony_ci 25d4afb5ceSopenharmony_ci#include "private-lib-core.h" 26d4afb5ceSopenharmony_ci#include "private-lib-event-libs-libev.h" 27d4afb5ceSopenharmony_ci 28d4afb5ceSopenharmony_ci#define pt_to_priv_ev(_pt) ((struct lws_pt_eventlibs_libev *)(_pt)->evlib_pt) 29d4afb5ceSopenharmony_ci#define vh_to_priv_ev(_vh) ((struct lws_vh_eventlibs_libev *)(_vh)->evlib_vh) 30d4afb5ceSopenharmony_ci#define wsi_to_priv_ev(_w) ((struct lws_wsi_eventlibs_libev *)(_w)->evlib_wsi) 31d4afb5ceSopenharmony_ci 32d4afb5ceSopenharmony_cistatic void 33d4afb5ceSopenharmony_cilws_ev_hrtimer_cb(struct ev_loop *loop, struct ev_timer *watcher, int revents) 34d4afb5ceSopenharmony_ci{ 35d4afb5ceSopenharmony_ci struct lws_pt_eventlibs_libev *ptpr = lws_container_of(watcher, 36d4afb5ceSopenharmony_ci struct lws_pt_eventlibs_libev, hrtimer); 37d4afb5ceSopenharmony_ci struct lws_context_per_thread *pt = ptpr->pt; 38d4afb5ceSopenharmony_ci lws_usec_t us; 39d4afb5ceSopenharmony_ci 40d4afb5ceSopenharmony_ci lws_pt_lock(pt, __func__); 41d4afb5ceSopenharmony_ci us = __lws_sul_service_ripe(pt->pt_sul_owner, LWS_COUNT_PT_SUL_OWNERS, 42d4afb5ceSopenharmony_ci lws_now_usecs()); 43d4afb5ceSopenharmony_ci if (us) { 44d4afb5ceSopenharmony_ci ev_timer_set(&ptpr->hrtimer, ((float)us) / 1000000.0, 0); 45d4afb5ceSopenharmony_ci ev_timer_start(ptpr->io_loop, &ptpr->hrtimer); 46d4afb5ceSopenharmony_ci } 47d4afb5ceSopenharmony_ci lws_pt_unlock(pt); 48d4afb5ceSopenharmony_ci} 49d4afb5ceSopenharmony_ci 50d4afb5ceSopenharmony_cistatic void 51d4afb5ceSopenharmony_cilws_ev_idle_cb(struct ev_loop *loop, struct ev_idle *handle, int revents) 52d4afb5ceSopenharmony_ci{ 53d4afb5ceSopenharmony_ci struct lws_pt_eventlibs_libev *ptpr = lws_container_of(handle, 54d4afb5ceSopenharmony_ci struct lws_pt_eventlibs_libev, idle); 55d4afb5ceSopenharmony_ci struct lws_context_per_thread *pt = ptpr->pt; 56d4afb5ceSopenharmony_ci int reschedule = 0; 57d4afb5ceSopenharmony_ci lws_usec_t us; 58d4afb5ceSopenharmony_ci 59d4afb5ceSopenharmony_ci lws_service_do_ripe_rxflow(pt); 60d4afb5ceSopenharmony_ci 61d4afb5ceSopenharmony_ci /* 62d4afb5ceSopenharmony_ci * is there anybody with pending stuff that needs service forcing? 63d4afb5ceSopenharmony_ci */ 64d4afb5ceSopenharmony_ci if (!lws_service_adjust_timeout(pt->context, 1, pt->tid)) 65d4afb5ceSopenharmony_ci /* -1 timeout means just do forced service */ 66d4afb5ceSopenharmony_ci reschedule = _lws_plat_service_forced_tsi(pt->context, pt->tid); 67d4afb5ceSopenharmony_ci 68d4afb5ceSopenharmony_ci /* account for hrtimer */ 69d4afb5ceSopenharmony_ci 70d4afb5ceSopenharmony_ci lws_pt_lock(pt, __func__); 71d4afb5ceSopenharmony_ci us = __lws_sul_service_ripe(pt->pt_sul_owner, LWS_COUNT_PT_SUL_OWNERS, 72d4afb5ceSopenharmony_ci lws_now_usecs()); 73d4afb5ceSopenharmony_ci if (us) { 74d4afb5ceSopenharmony_ci ev_timer_set(&ptpr->hrtimer, ((float)us) / 1000000.0, 0); 75d4afb5ceSopenharmony_ci ev_timer_start(ptpr->io_loop, &ptpr->hrtimer); 76d4afb5ceSopenharmony_ci } 77d4afb5ceSopenharmony_ci lws_pt_unlock(pt); 78d4afb5ceSopenharmony_ci 79d4afb5ceSopenharmony_ci /* there is nobody who needs service forcing, shut down idle */ 80d4afb5ceSopenharmony_ci if (!reschedule) 81d4afb5ceSopenharmony_ci ev_idle_stop(loop, handle); 82d4afb5ceSopenharmony_ci 83d4afb5ceSopenharmony_ci if (pt->destroy_self) 84d4afb5ceSopenharmony_ci lws_context_destroy(pt->context); 85d4afb5ceSopenharmony_ci} 86d4afb5ceSopenharmony_ci 87d4afb5ceSopenharmony_cistatic void 88d4afb5ceSopenharmony_cilws_accept_cb(struct ev_loop *loop, struct ev_io *watcher, int revents) 89d4afb5ceSopenharmony_ci{ 90d4afb5ceSopenharmony_ci struct lws_io_watcher_libev *lws_io = lws_container_of(watcher, 91d4afb5ceSopenharmony_ci struct lws_io_watcher_libev, watcher); 92d4afb5ceSopenharmony_ci struct lws_context *context = lws_io->context; 93d4afb5ceSopenharmony_ci struct lws_pt_eventlibs_libev *ptpr; 94d4afb5ceSopenharmony_ci struct lws_context_per_thread *pt; 95d4afb5ceSopenharmony_ci struct lws_pollfd eventfd; 96d4afb5ceSopenharmony_ci struct lws *wsi; 97d4afb5ceSopenharmony_ci 98d4afb5ceSopenharmony_ci if (revents & EV_ERROR) 99d4afb5ceSopenharmony_ci return; 100d4afb5ceSopenharmony_ci 101d4afb5ceSopenharmony_ci eventfd.fd = watcher->fd; 102d4afb5ceSopenharmony_ci eventfd.events = 0; 103d4afb5ceSopenharmony_ci eventfd.revents = EV_NONE; 104d4afb5ceSopenharmony_ci 105d4afb5ceSopenharmony_ci if (revents & EV_READ) { 106d4afb5ceSopenharmony_ci eventfd.events |= LWS_POLLIN; 107d4afb5ceSopenharmony_ci eventfd.revents |= LWS_POLLIN; 108d4afb5ceSopenharmony_ci } 109d4afb5ceSopenharmony_ci if (revents & EV_WRITE) { 110d4afb5ceSopenharmony_ci eventfd.events |= LWS_POLLOUT; 111d4afb5ceSopenharmony_ci eventfd.revents |= LWS_POLLOUT; 112d4afb5ceSopenharmony_ci } 113d4afb5ceSopenharmony_ci 114d4afb5ceSopenharmony_ci wsi = wsi_from_fd(context, watcher->fd); 115d4afb5ceSopenharmony_ci pt = &context->pt[(int)wsi->tsi]; 116d4afb5ceSopenharmony_ci ptpr = pt_to_priv_ev(pt); 117d4afb5ceSopenharmony_ci 118d4afb5ceSopenharmony_ci lws_service_fd_tsi(context, &eventfd, (int)wsi->tsi); 119d4afb5ceSopenharmony_ci 120d4afb5ceSopenharmony_ci ev_idle_start(ptpr->io_loop, &ptpr->idle); 121d4afb5ceSopenharmony_ci} 122d4afb5ceSopenharmony_ci 123d4afb5ceSopenharmony_civoid 124d4afb5ceSopenharmony_cilws_ev_sigint_cb(struct ev_loop *loop, struct ev_signal *watcher, int revents) 125d4afb5ceSopenharmony_ci{ 126d4afb5ceSopenharmony_ci struct lws_context *context = watcher->data; 127d4afb5ceSopenharmony_ci 128d4afb5ceSopenharmony_ci if (context->eventlib_signal_cb) { 129d4afb5ceSopenharmony_ci context->eventlib_signal_cb((void *)watcher, watcher->signum); 130d4afb5ceSopenharmony_ci 131d4afb5ceSopenharmony_ci return; 132d4afb5ceSopenharmony_ci } 133d4afb5ceSopenharmony_ci ev_break(loop, EVBREAK_ALL); 134d4afb5ceSopenharmony_ci} 135d4afb5ceSopenharmony_ci 136d4afb5ceSopenharmony_cistatic int 137d4afb5ceSopenharmony_cielops_listen_init_ev(struct lws_dll2 *d, void *user) 138d4afb5ceSopenharmony_ci{ 139d4afb5ceSopenharmony_ci struct lws *wsi = lws_container_of(d, struct lws, listen_list); 140d4afb5ceSopenharmony_ci struct lws_context *context = (struct lws_context *)user; 141d4afb5ceSopenharmony_ci struct lws_context_per_thread *pt = &context->pt[(int)wsi->tsi]; 142d4afb5ceSopenharmony_ci struct lws_pt_eventlibs_libev *ptpr = pt_to_priv_ev(pt); 143d4afb5ceSopenharmony_ci struct lws_wsi_eventlibs_libev *w = wsi_to_priv_ev(wsi); 144d4afb5ceSopenharmony_ci struct lws_vhost *vh = wsi->a.vhost; 145d4afb5ceSopenharmony_ci 146d4afb5ceSopenharmony_ci w->w_read.context = context; 147d4afb5ceSopenharmony_ci w->w_write.context = context; 148d4afb5ceSopenharmony_ci vh_to_priv_ev(vh)->w_accept.context = context; 149d4afb5ceSopenharmony_ci 150d4afb5ceSopenharmony_ci ev_io_init(&vh_to_priv_ev(vh)->w_accept.watcher, 151d4afb5ceSopenharmony_ci lws_accept_cb, wsi->desc.sockfd, EV_READ); 152d4afb5ceSopenharmony_ci ev_io_start(ptpr->io_loop, &vh_to_priv_ev(vh)->w_accept.watcher); 153d4afb5ceSopenharmony_ci 154d4afb5ceSopenharmony_ci return 0; 155d4afb5ceSopenharmony_ci} 156d4afb5ceSopenharmony_ci 157d4afb5ceSopenharmony_cistatic int 158d4afb5ceSopenharmony_cielops_init_pt_ev(struct lws_context *context, void *_loop, int tsi) 159d4afb5ceSopenharmony_ci{ 160d4afb5ceSopenharmony_ci struct lws_context_per_thread *pt = &context->pt[tsi]; 161d4afb5ceSopenharmony_ci struct lws_pt_eventlibs_libev *ptpr = pt_to_priv_ev(pt); 162d4afb5ceSopenharmony_ci struct ev_signal *w_sigint = &ptpr->w_sigint.watcher; 163d4afb5ceSopenharmony_ci struct ev_loop *loop = (struct ev_loop *)_loop; 164d4afb5ceSopenharmony_ci const char *backend_name; 165d4afb5ceSopenharmony_ci unsigned int backend; 166d4afb5ceSopenharmony_ci int status = 0; 167d4afb5ceSopenharmony_ci 168d4afb5ceSopenharmony_ci lwsl_cx_info(context, "loop %p", _loop); 169d4afb5ceSopenharmony_ci 170d4afb5ceSopenharmony_ci ptpr->pt = pt; 171d4afb5ceSopenharmony_ci 172d4afb5ceSopenharmony_ci if (!loop) 173d4afb5ceSopenharmony_ci loop = ev_loop_new(0); 174d4afb5ceSopenharmony_ci else 175d4afb5ceSopenharmony_ci context->pt[tsi].event_loop_foreign = 1; 176d4afb5ceSopenharmony_ci 177d4afb5ceSopenharmony_ci if (!loop) { 178d4afb5ceSopenharmony_ci lwsl_cx_err(context, "creating event base failed"); 179d4afb5ceSopenharmony_ci 180d4afb5ceSopenharmony_ci return -1; 181d4afb5ceSopenharmony_ci } 182d4afb5ceSopenharmony_ci 183d4afb5ceSopenharmony_ci ptpr->io_loop = loop; 184d4afb5ceSopenharmony_ci 185d4afb5ceSopenharmony_ci lws_vhost_foreach_listen_wsi(context, context, elops_listen_init_ev); 186d4afb5ceSopenharmony_ci 187d4afb5ceSopenharmony_ci /* Register the signal watcher unless it's a foreign loop */ 188d4afb5ceSopenharmony_ci if (!context->pt[tsi].event_loop_foreign) { 189d4afb5ceSopenharmony_ci ev_signal_init(w_sigint, lws_ev_sigint_cb, SIGINT); 190d4afb5ceSopenharmony_ci w_sigint->data = context; 191d4afb5ceSopenharmony_ci ev_signal_start(loop, w_sigint); 192d4afb5ceSopenharmony_ci } 193d4afb5ceSopenharmony_ci 194d4afb5ceSopenharmony_ci backend = ev_backend(loop); 195d4afb5ceSopenharmony_ci switch (backend) { 196d4afb5ceSopenharmony_ci case EVBACKEND_SELECT: 197d4afb5ceSopenharmony_ci backend_name = "select"; 198d4afb5ceSopenharmony_ci break; 199d4afb5ceSopenharmony_ci case EVBACKEND_POLL: 200d4afb5ceSopenharmony_ci backend_name = "poll"; 201d4afb5ceSopenharmony_ci break; 202d4afb5ceSopenharmony_ci case EVBACKEND_EPOLL: 203d4afb5ceSopenharmony_ci backend_name = "epoll"; 204d4afb5ceSopenharmony_ci break; 205d4afb5ceSopenharmony_ci#if defined(LWS_HAVE_EVBACKEND_LINUXAIO) 206d4afb5ceSopenharmony_ci case EVBACKEND_LINUXAIO: 207d4afb5ceSopenharmony_ci backend_name = "Linux AIO"; 208d4afb5ceSopenharmony_ci break; 209d4afb5ceSopenharmony_ci#endif 210d4afb5ceSopenharmony_ci#if defined(LWS_HAVE_EVBACKEND_IOURING) 211d4afb5ceSopenharmony_ci case EVBACKEND_IOURING: 212d4afb5ceSopenharmony_ci backend_name = "Linux io_uring"; 213d4afb5ceSopenharmony_ci break; 214d4afb5ceSopenharmony_ci#endif 215d4afb5ceSopenharmony_ci case EVBACKEND_KQUEUE: 216d4afb5ceSopenharmony_ci backend_name = "kqueue"; 217d4afb5ceSopenharmony_ci break; 218d4afb5ceSopenharmony_ci case EVBACKEND_DEVPOLL: 219d4afb5ceSopenharmony_ci backend_name = "/dev/poll"; 220d4afb5ceSopenharmony_ci break; 221d4afb5ceSopenharmony_ci case EVBACKEND_PORT: 222d4afb5ceSopenharmony_ci backend_name = "Solaris 10 \"port\""; 223d4afb5ceSopenharmony_ci break; 224d4afb5ceSopenharmony_ci default: 225d4afb5ceSopenharmony_ci backend_name = "Unknown libev backend"; 226d4afb5ceSopenharmony_ci break; 227d4afb5ceSopenharmony_ci } 228d4afb5ceSopenharmony_ci 229d4afb5ceSopenharmony_ci lwsl_cx_info(context, " libev backend: %s", backend_name); 230d4afb5ceSopenharmony_ci (void)backend_name; 231d4afb5ceSopenharmony_ci 232d4afb5ceSopenharmony_ci ev_timer_init(&ptpr->hrtimer, lws_ev_hrtimer_cb, 0, 0); 233d4afb5ceSopenharmony_ci ptpr->hrtimer.data = pt; 234d4afb5ceSopenharmony_ci 235d4afb5ceSopenharmony_ci ev_idle_init(&ptpr->idle, lws_ev_idle_cb); 236d4afb5ceSopenharmony_ci 237d4afb5ceSopenharmony_ci return status; 238d4afb5ceSopenharmony_ci} 239d4afb5ceSopenharmony_ci 240d4afb5ceSopenharmony_cistatic int 241d4afb5ceSopenharmony_cielops_listen_destroy_ev(struct lws_dll2 *d, void *user) 242d4afb5ceSopenharmony_ci{ 243d4afb5ceSopenharmony_ci struct lws *wsi = lws_container_of(d, struct lws, listen_list); 244d4afb5ceSopenharmony_ci struct lws_context *context = (struct lws_context *)user; 245d4afb5ceSopenharmony_ci struct lws_context_per_thread *pt = &context->pt[(int)wsi->tsi]; 246d4afb5ceSopenharmony_ci struct lws_pt_eventlibs_libev *ptpr = pt_to_priv_ev(pt); 247d4afb5ceSopenharmony_ci struct lws_vhost *vh = wsi->a.vhost; 248d4afb5ceSopenharmony_ci 249d4afb5ceSopenharmony_ci ev_io_stop(ptpr->io_loop, &vh_to_priv_ev(vh)->w_accept.watcher); 250d4afb5ceSopenharmony_ci 251d4afb5ceSopenharmony_ci return 0; 252d4afb5ceSopenharmony_ci} 253d4afb5ceSopenharmony_ci 254d4afb5ceSopenharmony_cistatic void 255d4afb5ceSopenharmony_cielops_destroy_pt_ev(struct lws_context *context, int tsi) 256d4afb5ceSopenharmony_ci{ 257d4afb5ceSopenharmony_ci struct lws_context_per_thread *pt = &context->pt[tsi]; 258d4afb5ceSopenharmony_ci struct lws_pt_eventlibs_libev *ptpr = pt_to_priv_ev(pt); 259d4afb5ceSopenharmony_ci 260d4afb5ceSopenharmony_ci lws_vhost_foreach_listen_wsi(context, context, elops_listen_destroy_ev); 261d4afb5ceSopenharmony_ci 262d4afb5ceSopenharmony_ci /* static assets */ 263d4afb5ceSopenharmony_ci 264d4afb5ceSopenharmony_ci ev_timer_stop(ptpr->io_loop, &ptpr->hrtimer); 265d4afb5ceSopenharmony_ci ev_idle_stop(ptpr->io_loop, &ptpr->idle); 266d4afb5ceSopenharmony_ci 267d4afb5ceSopenharmony_ci if (!pt->event_loop_foreign) 268d4afb5ceSopenharmony_ci ev_signal_stop(ptpr->io_loop, &ptpr->w_sigint.watcher); 269d4afb5ceSopenharmony_ci} 270d4afb5ceSopenharmony_ci 271d4afb5ceSopenharmony_cistatic int 272d4afb5ceSopenharmony_cielops_init_context_ev(struct lws_context *context, 273d4afb5ceSopenharmony_ci const struct lws_context_creation_info *info) 274d4afb5ceSopenharmony_ci{ 275d4afb5ceSopenharmony_ci int n; 276d4afb5ceSopenharmony_ci 277d4afb5ceSopenharmony_ci context->eventlib_signal_cb = info->signal_cb; 278d4afb5ceSopenharmony_ci 279d4afb5ceSopenharmony_ci for (n = 0; n < context->count_threads; n++) 280d4afb5ceSopenharmony_ci pt_to_priv_ev(&context->pt[n])->w_sigint.context = context; 281d4afb5ceSopenharmony_ci 282d4afb5ceSopenharmony_ci return 0; 283d4afb5ceSopenharmony_ci} 284d4afb5ceSopenharmony_ci 285d4afb5ceSopenharmony_cistatic int 286d4afb5ceSopenharmony_cielops_accept_ev(struct lws *wsi) 287d4afb5ceSopenharmony_ci{ 288d4afb5ceSopenharmony_ci struct lws_wsi_eventlibs_libev *w = wsi_to_priv_ev(wsi); 289d4afb5ceSopenharmony_ci int fd; 290d4afb5ceSopenharmony_ci 291d4afb5ceSopenharmony_ci if (wsi->role_ops->file_handle) 292d4afb5ceSopenharmony_ci fd = wsi->desc.filefd; 293d4afb5ceSopenharmony_ci else 294d4afb5ceSopenharmony_ci fd = wsi->desc.sockfd; 295d4afb5ceSopenharmony_ci 296d4afb5ceSopenharmony_ci w->w_read.context = wsi->a.context; 297d4afb5ceSopenharmony_ci w->w_write.context = wsi->a.context; 298d4afb5ceSopenharmony_ci 299d4afb5ceSopenharmony_ci ev_io_init(&w->w_read.watcher, lws_accept_cb, fd, EV_READ); 300d4afb5ceSopenharmony_ci ev_io_init(&w->w_write.watcher, lws_accept_cb, fd, EV_WRITE); 301d4afb5ceSopenharmony_ci 302d4afb5ceSopenharmony_ci return 0; 303d4afb5ceSopenharmony_ci} 304d4afb5ceSopenharmony_ci 305d4afb5ceSopenharmony_cistatic void 306d4afb5ceSopenharmony_cielops_io_ev(struct lws *wsi, unsigned int flags) 307d4afb5ceSopenharmony_ci{ 308d4afb5ceSopenharmony_ci struct lws_context_per_thread *pt = &wsi->a.context->pt[(int)wsi->tsi]; 309d4afb5ceSopenharmony_ci struct lws_pt_eventlibs_libev *ptpr = pt_to_priv_ev(pt); 310d4afb5ceSopenharmony_ci struct lws_wsi_eventlibs_libev *w = wsi_to_priv_ev(wsi); 311d4afb5ceSopenharmony_ci 312d4afb5ceSopenharmony_ci lwsl_wsi_debug(wsi, "%s flags 0x%x %p %d", wsi->role_ops->name, flags, 313d4afb5ceSopenharmony_ci ptpr->io_loop, 314d4afb5ceSopenharmony_ci pt->is_destroyed); 315d4afb5ceSopenharmony_ci 316d4afb5ceSopenharmony_ci if (!ptpr->io_loop || pt->is_destroyed) 317d4afb5ceSopenharmony_ci return; 318d4afb5ceSopenharmony_ci 319d4afb5ceSopenharmony_ci assert((flags & (LWS_EV_START | LWS_EV_STOP)) && 320d4afb5ceSopenharmony_ci (flags & (LWS_EV_READ | LWS_EV_WRITE))); 321d4afb5ceSopenharmony_ci 322d4afb5ceSopenharmony_ci if (flags & LWS_EV_START) { 323d4afb5ceSopenharmony_ci if (flags & LWS_EV_WRITE) 324d4afb5ceSopenharmony_ci ev_io_start(ptpr->io_loop, &w->w_write.watcher); 325d4afb5ceSopenharmony_ci if (flags & LWS_EV_READ) 326d4afb5ceSopenharmony_ci ev_io_start(ptpr->io_loop, &w->w_read.watcher); 327d4afb5ceSopenharmony_ci } else { 328d4afb5ceSopenharmony_ci if (flags & LWS_EV_WRITE) 329d4afb5ceSopenharmony_ci ev_io_stop(ptpr->io_loop, &w->w_write.watcher); 330d4afb5ceSopenharmony_ci if (flags & LWS_EV_READ) 331d4afb5ceSopenharmony_ci ev_io_stop(ptpr->io_loop, &w->w_read.watcher); 332d4afb5ceSopenharmony_ci } 333d4afb5ceSopenharmony_ci 334d4afb5ceSopenharmony_ci if (pt->destroy_self) 335d4afb5ceSopenharmony_ci lws_context_destroy(pt->context); 336d4afb5ceSopenharmony_ci} 337d4afb5ceSopenharmony_ci 338d4afb5ceSopenharmony_cistatic void 339d4afb5ceSopenharmony_cielops_run_pt_ev(struct lws_context *context, int tsi) 340d4afb5ceSopenharmony_ci{ 341d4afb5ceSopenharmony_ci if (pt_to_priv_ev(&context->pt[tsi])->io_loop) 342d4afb5ceSopenharmony_ci ev_run(pt_to_priv_ev(&context->pt[tsi])->io_loop, 0); 343d4afb5ceSopenharmony_ci} 344d4afb5ceSopenharmony_ci 345d4afb5ceSopenharmony_cistatic int 346d4afb5ceSopenharmony_cielops_destroy_context2_ev(struct lws_context *context) 347d4afb5ceSopenharmony_ci{ 348d4afb5ceSopenharmony_ci struct lws_context_per_thread *pt; 349d4afb5ceSopenharmony_ci struct lws_pt_eventlibs_libev *ptpr; 350d4afb5ceSopenharmony_ci int n, m; 351d4afb5ceSopenharmony_ci 352d4afb5ceSopenharmony_ci for (n = 0; n < context->count_threads; n++) { 353d4afb5ceSopenharmony_ci int budget = 1000; 354d4afb5ceSopenharmony_ci 355d4afb5ceSopenharmony_ci pt = &context->pt[n]; 356d4afb5ceSopenharmony_ci ptpr = pt_to_priv_ev(pt); 357d4afb5ceSopenharmony_ci 358d4afb5ceSopenharmony_ci /* only for internal loops... */ 359d4afb5ceSopenharmony_ci 360d4afb5ceSopenharmony_ci if (pt->event_loop_foreign || !ptpr->io_loop) 361d4afb5ceSopenharmony_ci continue; 362d4afb5ceSopenharmony_ci 363d4afb5ceSopenharmony_ci if (!context->evlib_finalize_destroy_after_int_loops_stop) { 364d4afb5ceSopenharmony_ci ev_break(ptpr->io_loop, EVBREAK_ONE); 365d4afb5ceSopenharmony_ci continue; 366d4afb5ceSopenharmony_ci } 367d4afb5ceSopenharmony_ci while (budget-- && 368d4afb5ceSopenharmony_ci (m = ev_run(ptpr->io_loop, 0))) 369d4afb5ceSopenharmony_ci ; 370d4afb5ceSopenharmony_ci 371d4afb5ceSopenharmony_ci ev_loop_destroy(ptpr->io_loop); 372d4afb5ceSopenharmony_ci } 373d4afb5ceSopenharmony_ci 374d4afb5ceSopenharmony_ci return 0; 375d4afb5ceSopenharmony_ci} 376d4afb5ceSopenharmony_ci 377d4afb5ceSopenharmony_cistatic int 378d4afb5ceSopenharmony_cielops_init_vhost_listen_wsi_ev(struct lws *wsi) 379d4afb5ceSopenharmony_ci{ 380d4afb5ceSopenharmony_ci struct lws_wsi_eventlibs_libev *w; 381d4afb5ceSopenharmony_ci int fd; 382d4afb5ceSopenharmony_ci 383d4afb5ceSopenharmony_ci if (!wsi) { 384d4afb5ceSopenharmony_ci assert(0); 385d4afb5ceSopenharmony_ci return 0; 386d4afb5ceSopenharmony_ci } 387d4afb5ceSopenharmony_ci 388d4afb5ceSopenharmony_ci w = wsi_to_priv_ev(wsi); 389d4afb5ceSopenharmony_ci w->w_read.context = wsi->a.context; 390d4afb5ceSopenharmony_ci w->w_write.context = wsi->a.context; 391d4afb5ceSopenharmony_ci 392d4afb5ceSopenharmony_ci if (wsi->role_ops->file_handle) 393d4afb5ceSopenharmony_ci fd = wsi->desc.filefd; 394d4afb5ceSopenharmony_ci else 395d4afb5ceSopenharmony_ci fd = wsi->desc.sockfd; 396d4afb5ceSopenharmony_ci 397d4afb5ceSopenharmony_ci ev_io_init(&w->w_read.watcher, lws_accept_cb, fd, EV_READ); 398d4afb5ceSopenharmony_ci //ev_io_init(&w->w_write.watcher, lws_accept_cb, fd, EV_WRITE); 399d4afb5ceSopenharmony_ci 400d4afb5ceSopenharmony_ci elops_io_ev(wsi, LWS_EV_START | LWS_EV_READ); 401d4afb5ceSopenharmony_ci 402d4afb5ceSopenharmony_ci return 0; 403d4afb5ceSopenharmony_ci} 404d4afb5ceSopenharmony_ci 405d4afb5ceSopenharmony_cistatic void 406d4afb5ceSopenharmony_cielops_destroy_wsi_ev(struct lws *wsi) 407d4afb5ceSopenharmony_ci{ 408d4afb5ceSopenharmony_ci struct lws_context_per_thread *pt = &wsi->a.context->pt[(int)wsi->tsi]; 409d4afb5ceSopenharmony_ci struct lws_pt_eventlibs_libev *ptpr = pt_to_priv_ev(pt); 410d4afb5ceSopenharmony_ci struct lws_wsi_eventlibs_libev *w = wsi_to_priv_ev(wsi); 411d4afb5ceSopenharmony_ci 412d4afb5ceSopenharmony_ci ev_io_stop(ptpr->io_loop, &w->w_read.watcher); 413d4afb5ceSopenharmony_ci ev_io_stop(ptpr->io_loop, &w->w_write.watcher); 414d4afb5ceSopenharmony_ci} 415d4afb5ceSopenharmony_ci 416d4afb5ceSopenharmony_cistatic const struct lws_event_loop_ops event_loop_ops_ev = { 417d4afb5ceSopenharmony_ci /* name */ "libev", 418d4afb5ceSopenharmony_ci /* init_context */ elops_init_context_ev, 419d4afb5ceSopenharmony_ci /* destroy_context1 */ NULL, 420d4afb5ceSopenharmony_ci /* destroy_context2 */ elops_destroy_context2_ev, 421d4afb5ceSopenharmony_ci /* init_vhost_listen_wsi */ elops_init_vhost_listen_wsi_ev, 422d4afb5ceSopenharmony_ci /* init_pt */ elops_init_pt_ev, 423d4afb5ceSopenharmony_ci /* wsi_logical_close */ NULL, 424d4afb5ceSopenharmony_ci /* check_client_connect_ok */ NULL, 425d4afb5ceSopenharmony_ci /* close_handle_manually */ NULL, 426d4afb5ceSopenharmony_ci /* accept */ elops_accept_ev, 427d4afb5ceSopenharmony_ci /* io */ elops_io_ev, 428d4afb5ceSopenharmony_ci /* run_pt */ elops_run_pt_ev, 429d4afb5ceSopenharmony_ci /* destroy_pt */ elops_destroy_pt_ev, 430d4afb5ceSopenharmony_ci /* destroy wsi */ elops_destroy_wsi_ev, 431d4afb5ceSopenharmony_ci /* foreign_thread */ NULL, 432d4afb5ceSopenharmony_ci 433d4afb5ceSopenharmony_ci /* flags */ 0, 434d4afb5ceSopenharmony_ci 435d4afb5ceSopenharmony_ci /* evlib_size_ctx */ 0, 436d4afb5ceSopenharmony_ci /* evlib_size_pt */ sizeof(struct lws_pt_eventlibs_libev), 437d4afb5ceSopenharmony_ci /* evlib_size_vh */ sizeof(struct lws_vh_eventlibs_libev), 438d4afb5ceSopenharmony_ci /* evlib_size_wsi */ sizeof(struct lws_wsi_eventlibs_libev), 439d4afb5ceSopenharmony_ci}; 440d4afb5ceSopenharmony_ci 441d4afb5ceSopenharmony_ci#if defined(LWS_WITH_EVLIB_PLUGINS) 442d4afb5ceSopenharmony_ciLWS_VISIBLE 443d4afb5ceSopenharmony_ci#endif 444d4afb5ceSopenharmony_ciconst lws_plugin_evlib_t evlib_ev = { 445d4afb5ceSopenharmony_ci .hdr = { 446d4afb5ceSopenharmony_ci "libev event loop", 447d4afb5ceSopenharmony_ci "lws_evlib_plugin", 448d4afb5ceSopenharmony_ci LWS_BUILD_HASH, 449d4afb5ceSopenharmony_ci LWS_PLUGIN_API_MAGIC 450d4afb5ceSopenharmony_ci }, 451d4afb5ceSopenharmony_ci 452d4afb5ceSopenharmony_ci .ops = &event_loop_ops_ev 453d4afb5ceSopenharmony_ci}; 454