void process_expired_events(struct npool *nsp) { for (;;) { gh_hnode_t *hnode; struct nevent *nse; hnode = gh_heap_min(&nsp->expirables); if (!hnode) break; nse = container_of(hnode, struct nevent, expire); if (!event_timedout(nse)) break; gh_heap_pop(&nsp->expirables); process_event(nsp, NULL, nse, EV_NONE); assert(nse->event_done); update_first_events(nse); nevent_unref(nsp, nse); } }
/* If nsp_new returned success, you must free the nsp when you are done with it * to conserve memory (and in some cases, sockets). After this call, nsp may no * longer be used. Any pending events are sent an NSE_STATUS_KILL callback and * all outstanding iods are deleted. */ void nsp_delete(nsock_pool ms_pool) { mspool *nsp = (mspool *)ms_pool; msevent *nse; msiod *nsi; int i; gh_lnode_t *current, *next; gh_list_t *event_lists[] = { &nsp->connect_events, &nsp->read_events, &nsp->write_events, #if HAVE_PCAP &nsp->pcap_read_events, #endif NULL }; assert(nsp); /* First I go through all the events sending NSE_STATUS_KILL */ for (i = 0; event_lists[i] != NULL; i++) { while (gh_list_count(event_lists[i]) > 0) { gh_lnode_t *lnode = gh_list_pop(event_lists[i]); assert(lnode); #if HAVE_PCAP if (event_lists[i] == &nsp->pcap_read_events) nse = lnode_msevent2(lnode); else #endif nse = lnode_msevent(lnode); assert(nse); nse->status = NSE_STATUS_KILL; nsock_trace_handler_callback(nsp, nse); nse->handler(nsp, nse, nse->userdata); if (nse->iod) { nse->iod->events_pending--; assert(nse->iod->events_pending >= 0); } msevent_delete(nsp, nse); } gh_list_free(event_lists[i]); } /* Kill timers too, they're not in event lists */ while (gh_heap_count(&nsp->expirables) > 0) { gh_hnode_t *hnode; hnode = gh_heap_pop(&nsp->expirables); nse = container_of(hnode, msevent, expire); if (nse->type == NSE_TYPE_TIMER) { nse->status = NSE_STATUS_KILL; nsock_trace_handler_callback(nsp, nse); nse->handler(nsp, nse, nse->userdata); msevent_delete(nsp, nse); gh_list_append(&nsp->free_events, &nse->nodeq_io); } } gh_heap_free(&nsp->expirables); /* foreach msiod */ for (current = gh_list_first_elem(&nsp->active_iods); current != NULL; current = next) { next = gh_lnode_next(current); nsi = container_of(current, msiod, nodeq); nsi_delete(nsi, NSOCK_PENDING_ERROR); gh_list_remove(&nsp->active_iods, current); gh_list_prepend(&nsp->free_iods, &nsi->nodeq); } /* Now we free all the memory in the free iod list */ while ((current = gh_list_pop(&nsp->free_iods))) { nsi = container_of(current, msiod, nodeq); free(nsi); } while ((current = gh_list_pop(&nsp->free_events))) { nse = lnode_msevent(current); free(nse); } gh_list_free(&nsp->active_iods); gh_list_free(&nsp->free_iods); gh_list_free(&nsp->free_events); nsock_engine_destroy(nsp); #if HAVE_OPENSSL if (nsp->sslctx != NULL) SSL_CTX_free(nsp->sslctx); #endif free(nsp); }