static char *_get_stats(const char *source, const char *name) { stats_node_t *stats = NULL; stats_source_t *src = NULL; char *value = NULL; if (source == NULL) { avl_tree_rlock (_stats.global_tree); stats = _find_node(_stats.global_tree, name); if (stats) value = (char *)strdup(stats->value); avl_tree_unlock (_stats.global_tree); } else { avl_tree_rlock (_stats.source_tree); src = _find_source(_stats.source_tree, source); if (src) { avl_tree_rlock (src->stats_tree); avl_tree_unlock (_stats.source_tree); stats = _find_node(src->stats_tree, name); if (stats) value = (char *)strdup(stats->value); avl_tree_unlock (src->stats_tree); } else avl_tree_unlock (_stats.source_tree); } return value; }
static void process_global_event (stats_event_t *event) { stats_node_t *node; /* ICECAST_LOG_DEBUG("global event %s %s %d", event->name, event->value, event->action); */ if (event->action == STATS_EVENT_REMOVE) { /* we're deleting */ node = _find_node(_stats.global_tree, event->name); if (node != NULL) avl_delete(_stats.global_tree, (void *)node, _free_stats); return; } node = _find_node(_stats.global_tree, event->name); if (node) { modify_node_event (node, event); } else { /* add node */ node = (stats_node_t *)calloc(1, sizeof(stats_node_t)); node->name = (char *)strdup(event->name); node->value = (char *)strdup(event->value); avl_insert(_stats.global_tree, (void *)node); } }
/* Add the new node information to our libstate cache, making a copy if * information is new. Otherwise, swap the data and return to the user old * data, which is fine in this case since it is only deleted by slurmctld */ static void _cache_node_info(sw_gen_node_info_t *new_node_info) { sw_gen_node_info_t *old_node_info; uint16_t ifa_cnt; sw_gen_ifa_t **ifa_array; struct sw_gen_node_info *next; bool new_alloc; /* True if this is new node to be added to cache */ slurm_mutex_lock(&global_lock); old_node_info = _find_node(new_node_info->node_name); new_alloc = (old_node_info == NULL); if (new_alloc) { (void) switch_p_alloc_node_info((switch_node_info_t **) &old_node_info); old_node_info->node_name = xstrdup(new_node_info->node_name); } /* Swap contents */ ifa_cnt = old_node_info->ifa_cnt; ifa_array = old_node_info->ifa_array; next = old_node_info->next; old_node_info->ifa_cnt = new_node_info->ifa_cnt; old_node_info->ifa_array = new_node_info->ifa_array; old_node_info->next = new_node_info->next; new_node_info->ifa_cnt = ifa_cnt; new_node_info->ifa_array = ifa_array; new_node_info->next = next; if (new_alloc) _hash_add_nodeinfo(old_node_info); slurm_mutex_unlock(&global_lock); }
/* This removes any source stats from virtual mountpoints, ie mountpoints * where no source_t exists. This function requires the global sources lock * to be held before calling. */ void stats_clear_virtual_mounts (void) { avl_node *snode; avl_tree_wlock (_stats.source_tree); snode = avl_get_first(_stats.source_tree); while (snode) { stats_source_t *src = (stats_source_t *)snode->key; source_t *source = source_find_mount_raw (src->source); if (source == NULL) { stats_node_t *node; avl_tree_wlock (src->stats_tree); node = _find_node (src->stats_tree, "fallback"); if (node == NULL) { /* no source_t and no fallback file stat, so delete */ snode = avl_get_next (snode); avl_delete (_stats.source_tree, src, _free_source_stats); continue; } avl_tree_unlock (src->stats_tree); } snode = avl_get_next (snode); } avl_tree_unlock (_stats.source_tree); }
TElemType right_sibling( BiTree T, TElemType e ){ BitreeNode *cur_node = _find_node( e ); if( cur_node && cur_node->parent && cur_node->parent->l_child ){ return cur_node->parent->l_child->value; } else { return TElemType(0); } }
TElemType right_child( BiTree T, TElemType e ){ BitreeNode *cur_node = _find_node( e ); if( cur_node && cur_node->r_child ){ return cur_node->r_child->value; }else{ return TElemType(0); } }
TElemType parent( BiTree T, TElemType e ){ BitreeNode *cur_node = _find_node( e ); if( cur_node && cur_node->parent ){ return cur_node->parent->value; } else { return TElemType(0); } }
char *stats_retrieve (long handle, const char *name) { char *v = NULL; stats_source_t *src_stats = (stats_source_t *)handle; stats_node_t *stats = _find_node (src_stats->stats_tree, name); if (stats) v = strdup (stats->value); return v; }
static void process_global_event (stats_event_t *event) { stats_node_t *node = NULL; avl_tree_wlock (_stats.global_tree); /* DEBUG3("global event %s %s %d", event->name, event->value, event->action); */ if (event->action == STATS_EVENT_REMOVE) { /* we're deleting */ node = _find_node(_stats.global_tree, event->name); if (node != NULL) { stats_listener_send (node->flags, "DELETE global %s\n", event->name); avl_delete(_stats.global_tree, (void *)node, _free_stats); } avl_tree_unlock (_stats.global_tree); return; } node = _find_node(_stats.global_tree, event->name); if (node) { modify_node_event (node, event); if ((node->flags & STATS_REGULAR) == 0) stats_listener_send (node->flags, "EVENT global %s %s\n", node->name, node->value); } else { /* add node */ node = (stats_node_t *)calloc(1, sizeof(stats_node_t)); node->name = (char *)strdup(event->name); node->value = (char *)strdup(event->value); node->flags = event->flags; avl_insert(_stats.global_tree, (void *)node); stats_listener_send (node->flags, "EVENT global %s %s\n", event->name, event->value); } avl_tree_unlock (_stats.global_tree); }
static char *_get_stats(char *source, char *name) { stats_node_t *stats = NULL; stats_source_t *src = NULL; char *value = NULL; thread_mutex_lock(&_stats_mutex); if (source == NULL) { stats = _find_node(_stats.global_tree, name); } else { src = _find_source(_stats.source_tree, source); if (src) { stats = _find_node(src->stats_tree, name); } } if (stats) value = (char *)strdup(stats->value); thread_mutex_unlock(&_stats_mutex); return value; }
int switch_p_build_jobinfo(switch_jobinfo_t *switch_job, slurm_step_layout_t *step_layout, char *network) { sw_gen_step_info_t *gen_step_info = (sw_gen_step_info_t *) switch_job; sw_gen_node_info_t *gen_node_info; sw_gen_node_t *node_ptr; hostlist_t hl = NULL; hostlist_iterator_t hi; char *host = NULL; int i, j; if (debug_flags & DEBUG_FLAG_SWITCH) info("switch_p_build_jobinfo() starting"); xassert(gen_step_info); xassert(gen_step_info->magic == SW_GEN_STEP_INFO_MAGIC); hl = hostlist_create(step_layout->node_list); if (!hl) fatal("hostlist_create(%s): %m", step_layout->node_list); gen_step_info->node_cnt = hostlist_count(hl); gen_step_info->node_array = xmalloc(sizeof(sw_gen_node_t *) * gen_step_info->node_cnt); hi = hostlist_iterator_create(hl); for (i = 0; (host = hostlist_next(hi)); i++) { node_ptr = xmalloc(sizeof(sw_gen_node_t)); gen_step_info->node_array[i] = node_ptr; node_ptr->node_name = xstrdup(host); gen_node_info = _find_node(host); if (gen_node_info) { /* Copy node info to this step */ node_ptr->ifa_cnt = gen_node_info->ifa_cnt; node_ptr->ifa_array = xmalloc(sizeof(sw_gen_node_t *) * node_ptr->ifa_cnt); for (j = 0; j < node_ptr->ifa_cnt; j++) { node_ptr->ifa_array[j] = xmalloc(sizeof(sw_gen_node_t)); node_ptr->ifa_array[j]->ifa_addr = xstrdup( gen_node_info->ifa_array[j]->ifa_addr); node_ptr->ifa_array[j]->ifa_family = xstrdup( gen_node_info->ifa_array[j]->ifa_family); node_ptr->ifa_array[j]->ifa_name = xstrdup( gen_node_info->ifa_array[j]->ifa_name); } } free(host); } hostlist_iterator_destroy(hi); hostlist_destroy(hl); return SLURM_SUCCESS; }
static void process_source_event (stats_event_t *event) { stats_source_t *snode; avl_tree_wlock (_stats.source_tree); snode = _find_source(_stats.source_tree, event->source); if (snode == NULL) { if (event->action == STATS_EVENT_REMOVE) { avl_tree_unlock (_stats.source_tree); return; } snode = (stats_source_t *)calloc(1,sizeof(stats_source_t)); if (snode == NULL) abort(); DEBUG1 ("new source stat %s", event->source); snode->source = (char *)strdup(event->source); snode->stats_tree = avl_tree_new(_compare_stats, NULL); snode->flags = STATS_SLAVE|STATS_GENERAL|STATS_HIDDEN; avl_insert(_stats.source_tree, (void *)snode); } if (event->action == STATS_EVENT_REMOVE && event->name == NULL) { int fallback_stream = 0; avl_tree_wlock (snode->stats_tree); fallback_stream = _find_node (snode->stats_tree, "fallback") == NULL ? 1 : 0; if (fallback_stream) avl_delete(_stats.source_tree, (void *)snode, _free_source_stats); else avl_tree_unlock (snode->stats_tree); avl_tree_unlock (_stats.source_tree); return; } avl_tree_wlock (snode->stats_tree); avl_tree_unlock (_stats.source_tree); process_source_stat (snode, event); avl_tree_unlock (snode->stats_tree); }
static void process_source_stat (stats_source_t *src_stats, stats_event_t *event) { if (event->name) { stats_node_t *node = _find_node (src_stats->stats_tree, event->name); if (node == NULL) { /* adding node */ if (event->action != STATS_EVENT_REMOVE && event->value) { DEBUG3 ("new node on %s \"%s\" (%s)", src_stats->source, event->name, event->value); node = (stats_node_t *)calloc (1,sizeof(stats_node_t)); node->name = (char *)strdup (event->name); node->value = (char *)strdup (event->value); node->flags = event->flags; if (src_stats->flags & STATS_HIDDEN) node->flags |= STATS_HIDDEN; stats_listener_send (node->flags, "EVENT %s %s %s\n", src_stats->source, event->name, event->value); avl_insert (src_stats->stats_tree, (void *)node); } return; } if (event->action == STATS_EVENT_REMOVE) { DEBUG2 ("delete node %s from %s", event->name, src_stats->source); stats_listener_send (node->flags, "DELETE %s %s\n", src_stats->source, event->name); avl_delete (src_stats->stats_tree, (void *)node, _free_stats); return; } modify_node_event (node, event); stats_listener_send (node->flags, "EVENT %s %s %s\n", src_stats->source, node->name, node->value); return; } if (event->action == STATS_EVENT_REMOVE && event->name == NULL) { avl_tree_unlock (src_stats->stats_tree); avl_tree_wlock (_stats.source_tree); avl_tree_wlock (src_stats->stats_tree); avl_delete (_stats.source_tree, (void *)src_stats, _free_source_stats); avl_tree_unlock (_stats.source_tree); return; } /* change source flags status */ if (event->action & STATS_EVENT_HIDDEN) { avl_node *node = avl_get_first (src_stats->stats_tree); int visible = 0; if ((event->flags&STATS_HIDDEN) == (src_stats->flags&STATS_HIDDEN)) return; if (src_stats->flags & STATS_HIDDEN) { stats_node_t *ct = _find_node (src_stats->stats_tree, "server_type"); const char *type = "audio/mpeg"; if (ct) type = ct->value; src_stats->flags &= ~STATS_HIDDEN; stats_listener_send (src_stats->flags, "NEW %s %s\n", type, src_stats->source); visible = 1; } else { stats_listener_send (src_stats->flags, "DELETE %s\n", src_stats->source); src_stats->flags |= STATS_HIDDEN; } while (node) { stats_node_t *stats = (stats_node_t*)node->key; if (visible) { stats->flags &= ~STATS_HIDDEN; stats_listener_send (stats->flags, "EVENT %s %s %s\n", src_stats->source, stats->name, stats->value); } else stats->flags |= STATS_HIDDEN; node = avl_get_next (node); } } }
static void *_stats_thread(void *arg) { stats_event_t *event; stats_event_t *copy; stats_node_t *node; stats_node_t *anode; stats_source_t *snode; stats_source_t *asnode; event_listener_t *listener; avl_node *avlnode; while (_stats_running) { thread_mutex_lock(&_global_event_mutex); if (_global_event_queue != NULL) { /* grab the next event from the queue */ event = _global_event_queue; _global_event_queue = event->next; event->next = NULL; thread_mutex_unlock(&_global_event_mutex); thread_mutex_lock(&_stats_mutex); if (event->source == NULL) { /* we have a global event */ if (event->value != NULL) { /* adding/updating */ node = _find_node(_stats.global_tree, event->name); if (node == NULL) { /* add node */ anode = (stats_node_t *)malloc(sizeof(stats_node_t)); anode->name = (char *)strdup(event->name); anode->value = (char *)strdup(event->value); avl_insert(_stats.global_tree, (void *)anode); } else { /* update node */ free(node->value); node->value = (char *)strdup(event->value); } } else { /* we're deleting */ node = _find_node(_stats.global_tree, event->name); if (node != NULL) avl_delete(_stats.global_tree, (void *)node, _free_stats); } } else { /* we have a source event */ snode = _find_source(_stats.source_tree, event->source); if (snode != NULL) { /* this is a source we already have a tree for */ if (event->value != NULL) { /* we're add/updating */ node = _find_node(snode->stats_tree, event->name); if (node == NULL) { /* adding node */ anode = (stats_node_t *)malloc(sizeof(stats_node_t)); anode->name = (char *)strdup(event->name); anode->value = (char *)strdup(event->value); avl_insert(snode->stats_tree, (void *)anode); } else { /* updating node */ free(node->value); node->value = (char *)strdup(event->value); } } else { /* we're deleting */ node = _find_node(snode->stats_tree, event->name); if (node != NULL) { avl_delete(snode->stats_tree, (void *)node, _free_stats); avlnode = avl_get_first(snode->stats_tree); if (avlnode == NULL) { avl_delete(_stats.source_tree, (void *)snode, _free_source_stats); } } } } else { /* this is a new source */ asnode = (stats_source_t *)malloc(sizeof(stats_source_t)); asnode->source = (char *)strdup(event->source); asnode->stats_tree = avl_tree_new(_compare_stats, NULL); anode = (stats_node_t *)malloc(sizeof(stats_node_t)); anode->name = (char *)strdup(event->name); anode->value = (char *)strdup(event->value); avl_insert(asnode->stats_tree, (void *)anode); avl_insert(_stats.source_tree, (void *)asnode); } } /* now we have an event that's been processed into the running stats */ /* this event should get copied to event listeners' queues */ listener = _event_listeners; while (listener) { copy = _copy_event(event); thread_mutex_lock(listener->mutex); _add_event_to_queue(copy, listener->queue); thread_mutex_unlock(listener->mutex); listener = listener->next; } thread_cond_broadcast(&_event_signal_cond); /* now we need to destroy the event */ _free_event(event); thread_mutex_unlock(&_stats_mutex); continue; } else { thread_mutex_unlock(&_global_event_mutex); } thread_sleep(300000); } /* wake the other threads so they can shut down cleanly */ thread_cond_broadcast(&_event_signal_cond); thread_exit(0); return NULL; }
static void process_source_event (stats_event_t *event) { stats_source_t *snode = _find_source(_stats.source_tree, event->source); if (snode == NULL) { if (event->action == STATS_EVENT_REMOVE) return; snode = (stats_source_t *)calloc(1,sizeof(stats_source_t)); if (snode == NULL) return; ICECAST_LOG_DEBUG("new source stat %s", event->source); snode->source = (char *)strdup(event->source); snode->stats_tree = avl_tree_new(_compare_stats, NULL); if (event->action == STATS_EVENT_HIDDEN) snode->hidden = 1; else snode->hidden = 0; avl_insert(_stats.source_tree, (void *) snode); } if (event->name) { stats_node_t *node = _find_node(snode->stats_tree, event->name); if (node == NULL) { if (event->action == STATS_EVENT_REMOVE) return; /* adding node */ if (event->value) { ICECAST_LOG_DEBUG("new node %s (%s)", event->name, event->value); node = (stats_node_t *)calloc(1,sizeof(stats_node_t)); node->name = (char *)strdup(event->name); node->value = (char *)strdup(event->value); node->hidden = snode->hidden; avl_insert(snode->stats_tree, (void *)node); } return; } if (event->action == STATS_EVENT_REMOVE) { ICECAST_LOG_DEBUG("delete node %s", event->name); avl_delete(snode->stats_tree, (void *)node, _free_stats); return; } modify_node_event (node, event); return; } if (event->action == STATS_EVENT_HIDDEN) { avl_node *node = avl_get_first (snode->stats_tree); if (event->value) snode->hidden = 1; else snode->hidden = 0; while (node) { stats_node_t *stats = (stats_node_t*)node->key; stats->hidden = snode->hidden; node = avl_get_next (node); } return; } if (event->action == STATS_EVENT_REMOVE) { ICECAST_LOG_DEBUG("delete source node %s", event->source); avl_delete(_stats.source_tree, (void *)snode, _free_source_stats); } }
/* factoring out code for stats loops ** this function copies all stats to queue, and registers */ static void _register_listener (client_t *client) { event_listener_t *listener = client->shared_data; avl_node *node; stats_event_t stats_count; refbuf_t *refbuf; size_t size = 8192; char buffer[20]; build_event (&stats_count, NULL, "stats_connections", buffer); stats_count.action = STATS_EVENT_INC; process_event (&stats_count); /* first we fill our queue with the current stats */ refbuf = refbuf_new (size); refbuf->len = 0; /* the global stats */ avl_tree_rlock (_stats.global_tree); node = avl_get_first(_stats.global_tree); while (node) { stats_node_t *stat = node->key; if (stat->flags & listener->mask) { if (_append_to_buffer (refbuf, size, "EVENT global %s %s\n", stat->name, stat->value) < 0) { _add_node_to_stats_client (client, refbuf); refbuf = refbuf_new (size); refbuf->len = 0; continue; } } node = avl_get_next(node); } avl_tree_unlock (_stats.global_tree); /* now the stats for each source */ avl_tree_rlock (_stats.source_tree); node = avl_get_first(_stats.source_tree); while (node) { avl_node *node2; stats_node_t *metadata_stat = NULL; stats_source_t *snode = (stats_source_t *)node->key; if (snode->flags & listener->mask) { stats_node_t *ct = _find_node (snode->stats_tree, "content-type"); const char *type = "audio/mpeg"; if (ct) type = ct->name; if (_append_to_buffer (refbuf, size, "NEW %s %s\n", type, snode->source) < 0) { _add_node_to_stats_client (client, refbuf); refbuf = refbuf_new (size); refbuf->len = 0; continue; } } node = avl_get_next(node); avl_tree_rlock (snode->stats_tree); node2 = avl_get_first(snode->stats_tree); while (node2) { stats_node_t *stat = node2->key; if (metadata_stat == NULL && strcmp (stat->name, "metadata_updated") == 0) metadata_stat = stat; else if (stat->flags & listener->mask) { if (_append_to_buffer (refbuf, size, "EVENT %s %s %s\n", snode->source, stat->name, stat->value) < 0) { _add_node_to_stats_client (client, refbuf); refbuf = refbuf_new (size); refbuf->len = 0; continue; } } node2 = avl_get_next (node2); } while (metadata_stat) { if (_append_to_buffer (refbuf, size, "EVENT %s %s %s\n", snode->source, metadata_stat->name, metadata_stat->value) < 0) { _add_node_to_stats_client (client, refbuf); refbuf = refbuf_new (size); refbuf->len = 0; continue; } break; } avl_tree_unlock (snode->stats_tree); } avl_tree_unlock (_stats.source_tree); _add_node_to_stats_client (client, refbuf); /* now we register to receive future event notices */ thread_mutex_lock (&_stats.listeners_lock); listener->next = _stats.event_listeners; _stats.event_listeners = listener; thread_mutex_unlock (&_stats.listeners_lock); }