1d4afb5ceSopenharmony_ci/* 2d4afb5ceSopenharmony_ci * libwebsockets - small server side websockets and web server implementation 3d4afb5ceSopenharmony_ci * 4d4afb5ceSopenharmony_ci * Copyright (C) 2010 - 2019 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-libevent.h" 27d4afb5ceSopenharmony_ci 28d4afb5ceSopenharmony_ci#define pt_to_priv_event(_pt) ((struct lws_pt_eventlibs_libevent *)(_pt)->evlib_pt) 29d4afb5ceSopenharmony_ci#define wsi_to_priv_event(_w) ((struct lws_wsi_eventlibs_libevent *)(_w)->evlib_wsi) 30d4afb5ceSopenharmony_ci 31d4afb5ceSopenharmony_cistatic void 32d4afb5ceSopenharmony_cilws_event_hrtimer_cb(evutil_socket_t fd, short event, void *p) 33d4afb5ceSopenharmony_ci{ 34d4afb5ceSopenharmony_ci struct lws_context_per_thread *pt = (struct lws_context_per_thread *)p; 35d4afb5ceSopenharmony_ci struct lws_pt_eventlibs_libevent *ptpr = pt_to_priv_event(pt); 36d4afb5ceSopenharmony_ci struct timeval tv; 37d4afb5ceSopenharmony_ci lws_usec_t us; 38d4afb5ceSopenharmony_ci 39d4afb5ceSopenharmony_ci lws_pt_lock(pt, __func__); 40d4afb5ceSopenharmony_ci us = __lws_sul_service_ripe(pt->pt_sul_owner, LWS_COUNT_PT_SUL_OWNERS, 41d4afb5ceSopenharmony_ci lws_now_usecs()); 42d4afb5ceSopenharmony_ci if (us) { 43d4afb5ceSopenharmony_ci#if defined(__APPLE__) 44d4afb5ceSopenharmony_ci tv.tv_sec = (int)(us / LWS_US_PER_SEC); 45d4afb5ceSopenharmony_ci tv.tv_usec = (int)(us - (tv.tv_sec * LWS_US_PER_SEC)); 46d4afb5ceSopenharmony_ci#else 47d4afb5ceSopenharmony_ci tv.tv_sec = (long)(us / LWS_US_PER_SEC); 48d4afb5ceSopenharmony_ci tv.tv_usec = (long)(us - (tv.tv_sec * LWS_US_PER_SEC)); 49d4afb5ceSopenharmony_ci#endif 50d4afb5ceSopenharmony_ci evtimer_add(ptpr->hrtimer, &tv); 51d4afb5ceSopenharmony_ci } 52d4afb5ceSopenharmony_ci lws_pt_unlock(pt); 53d4afb5ceSopenharmony_ci} 54d4afb5ceSopenharmony_ci 55d4afb5ceSopenharmony_cistatic void 56d4afb5ceSopenharmony_cilws_event_idle_timer_cb(evutil_socket_t fd, short event, void *p) 57d4afb5ceSopenharmony_ci{ 58d4afb5ceSopenharmony_ci struct lws_context_per_thread *pt = (struct lws_context_per_thread *)p; 59d4afb5ceSopenharmony_ci struct lws_pt_eventlibs_libevent *ptpr = pt_to_priv_event(pt); 60d4afb5ceSopenharmony_ci struct timeval tv; 61d4afb5ceSopenharmony_ci lws_usec_t us; 62d4afb5ceSopenharmony_ci 63d4afb5ceSopenharmony_ci if (pt->is_destroyed) 64d4afb5ceSopenharmony_ci return; 65d4afb5ceSopenharmony_ci 66d4afb5ceSopenharmony_ci lws_service_do_ripe_rxflow(pt); 67d4afb5ceSopenharmony_ci 68d4afb5ceSopenharmony_ci /* 69d4afb5ceSopenharmony_ci * is there anybody with pending stuff that needs service forcing? 70d4afb5ceSopenharmony_ci */ 71d4afb5ceSopenharmony_ci if (!lws_service_adjust_timeout(pt->context, 1, pt->tid)) { 72d4afb5ceSopenharmony_ci /* -1 timeout means just do forced service */ 73d4afb5ceSopenharmony_ci _lws_plat_service_forced_tsi(pt->context, pt->tid); 74d4afb5ceSopenharmony_ci /* still somebody left who wants forced service? */ 75d4afb5ceSopenharmony_ci if (!lws_service_adjust_timeout(pt->context, 1, pt->tid)) { 76d4afb5ceSopenharmony_ci /* yes... come back again later */ 77d4afb5ceSopenharmony_ci 78d4afb5ceSopenharmony_ci tv.tv_sec = 0; 79d4afb5ceSopenharmony_ci tv.tv_usec = 1000; 80d4afb5ceSopenharmony_ci evtimer_add(ptpr->idle_timer, &tv); 81d4afb5ceSopenharmony_ci 82d4afb5ceSopenharmony_ci return; 83d4afb5ceSopenharmony_ci } 84d4afb5ceSopenharmony_ci } 85d4afb5ceSopenharmony_ci 86d4afb5ceSopenharmony_ci /* account for hrtimer */ 87d4afb5ceSopenharmony_ci 88d4afb5ceSopenharmony_ci lws_pt_lock(pt, __func__); 89d4afb5ceSopenharmony_ci us = __lws_sul_service_ripe(pt->pt_sul_owner, LWS_COUNT_PT_SUL_OWNERS, 90d4afb5ceSopenharmony_ci lws_now_usecs()); 91d4afb5ceSopenharmony_ci if (us) { 92d4afb5ceSopenharmony_ci tv.tv_sec = (suseconds_t)(us / LWS_US_PER_SEC); 93d4afb5ceSopenharmony_ci tv.tv_usec = (suseconds_t)(us - (tv.tv_sec * LWS_US_PER_SEC)); 94d4afb5ceSopenharmony_ci evtimer_add(ptpr->hrtimer, &tv); 95d4afb5ceSopenharmony_ci } 96d4afb5ceSopenharmony_ci lws_pt_unlock(pt); 97d4afb5ceSopenharmony_ci 98d4afb5ceSopenharmony_ci if (pt->destroy_self) 99d4afb5ceSopenharmony_ci lws_context_destroy(pt->context); 100d4afb5ceSopenharmony_ci} 101d4afb5ceSopenharmony_ci 102d4afb5ceSopenharmony_cistatic void 103d4afb5ceSopenharmony_cilws_event_cb(evutil_socket_t sock_fd, short revents, void *ctx) 104d4afb5ceSopenharmony_ci{ 105d4afb5ceSopenharmony_ci struct lws_signal_watcher_libevent *lws_io = 106d4afb5ceSopenharmony_ci (struct lws_signal_watcher_libevent *)ctx; 107d4afb5ceSopenharmony_ci struct lws_context *context = lws_io->context; 108d4afb5ceSopenharmony_ci struct lws_context_per_thread *pt; 109d4afb5ceSopenharmony_ci struct lws_pollfd eventfd; 110d4afb5ceSopenharmony_ci struct timeval tv; 111d4afb5ceSopenharmony_ci struct lws *wsi; 112d4afb5ceSopenharmony_ci 113d4afb5ceSopenharmony_ci if (revents & EV_TIMEOUT) 114d4afb5ceSopenharmony_ci return; 115d4afb5ceSopenharmony_ci 116d4afb5ceSopenharmony_ci /* !!! EV_CLOSED doesn't exist in libevent2 */ 117d4afb5ceSopenharmony_ci#if LIBEVENT_VERSION_NUMBER < 0x02000000 118d4afb5ceSopenharmony_ci if (revents & EV_CLOSED) { 119d4afb5ceSopenharmony_ci event_del(lws_io->event.watcher); 120d4afb5ceSopenharmony_ci event_free(lws_io->event.watcher); 121d4afb5ceSopenharmony_ci return; 122d4afb5ceSopenharmony_ci } 123d4afb5ceSopenharmony_ci#endif 124d4afb5ceSopenharmony_ci 125d4afb5ceSopenharmony_ci eventfd.fd = sock_fd; 126d4afb5ceSopenharmony_ci eventfd.events = 0; 127d4afb5ceSopenharmony_ci eventfd.revents = 0; 128d4afb5ceSopenharmony_ci if (revents & EV_READ) { 129d4afb5ceSopenharmony_ci eventfd.events |= LWS_POLLIN; 130d4afb5ceSopenharmony_ci eventfd.revents |= LWS_POLLIN; 131d4afb5ceSopenharmony_ci } 132d4afb5ceSopenharmony_ci if (revents & EV_WRITE) { 133d4afb5ceSopenharmony_ci eventfd.events |= LWS_POLLOUT; 134d4afb5ceSopenharmony_ci eventfd.revents |= LWS_POLLOUT; 135d4afb5ceSopenharmony_ci } 136d4afb5ceSopenharmony_ci 137d4afb5ceSopenharmony_ci wsi = wsi_from_fd(context, sock_fd); 138d4afb5ceSopenharmony_ci if (!wsi) 139d4afb5ceSopenharmony_ci return; 140d4afb5ceSopenharmony_ci 141d4afb5ceSopenharmony_ci pt = &context->pt[(int)wsi->tsi]; 142d4afb5ceSopenharmony_ci if (pt->is_destroyed) 143d4afb5ceSopenharmony_ci return; 144d4afb5ceSopenharmony_ci 145d4afb5ceSopenharmony_ci lws_service_fd_tsi(context, &eventfd, wsi->tsi); 146d4afb5ceSopenharmony_ci 147d4afb5ceSopenharmony_ci if (pt->destroy_self) { 148d4afb5ceSopenharmony_ci lwsl_cx_notice(context, "pt destroy self coming true"); 149d4afb5ceSopenharmony_ci lws_context_destroy(pt->context); 150d4afb5ceSopenharmony_ci return; 151d4afb5ceSopenharmony_ci } 152d4afb5ceSopenharmony_ci 153d4afb5ceSopenharmony_ci /* set the idle timer for 1ms ahead */ 154d4afb5ceSopenharmony_ci 155d4afb5ceSopenharmony_ci tv.tv_sec = 0; 156d4afb5ceSopenharmony_ci tv.tv_usec = 1000; 157d4afb5ceSopenharmony_ci evtimer_add(pt_to_priv_event(pt)->idle_timer, &tv); 158d4afb5ceSopenharmony_ci} 159d4afb5ceSopenharmony_ci 160d4afb5ceSopenharmony_civoid 161d4afb5ceSopenharmony_cilws_event_sigint_cb(evutil_socket_t sock_fd, short revents, void *ctx) 162d4afb5ceSopenharmony_ci{ 163d4afb5ceSopenharmony_ci struct lws_context_per_thread *pt = ctx; 164d4afb5ceSopenharmony_ci struct event *signal = pt_to_priv_event(pt)->w_sigint.watcher; 165d4afb5ceSopenharmony_ci 166d4afb5ceSopenharmony_ci if (pt->context->eventlib_signal_cb) { 167d4afb5ceSopenharmony_ci pt->context->eventlib_signal_cb((void *)(lws_intptr_t)sock_fd, 168d4afb5ceSopenharmony_ci event_get_signal(signal)); 169d4afb5ceSopenharmony_ci 170d4afb5ceSopenharmony_ci return; 171d4afb5ceSopenharmony_ci } 172d4afb5ceSopenharmony_ci if (!pt->event_loop_foreign) 173d4afb5ceSopenharmony_ci event_base_loopbreak(pt_to_priv_event(pt)->io_loop); 174d4afb5ceSopenharmony_ci} 175d4afb5ceSopenharmony_ci 176d4afb5ceSopenharmony_cistatic int 177d4afb5ceSopenharmony_cielops_listen_init_event(struct lws_dll2 *d, void *user) 178d4afb5ceSopenharmony_ci{ 179d4afb5ceSopenharmony_ci struct lws *wsi = lws_container_of(d, struct lws, listen_list); 180d4afb5ceSopenharmony_ci struct lws_context *context = (struct lws_context *)user; 181d4afb5ceSopenharmony_ci struct lws_context_per_thread *pt = &context->pt[(int)wsi->tsi]; 182d4afb5ceSopenharmony_ci struct lws_pt_eventlibs_libevent *ptpr = pt_to_priv_event(pt); 183d4afb5ceSopenharmony_ci struct lws_io_watcher_libevent *w_read = 184d4afb5ceSopenharmony_ci &(wsi_to_priv_event(wsi)->w_read); 185d4afb5ceSopenharmony_ci 186d4afb5ceSopenharmony_ci w_read->context = context; 187d4afb5ceSopenharmony_ci w_read->watcher = event_new(ptpr->io_loop, wsi->desc.sockfd, 188d4afb5ceSopenharmony_ci (EV_READ | EV_PERSIST), lws_event_cb, w_read); 189d4afb5ceSopenharmony_ci event_add(w_read->watcher, NULL); 190d4afb5ceSopenharmony_ci w_read->set = 1; 191d4afb5ceSopenharmony_ci 192d4afb5ceSopenharmony_ci return 0; 193d4afb5ceSopenharmony_ci} 194d4afb5ceSopenharmony_ci 195d4afb5ceSopenharmony_cistatic int 196d4afb5ceSopenharmony_cielops_init_pt_event(struct lws_context *context, void *_loop, int tsi) 197d4afb5ceSopenharmony_ci{ 198d4afb5ceSopenharmony_ci struct event_base *loop = (struct event_base *)_loop; 199d4afb5ceSopenharmony_ci struct lws_context_per_thread *pt = &context->pt[tsi]; 200d4afb5ceSopenharmony_ci struct lws_pt_eventlibs_libevent *ptpr = pt_to_priv_event(pt); 201d4afb5ceSopenharmony_ci 202d4afb5ceSopenharmony_ci lwsl_cx_info(context, "loop %p", _loop); 203d4afb5ceSopenharmony_ci 204d4afb5ceSopenharmony_ci if (!loop) 205d4afb5ceSopenharmony_ci loop = event_base_new(); 206d4afb5ceSopenharmony_ci else 207d4afb5ceSopenharmony_ci context->pt[tsi].event_loop_foreign = 1; 208d4afb5ceSopenharmony_ci 209d4afb5ceSopenharmony_ci if (!loop) { 210d4afb5ceSopenharmony_ci lwsl_cx_err(context, "creating event base failed"); 211d4afb5ceSopenharmony_ci 212d4afb5ceSopenharmony_ci return -1; 213d4afb5ceSopenharmony_ci } 214d4afb5ceSopenharmony_ci 215d4afb5ceSopenharmony_ci ptpr->io_loop = loop; 216d4afb5ceSopenharmony_ci 217d4afb5ceSopenharmony_ci lws_vhost_foreach_listen_wsi(context, context, elops_listen_init_event); 218d4afb5ceSopenharmony_ci 219d4afb5ceSopenharmony_ci /* static event loop objects */ 220d4afb5ceSopenharmony_ci 221d4afb5ceSopenharmony_ci ptpr->hrtimer = event_new(loop, -1, EV_PERSIST, 222d4afb5ceSopenharmony_ci lws_event_hrtimer_cb, pt); 223d4afb5ceSopenharmony_ci 224d4afb5ceSopenharmony_ci ptpr->idle_timer = event_new(loop, -1, 0, 225d4afb5ceSopenharmony_ci lws_event_idle_timer_cb, pt); 226d4afb5ceSopenharmony_ci { 227d4afb5ceSopenharmony_ci struct timeval tv; 228d4afb5ceSopenharmony_ci tv.tv_sec = (long)0; 229d4afb5ceSopenharmony_ci tv.tv_usec = (long)1000; 230d4afb5ceSopenharmony_ci evtimer_add(ptpr->hrtimer, &tv); 231d4afb5ceSopenharmony_ci } 232d4afb5ceSopenharmony_ci 233d4afb5ceSopenharmony_ci /* Register the signal watcher unless it's a foreign loop */ 234d4afb5ceSopenharmony_ci 235d4afb5ceSopenharmony_ci if (pt->event_loop_foreign) 236d4afb5ceSopenharmony_ci return 0; 237d4afb5ceSopenharmony_ci 238d4afb5ceSopenharmony_ci ptpr->w_sigint.watcher = evsignal_new(loop, SIGINT, 239d4afb5ceSopenharmony_ci lws_event_sigint_cb, pt); 240d4afb5ceSopenharmony_ci event_add(ptpr->w_sigint.watcher, NULL); 241d4afb5ceSopenharmony_ci 242d4afb5ceSopenharmony_ci return 0; 243d4afb5ceSopenharmony_ci} 244d4afb5ceSopenharmony_ci 245d4afb5ceSopenharmony_cistatic int 246d4afb5ceSopenharmony_cielops_init_context_event(struct lws_context *context, 247d4afb5ceSopenharmony_ci const struct lws_context_creation_info *info) 248d4afb5ceSopenharmony_ci{ 249d4afb5ceSopenharmony_ci int n; 250d4afb5ceSopenharmony_ci 251d4afb5ceSopenharmony_ci context->eventlib_signal_cb = info->signal_cb; 252d4afb5ceSopenharmony_ci 253d4afb5ceSopenharmony_ci for (n = 0; n < context->count_threads; n++) 254d4afb5ceSopenharmony_ci pt_to_priv_event(&context->pt[n])->w_sigint.context = context; 255d4afb5ceSopenharmony_ci 256d4afb5ceSopenharmony_ci return 0; 257d4afb5ceSopenharmony_ci} 258d4afb5ceSopenharmony_ci 259d4afb5ceSopenharmony_cistatic int 260d4afb5ceSopenharmony_cielops_accept_event(struct lws *wsi) 261d4afb5ceSopenharmony_ci{ 262d4afb5ceSopenharmony_ci struct lws_context *context = lws_get_context(wsi); 263d4afb5ceSopenharmony_ci struct lws_context_per_thread *pt; 264d4afb5ceSopenharmony_ci struct lws_pt_eventlibs_libevent *ptpr; 265d4afb5ceSopenharmony_ci struct lws_wsi_eventlibs_libevent *wpr = wsi_to_priv_event(wsi); 266d4afb5ceSopenharmony_ci evutil_socket_t fd; 267d4afb5ceSopenharmony_ci 268d4afb5ceSopenharmony_ci wpr->w_read.context = context; 269d4afb5ceSopenharmony_ci wpr->w_write.context = context; 270d4afb5ceSopenharmony_ci 271d4afb5ceSopenharmony_ci // Initialize the event 272d4afb5ceSopenharmony_ci pt = &context->pt[(int)wsi->tsi]; 273d4afb5ceSopenharmony_ci ptpr = pt_to_priv_event(pt); 274d4afb5ceSopenharmony_ci 275d4afb5ceSopenharmony_ci if (wsi->role_ops->file_handle) 276d4afb5ceSopenharmony_ci fd = (evutil_socket_t)(ev_intptr_t) wsi->desc.filefd; 277d4afb5ceSopenharmony_ci else 278d4afb5ceSopenharmony_ci fd = wsi->desc.sockfd; 279d4afb5ceSopenharmony_ci 280d4afb5ceSopenharmony_ci wpr->w_read.watcher = event_new(ptpr->io_loop, fd, 281d4afb5ceSopenharmony_ci (EV_READ | EV_PERSIST), lws_event_cb, &wpr->w_read); 282d4afb5ceSopenharmony_ci wpr->w_write.watcher = event_new(ptpr->io_loop, fd, 283d4afb5ceSopenharmony_ci (EV_WRITE | EV_PERSIST), lws_event_cb, &wpr->w_write); 284d4afb5ceSopenharmony_ci 285d4afb5ceSopenharmony_ci return 0; 286d4afb5ceSopenharmony_ci} 287d4afb5ceSopenharmony_ci 288d4afb5ceSopenharmony_cistatic void 289d4afb5ceSopenharmony_cielops_io_event(struct lws *wsi, unsigned int flags) 290d4afb5ceSopenharmony_ci{ 291d4afb5ceSopenharmony_ci struct lws_context_per_thread *pt = &wsi->a.context->pt[(int)wsi->tsi]; 292d4afb5ceSopenharmony_ci struct lws_pt_eventlibs_libevent *ptpr = pt_to_priv_event(pt); 293d4afb5ceSopenharmony_ci struct lws_wsi_eventlibs_libevent *wpr = wsi_to_priv_event(wsi); 294d4afb5ceSopenharmony_ci 295d4afb5ceSopenharmony_ci if (!ptpr->io_loop || wsi->a.context->being_destroyed || 296d4afb5ceSopenharmony_ci pt->is_destroyed) 297d4afb5ceSopenharmony_ci return; 298d4afb5ceSopenharmony_ci 299d4afb5ceSopenharmony_ci assert((flags & (LWS_EV_START | LWS_EV_STOP)) && 300d4afb5ceSopenharmony_ci (flags & (LWS_EV_READ | LWS_EV_WRITE))); 301d4afb5ceSopenharmony_ci 302d4afb5ceSopenharmony_ci if (flags & LWS_EV_START) { 303d4afb5ceSopenharmony_ci if ((flags & LWS_EV_WRITE) && !wpr->w_write.set) { 304d4afb5ceSopenharmony_ci event_add(wpr->w_write.watcher, NULL); 305d4afb5ceSopenharmony_ci wpr->w_write.set = 1; 306d4afb5ceSopenharmony_ci } 307d4afb5ceSopenharmony_ci 308d4afb5ceSopenharmony_ci if ((flags & LWS_EV_READ) && !wpr->w_read.set) { 309d4afb5ceSopenharmony_ci event_add(wpr->w_read.watcher, NULL); 310d4afb5ceSopenharmony_ci wpr->w_read.set = 1; 311d4afb5ceSopenharmony_ci } 312d4afb5ceSopenharmony_ci } else { 313d4afb5ceSopenharmony_ci if ((flags & LWS_EV_WRITE) && wpr->w_write.set) { 314d4afb5ceSopenharmony_ci event_del(wpr->w_write.watcher); 315d4afb5ceSopenharmony_ci wpr->w_write.set = 0; 316d4afb5ceSopenharmony_ci } 317d4afb5ceSopenharmony_ci 318d4afb5ceSopenharmony_ci if ((flags & LWS_EV_READ) && wpr->w_read.set) { 319d4afb5ceSopenharmony_ci event_del(wpr->w_read.watcher); 320d4afb5ceSopenharmony_ci wpr->w_read.set = 0; 321d4afb5ceSopenharmony_ci } 322d4afb5ceSopenharmony_ci } 323d4afb5ceSopenharmony_ci} 324d4afb5ceSopenharmony_ci 325d4afb5ceSopenharmony_cistatic void 326d4afb5ceSopenharmony_cielops_run_pt_event(struct lws_context *context, int tsi) 327d4afb5ceSopenharmony_ci{ 328d4afb5ceSopenharmony_ci /* Run / Dispatch the event_base loop */ 329d4afb5ceSopenharmony_ci if (pt_to_priv_event(&context->pt[tsi])->io_loop) 330d4afb5ceSopenharmony_ci event_base_dispatch( 331d4afb5ceSopenharmony_ci pt_to_priv_event(&context->pt[tsi])->io_loop); 332d4afb5ceSopenharmony_ci} 333d4afb5ceSopenharmony_ci 334d4afb5ceSopenharmony_cistatic int 335d4afb5ceSopenharmony_cielops_listen_destroy_event(struct lws_dll2 *d, void *user) 336d4afb5ceSopenharmony_ci{ 337d4afb5ceSopenharmony_ci struct lws *wsi = lws_container_of(d, struct lws, listen_list); 338d4afb5ceSopenharmony_ci struct lws_wsi_eventlibs_libevent *w = wsi_to_priv_event(wsi); 339d4afb5ceSopenharmony_ci 340d4afb5ceSopenharmony_ci event_free(w->w_read.watcher); 341d4afb5ceSopenharmony_ci w->w_read.watcher = NULL; 342d4afb5ceSopenharmony_ci event_free(w->w_write.watcher); 343d4afb5ceSopenharmony_ci w->w_write.watcher = NULL; 344d4afb5ceSopenharmony_ci 345d4afb5ceSopenharmony_ci return 0; 346d4afb5ceSopenharmony_ci} 347d4afb5ceSopenharmony_ci 348d4afb5ceSopenharmony_cistatic void 349d4afb5ceSopenharmony_cielops_destroy_pt_event(struct lws_context *context, int tsi) 350d4afb5ceSopenharmony_ci{ 351d4afb5ceSopenharmony_ci struct lws_context_per_thread *pt = &context->pt[tsi]; 352d4afb5ceSopenharmony_ci struct lws_pt_eventlibs_libevent *ptpr = pt_to_priv_event(pt); 353d4afb5ceSopenharmony_ci 354d4afb5ceSopenharmony_ci if (!ptpr->io_loop) 355d4afb5ceSopenharmony_ci return; 356d4afb5ceSopenharmony_ci 357d4afb5ceSopenharmony_ci lws_vhost_foreach_listen_wsi(context, context, elops_listen_destroy_event); 358d4afb5ceSopenharmony_ci 359d4afb5ceSopenharmony_ci event_free(ptpr->hrtimer); 360d4afb5ceSopenharmony_ci event_free(ptpr->idle_timer); 361d4afb5ceSopenharmony_ci 362d4afb5ceSopenharmony_ci if (!pt->event_loop_foreign) { 363d4afb5ceSopenharmony_ci event_del(ptpr->w_sigint.watcher); 364d4afb5ceSopenharmony_ci event_free(ptpr->w_sigint.watcher); 365d4afb5ceSopenharmony_ci event_base_loopexit(ptpr->io_loop, NULL); 366d4afb5ceSopenharmony_ci // event_base_free(pt->event.io_loop); 367d4afb5ceSopenharmony_ci // pt->event.io_loop = NULL; 368d4afb5ceSopenharmony_ci lwsl_cx_notice(context, "set to exit loop"); 369d4afb5ceSopenharmony_ci } 370d4afb5ceSopenharmony_ci} 371d4afb5ceSopenharmony_ci 372d4afb5ceSopenharmony_cistatic void 373d4afb5ceSopenharmony_cielops_destroy_wsi_event(struct lws *wsi) 374d4afb5ceSopenharmony_ci{ 375d4afb5ceSopenharmony_ci struct lws_context_per_thread *pt; 376d4afb5ceSopenharmony_ci struct lws_wsi_eventlibs_libevent *w; 377d4afb5ceSopenharmony_ci 378d4afb5ceSopenharmony_ci if (!wsi) 379d4afb5ceSopenharmony_ci return; 380d4afb5ceSopenharmony_ci 381d4afb5ceSopenharmony_ci pt = &wsi->a.context->pt[(int)wsi->tsi]; 382d4afb5ceSopenharmony_ci if (pt->is_destroyed) 383d4afb5ceSopenharmony_ci return; 384d4afb5ceSopenharmony_ci 385d4afb5ceSopenharmony_ci w = wsi_to_priv_event(wsi); 386d4afb5ceSopenharmony_ci 387d4afb5ceSopenharmony_ci if (w->w_read.watcher) { 388d4afb5ceSopenharmony_ci event_free(w->w_read.watcher); 389d4afb5ceSopenharmony_ci w->w_read.watcher = NULL; 390d4afb5ceSopenharmony_ci } 391d4afb5ceSopenharmony_ci 392d4afb5ceSopenharmony_ci if (w->w_write.watcher) { 393d4afb5ceSopenharmony_ci event_free(w->w_write.watcher); 394d4afb5ceSopenharmony_ci w->w_write.watcher = NULL; 395d4afb5ceSopenharmony_ci } 396d4afb5ceSopenharmony_ci} 397d4afb5ceSopenharmony_ci 398d4afb5ceSopenharmony_cistatic int 399d4afb5ceSopenharmony_cielops_wsi_logical_close_event(struct lws *wsi) 400d4afb5ceSopenharmony_ci{ 401d4afb5ceSopenharmony_ci elops_destroy_wsi_event(wsi); 402d4afb5ceSopenharmony_ci 403d4afb5ceSopenharmony_ci return 0; 404d4afb5ceSopenharmony_ci} 405d4afb5ceSopenharmony_ci 406d4afb5ceSopenharmony_cistatic int 407d4afb5ceSopenharmony_cielops_init_vhost_listen_wsi_event(struct lws *wsi) 408d4afb5ceSopenharmony_ci{ 409d4afb5ceSopenharmony_ci struct lws_context_per_thread *pt; 410d4afb5ceSopenharmony_ci struct lws_pt_eventlibs_libevent *ptpr; 411d4afb5ceSopenharmony_ci struct lws_wsi_eventlibs_libevent *w; 412d4afb5ceSopenharmony_ci evutil_socket_t fd; 413d4afb5ceSopenharmony_ci 414d4afb5ceSopenharmony_ci if (!wsi) { 415d4afb5ceSopenharmony_ci assert(0); 416d4afb5ceSopenharmony_ci return 0; 417d4afb5ceSopenharmony_ci } 418d4afb5ceSopenharmony_ci 419d4afb5ceSopenharmony_ci w = wsi_to_priv_event(wsi); 420d4afb5ceSopenharmony_ci 421d4afb5ceSopenharmony_ci w->w_read.context = wsi->a.context; 422d4afb5ceSopenharmony_ci w->w_write.context = wsi->a.context; 423d4afb5ceSopenharmony_ci 424d4afb5ceSopenharmony_ci pt = &wsi->a.context->pt[(int)wsi->tsi]; 425d4afb5ceSopenharmony_ci ptpr = pt_to_priv_event(pt); 426d4afb5ceSopenharmony_ci 427d4afb5ceSopenharmony_ci if (wsi->role_ops->file_handle) 428d4afb5ceSopenharmony_ci fd = (evutil_socket_t) wsi->desc.filefd; 429d4afb5ceSopenharmony_ci else 430d4afb5ceSopenharmony_ci fd = wsi->desc.sockfd; 431d4afb5ceSopenharmony_ci 432d4afb5ceSopenharmony_ci w->w_read.watcher = event_new(ptpr->io_loop, fd, (EV_READ | EV_PERSIST), 433d4afb5ceSopenharmony_ci lws_event_cb, &w->w_read); 434d4afb5ceSopenharmony_ci w->w_write.watcher = event_new(ptpr->io_loop, fd, 435d4afb5ceSopenharmony_ci (EV_WRITE | EV_PERSIST), 436d4afb5ceSopenharmony_ci lws_event_cb, &w->w_write); 437d4afb5ceSopenharmony_ci 438d4afb5ceSopenharmony_ci elops_io_event(wsi, LWS_EV_START | LWS_EV_READ); 439d4afb5ceSopenharmony_ci 440d4afb5ceSopenharmony_ci return 0; 441d4afb5ceSopenharmony_ci} 442d4afb5ceSopenharmony_ci 443d4afb5ceSopenharmony_cistatic int 444d4afb5ceSopenharmony_cielops_destroy_context2_event(struct lws_context *context) 445d4afb5ceSopenharmony_ci{ 446d4afb5ceSopenharmony_ci struct lws_context_per_thread *pt; 447d4afb5ceSopenharmony_ci struct lws_pt_eventlibs_libevent *ptpr; 448d4afb5ceSopenharmony_ci int n, m; 449d4afb5ceSopenharmony_ci 450d4afb5ceSopenharmony_ci for (n = 0; n < context->count_threads; n++) { 451d4afb5ceSopenharmony_ci int budget = 1000; 452d4afb5ceSopenharmony_ci 453d4afb5ceSopenharmony_ci pt = &context->pt[n]; 454d4afb5ceSopenharmony_ci ptpr = pt_to_priv_event(pt); 455d4afb5ceSopenharmony_ci 456d4afb5ceSopenharmony_ci /* only for internal loops... */ 457d4afb5ceSopenharmony_ci 458d4afb5ceSopenharmony_ci if (pt->event_loop_foreign || !ptpr->io_loop) 459d4afb5ceSopenharmony_ci continue; 460d4afb5ceSopenharmony_ci 461d4afb5ceSopenharmony_ci if (!context->evlib_finalize_destroy_after_int_loops_stop) { 462d4afb5ceSopenharmony_ci event_base_loopexit(ptpr->io_loop, NULL); 463d4afb5ceSopenharmony_ci continue; 464d4afb5ceSopenharmony_ci } 465d4afb5ceSopenharmony_ci while (budget-- && 466d4afb5ceSopenharmony_ci (m = event_base_loop(ptpr->io_loop, EVLOOP_NONBLOCK))) 467d4afb5ceSopenharmony_ci ; 468d4afb5ceSopenharmony_ci 469d4afb5ceSopenharmony_ci lwsl_cx_info(context, "event_base_free"); 470d4afb5ceSopenharmony_ci 471d4afb5ceSopenharmony_ci event_base_free(ptpr->io_loop); 472d4afb5ceSopenharmony_ci ptpr->io_loop = NULL; 473d4afb5ceSopenharmony_ci } 474d4afb5ceSopenharmony_ci 475d4afb5ceSopenharmony_ci return 0; 476d4afb5ceSopenharmony_ci} 477d4afb5ceSopenharmony_ci 478d4afb5ceSopenharmony_cistatic const struct lws_event_loop_ops event_loop_ops_event = { 479d4afb5ceSopenharmony_ci /* name */ "libevent", 480d4afb5ceSopenharmony_ci /* init_context */ elops_init_context_event, 481d4afb5ceSopenharmony_ci /* destroy_context1 */ NULL, 482d4afb5ceSopenharmony_ci /* destroy_context2 */ elops_destroy_context2_event, 483d4afb5ceSopenharmony_ci /* init_vhost_listen_wsi */ elops_init_vhost_listen_wsi_event, 484d4afb5ceSopenharmony_ci /* init_pt */ elops_init_pt_event, 485d4afb5ceSopenharmony_ci /* wsi_logical_close */ elops_wsi_logical_close_event, 486d4afb5ceSopenharmony_ci /* check_client_connect_ok */ NULL, 487d4afb5ceSopenharmony_ci /* close_handle_manually */ NULL, 488d4afb5ceSopenharmony_ci /* accept */ elops_accept_event, 489d4afb5ceSopenharmony_ci /* io */ elops_io_event, 490d4afb5ceSopenharmony_ci /* run_pt */ elops_run_pt_event, 491d4afb5ceSopenharmony_ci /* destroy_pt */ elops_destroy_pt_event, 492d4afb5ceSopenharmony_ci /* destroy wsi */ elops_destroy_wsi_event, 493d4afb5ceSopenharmony_ci /* foreign_thread */ NULL, 494d4afb5ceSopenharmony_ci 495d4afb5ceSopenharmony_ci /* flags */ 0, 496d4afb5ceSopenharmony_ci 497d4afb5ceSopenharmony_ci /* evlib_size_ctx */ 0, 498d4afb5ceSopenharmony_ci /* evlib_size_pt */ sizeof(struct lws_pt_eventlibs_libevent), 499d4afb5ceSopenharmony_ci /* evlib_size_vh */ 0, 500d4afb5ceSopenharmony_ci /* evlib_size_wsi */ sizeof(struct lws_wsi_eventlibs_libevent), 501d4afb5ceSopenharmony_ci}; 502d4afb5ceSopenharmony_ci 503d4afb5ceSopenharmony_ci#if defined(LWS_WITH_EVLIB_PLUGINS) 504d4afb5ceSopenharmony_ciLWS_VISIBLE 505d4afb5ceSopenharmony_ci#endif 506d4afb5ceSopenharmony_ciconst lws_plugin_evlib_t evlib_event = { 507d4afb5ceSopenharmony_ci .hdr = { 508d4afb5ceSopenharmony_ci "libevent event loop", 509d4afb5ceSopenharmony_ci "lws_evlib_plugin", 510d4afb5ceSopenharmony_ci LWS_BUILD_HASH, 511d4afb5ceSopenharmony_ci LWS_PLUGIN_API_MAGIC 512d4afb5ceSopenharmony_ci }, 513d4afb5ceSopenharmony_ci 514d4afb5ceSopenharmony_ci .ops = &event_loop_ops_event 515d4afb5ceSopenharmony_ci}; 516