static subscriber_pool_t *get_spool(channel_spooler_t *spl, nchan_msg_id_t *id) { rbtree_seed_t *seed = &spl->spoolseed; ngx_rbtree_node_t *node; subscriber_pool_t *spool; if((node = rbtree_find_node(seed, id)) == NULL) { if((node = rbtree_create_node(seed, sizeof(*spool))) == NULL) { ERR("can't create rbtree node for spool"); return NULL; } // DBG("CREATED spool node %p for msgid %i:%i", node, id->time, id->tag); spool = (subscriber_pool_t *)rbtree_data_from_node(node); ngx_memzero(spool, sizeof(*spool)); spool->spooler = spl; spool->id = *id; spool->spooler = spl; spool->msg_status = MSG_INVALID; spool->msg = NULL; if(rbtree_insert_node(seed, node) != NGX_OK) { ERR("couldn't insert spool node"); rbtree_destroy_node(seed, node); return NULL; } } else { spool = (subscriber_pool_t *)rbtree_data_from_node(node); //DBG("found spool node %p with msgid %i:%i", node, id->time, id->tag); assert(spool->id.time == id->time); } return spool; }
ngx_int_t stop_spooler(channel_spooler_t *spl, uint8_t dequeue_subscribers) { ngx_rbtree_node_t *cur, *sentinel; spooler_event_ll_t *ecur, *ecur_next; subscriber_pool_t *spool; rbtree_seed_t *seed = &spl->spoolseed; ngx_rbtree_t *tree = &seed->tree; ngx_int_t n=0; sentinel = tree->sentinel; fetchmsg_data_t *dcur; #if NCHAN_RBTREE_DBG ngx_int_t active_before = seed->active_nodes, allocd_before = seed->active_nodes; #endif if(spl->running) { for(ecur = spl->spooler_dependent_events; ecur != NULL; ecur = ecur_next) { ecur_next = ecur->next; if(ecur->cancel) { ecur->cancel(ecur->ev.data); } ngx_event_del_timer(&ecur->ev); ngx_free(ecur); } for(cur = tree->root; cur != NULL && cur != sentinel; cur = tree->root) { spool = (subscriber_pool_t *)rbtree_data_from_node(cur); if(dequeue_subscribers) { destroy_spool(spool); } else { remove_spool(spool); rbtree_destroy_node(seed, cur); } n++; } for(dcur = spl->fetchmsg_cb_data_list; dcur != NULL; dcur = dcur->next) { dcur->spooler = NULL; } DBG("stopped %i spools in SPOOLER %p", n, *spl); } else { DBG("SPOOLER %p not running", *spl); } #if NCHAN_RBTREE_DBG assert(active_before - n == 0); assert(allocd_before - n == 0); assert(seed->active_nodes == 0); assert(seed->allocd_nodes == 0); #endif nchan_free_msg_id(&spl->prev_msg_id); spl->running = 0; return NGX_OK; }
unsigned rbtree_empty(rbtree_seed_t *seed, rbtree_walk_callback_pt callback, void *data) { ngx_rbtree_t *tree = &seed->tree; ngx_rbtree_node_t *cur, *sentinel = tree->sentinel; unsigned int n = 0; for(cur = tree->root; cur != NULL && cur != sentinel; cur = tree->root) { if(callback) { callback(seed, rbtree_data_from_node(cur), data); } rbtree_remove_node(seed, cur); rbtree_destroy_node(seed, cur); n++; } return n; }
ngx_int_t stop_spooler(channel_spooler_t *spl, uint8_t dequeue_subscribers) { ngx_rbtree_node_t *cur, *sentinel; subscriber_pool_t *spool; rbtree_seed_t *seed = &spl->spoolseed; ngx_rbtree_t *tree = &seed->tree; ngx_int_t n=0; sentinel = tree->sentinel; #if NCHAN_RBTREE_DBG ngx_int_t active_before = seed->active_nodes, allocd_before = seed->active_nodes; #endif if(spl->running) { for(cur = tree->root; cur != NULL && cur != sentinel; cur = tree->root) { spool = (subscriber_pool_t *)rbtree_data_from_node(cur); if(dequeue_subscribers) { destroy_spool(spool); } else { remove_spool(spool); rbtree_destroy_node(seed, cur); } n++; } DBG("stopped %i spools in SPOOLER %p", n, *spl); } else { DBG("SPOOLER %p not running", *spl); } #if NCHAN_RBTREE_DBG assert(active_before - n == 0); assert(allocd_before - n == 0); assert(seed->active_nodes == 0); assert(seed->allocd_nodes == 0); #endif spl->running = 0; return NGX_OK; }
static ngx_int_t destroy_spool(subscriber_pool_t *spool) { rbtree_seed_t *seed = &spool->spooler->spoolseed; spooled_subscriber_t *ssub; subscriber_t *sub; ngx_rbtree_node_t *node = rbtree_node_from_data(spool); remove_spool(spool); DBG("destroy spool node %p", node); for(ssub = spool->first; ssub!=NULL; ssub=ssub->next) { sub = ssub->sub; //DBG("dequeue sub %p in spool %p", sub, spool); sub->fn->dequeue(sub); } assert(spool->sub_count == 0); assert(spool->first == NULL); ngx_memset(spool, 0x42, sizeof(*spool)); //debug rbtree_destroy_node(seed, node); return NGX_OK; }
static subscriber_pool_t *get_spool(channel_spooler_t *spl, nchan_msg_id_t *id) { rbtree_seed_t *seed = &spl->spoolseed; ngx_rbtree_node_t *node; subscriber_pool_t *spool; if(id->time == NCHAN_NEWEST_MSGID_TIME) { spool = &spl->current_msg_spool; spool->msg_status = MSG_EXPECTED; return &spl->current_msg_spool; } if((node = rbtree_find_node(seed, id)) == NULL) { if((node = rbtree_create_node(seed, sizeof(*spool))) == NULL) { ERR("can't create rbtree node for spool"); return NULL; } // DBG("CREATED spool node %p for msgid %V", node, msgid_to_str(id)); spool = (subscriber_pool_t *)rbtree_data_from_node(node); init_spool(spl, spool, id); if(rbtree_insert_node(seed, node) != NGX_OK) { ERR("couldn't insert spool node"); rbtree_destroy_node(seed, node); return NULL; } } else { spool = (subscriber_pool_t *)rbtree_data_from_node(node); DBG("found spool node %p with msgid %V", node, msgid_to_str(id)); assert(spool->id.time == id->time); } return spool; }