void *stats_connection(void *arg)
{
    client_t *client = (client_t *)arg;
    stats_event_t *event;
    event_listener_t listener;

    ICECAST_LOG_INFO("stats client starting");

    event_queue_init (&listener.queue);
    /* increment the thread count */
    thread_mutex_lock(&_stats_mutex);
    _stats_threads++;
    stats_event_args (NULL, "stats", "%d", _stats_threads);
    thread_mutex_unlock(&_stats_mutex);

    thread_mutex_create (&(listener.mutex));

    _register_listener (&listener);

    while (_stats_running) {
        thread_mutex_lock (&listener.mutex);
        event = _get_event_from_queue (&listener.queue);
        thread_mutex_unlock (&listener.mutex);
        if (event != NULL) {
            if (_send_event_to_client(event, client) < 0) {
                _free_event(event);
                break;
            }
            _free_event(event);
            continue;
        }
        thread_sleep (500000);
    }

    thread_mutex_lock(&_stats_mutex);
    _unregister_listener (&listener);
    _stats_threads--;
    stats_event_args (NULL, "stats", "%d", _stats_threads);
    thread_mutex_unlock(&_stats_mutex);

    thread_mutex_destroy (&listener.mutex);
    client_destroy (client);
    ICECAST_LOG_INFO("stats client finished");

    return NULL;
}
Exemple #2
0
void *stats_connection(void *arg)
{
    stats_connection_t *statcon = (stats_connection_t *)arg;
    stats_event_t *local_event_queue = NULL;
    mutex_t local_event_mutex;
    stats_event_t *event;

    /* increment the thread count */
    thread_mutex_lock(&_stats_mutex);
    _stats_threads++;
    thread_mutex_unlock(&_stats_mutex);

    thread_mutex_create(&local_event_mutex);

    _atomic_get_and_register(&local_event_queue, &local_event_mutex);

    while (_stats_running) {
        thread_mutex_lock(&local_event_mutex);
        event = _get_event_from_queue(&local_event_queue);
        if (event != NULL) {
            if (!_send_event_to_client(event, statcon->con)) {
                _free_event(event);
                thread_mutex_unlock(&local_event_mutex);
                break;
            }
            _free_event(event);
        } else {
            thread_mutex_unlock(&local_event_mutex);
            thread_cond_wait(&_event_signal_cond);
            continue;
        }
                   
        thread_mutex_unlock(&local_event_mutex);
    }

    thread_mutex_destroy(&local_event_mutex);

    thread_mutex_lock(&_stats_mutex);
    _stats_threads--;
    thread_mutex_unlock(&_stats_mutex);

    thread_exit(0);
    
    return NULL;
}
Exemple #3
0
void stats_sendxml(client_t *client)
{
    int bytes;
    stats_event_t *event;
    stats_event_t *queue;
    xmlDocPtr doc;
    xmlNodePtr node, srcnode;
    int len;
    xmlChar *buff = NULL;
    source_xml_t *snd;
    source_xml_t *src_nodes = NULL;

    queue = NULL;
    _dump_stats_to_queue(&queue);

    doc = xmlNewDoc("1.0");
    node = xmlNewDocNode(doc, NULL, "icestats", NULL);
    xmlDocSetRootElement(doc, node);


    event = _get_event_from_queue(&queue);
    while (event) {
        if (event->source == NULL) {
            xmlNewChild(node, NULL, event->name, event->value);
        } else {
            srcnode = _find_xml_node(event->source, &src_nodes, node);
            xmlNewChild(srcnode, NULL, event->name, event->value);
        }

        _free_event(event);
        event = _get_event_from_queue(&queue);
    }

    xmlDocDumpMemory(doc, &buff, &len);
    xmlFreeDoc(doc);
    
    client->respcode = 200;
    bytes = sock_write(client->con->sock, "HTTP/1.0 200 OK\r\n"
               "Content-Length: %d\r\n"
               "Content-Type: text/xml\r\n"
               "\r\n", len);
    if (bytes > 0) client->con->sent_bytes += bytes;
    else goto send_error;

    bytes = sock_write_bytes(client->con->sock, buff, len);
    if (bytes > 0) client->con->sent_bytes += bytes;

 send_error:
    while (src_nodes) {
        snd = src_nodes->next;
        free(src_nodes->mount);
        free(src_nodes);
        src_nodes = snd;
    }
    if (buff) xmlFree(buff);
}
Exemple #4
0
/*
 * Clear all events from the event list. Must already have the aeld_mutex
 * locked.
 */
static void _clear_event_list(alpsc_ev_app_t *list, int32_t *size)
{
	int32_t i;

	for (i = 0; i < *size; i++) {
		_free_event(&list[i]);
	}
	*size = 0;
	return;
}
Exemple #5
0
void stats_get_xml(xmlDocPtr *doc, int show_hidden)
{
    stats_event_t *event;
    stats_event_t *queue;
    xmlNodePtr node, srcnode;
    source_xml_t *src_nodes = NULL;
    source_xml_t *next;

    queue = NULL;
    _dump_stats_to_queue(&queue);

    *doc = xmlNewDoc("1.0");
    node = xmlNewDocNode(*doc, NULL, "icestats", NULL);
    xmlDocSetRootElement(*doc, node);


    event = _get_event_from_queue(&queue);
    while (event)
    {
        if (event->hidden <= show_hidden)
        {
            xmlChar *name, *value;
            name = xmlEncodeEntitiesReentrant (*doc, event->name);
            value = xmlEncodeEntitiesReentrant (*doc, event->value);
            srcnode = node;
            if (event->source) {
                srcnode = _find_xml_node(event->source, &src_nodes, node);
            }
            xmlNewChild(srcnode, NULL, name, value);
            xmlFree (value);
            xmlFree (name);
        }

        _free_event(event);
        event = _get_event_from_queue(&queue);
    }

    while (src_nodes) {
        next = src_nodes->next;
        free(src_nodes->mount);
        free(src_nodes);
        src_nodes = next;
    }
}
Exemple #6
0
void stats_get_xml(xmlDocPtr *doc)
{
    stats_event_t *event;
    stats_event_t *queue;
    xmlNodePtr node, srcnode;
    source_xml_t *src_nodes = NULL;
    source_xml_t *next;

    queue = NULL;
    _dump_stats_to_queue(&queue);

    *doc = xmlNewDoc("1.0");
    node = xmlNewDocNode(*doc, NULL, "icestats", NULL);
    xmlDocSetRootElement(*doc, node);


    event = _get_event_from_queue(&queue);
    while (event) {
        if (event->source == NULL) {
            xmlNewChild(node, NULL, event->name, event->value);
        } else {
            srcnode = _find_xml_node(event->source, &src_nodes, node);
            xmlNewChild(srcnode, NULL, event->name, event->value);
        }

        _free_event(event);
        event = _get_event_from_queue(&queue);
    }

    while (src_nodes) {
        next = src_nodes->next;
        free(src_nodes->mount);
        free(src_nodes);
        src_nodes = next;
    }
}
Exemple #7
0
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 *_stats_thread(void *arg)
{
    stats_event_t *event;
    stats_event_t *copy;
    event_listener_t *listener;

    stats_event_time (NULL, "server_start");
    stats_event_time_iso8601 (NULL, "server_start_iso8601");

    /* global currently active stats */
    stats_event (NULL, "clients", "0");
    stats_event (NULL, "connections", "0");
    stats_event (NULL, "sources", "0");
    stats_event (NULL, "stats", "0");
    stats_event (NULL, "listeners", "0");

    /* global accumulating stats */
    stats_event (NULL, "client_connections", "0");
    stats_event (NULL, "source_client_connections", "0");
    stats_event (NULL, "source_relay_connections", "0");
    stats_event (NULL, "source_total_connections", "0");
    stats_event (NULL, "stats_connections", "0");
    stats_event (NULL, "listener_connections", "0");

    ICECAST_LOG_INFO("stats thread started");
    while (_stats_running) {
        thread_mutex_lock(&_global_event_mutex);
        if (_global_event_queue.head != NULL) {
            /* grab the next event from the queue */
            event = _get_event_from_queue (&_global_event_queue);
            thread_mutex_unlock(&_global_event_mutex);

            if (event == NULL)
                continue;
            event->next = NULL;

            thread_mutex_lock(&_stats_mutex);

            /* check if we are dealing with a global or source event */
            if (event->source == NULL)
                process_global_event (event);
            else
                process_source_event (event);

            /* now we have an event that's been processed into the running stats */
            /* this event should get copied to event listeners' queues */
            listener = (event_listener_t *)_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;
            }

            /* 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);
    }

    return NULL;
}
Exemple #9
0
/*
 * For starting apps, push to the app list. For ending apps, removes from the
 * app list. For suspend/resume apps, edits the app list. Always adds to the
 * event list.
 */
static void _update_app(struct job_record *job_ptr,
			struct step_record *step_ptr,
			alpsc_ev_app_state_e state)
{
	uint64_t apid;
	int32_t i;
	alpsc_ev_app_t app;
	int found;

	// If aeld thread isn't running, do nothing
	if (aeld_running == 0) {
		return;
	}

	// Fill in the new event
	_initialize_event(&app, job_ptr, step_ptr, state);

	pthread_mutex_lock(&aeld_mutex);

	// Add it to the event list, only if aeld is up
	if (aeld_running == 2) {
		_add_to_app_list(&event_list, &event_list_size,
				 &event_list_capacity, &app);
	}

	// Now deal with the app list
	// Maintain app list even if aeld is down, so we have it ready when
	// it comes up.
	switch(state) {
	case ALPSC_EV_START:
		// This is new, add to the app list
		_add_to_app_list(&app_list, &app_list_size,
				 &app_list_capacity, &app);
		break;
	case ALPSC_EV_END:
		// Search for the app matching this apid
		found = 0;
		apid = SLURM_ID_HASH(job_ptr->job_id, step_ptr->step_id);
		for (i = 0; i < app_list_size; i++) {
			if (app_list[i].apid == apid) {
				found = 1;

				// Free allocated info
				_free_event(&app_list[i]);

				// Copy last list entry to this spot
				if (i < app_list_size - 1) {
					memcpy(&app_list[i],
					       &app_list[app_list_size - 1],
					       sizeof(alpsc_ev_app_t));
				}

				app_list_size--;
				break;
			}
		}

		// Not found
		if (!found) {
			debug("Application %"PRIu64" not found in app list",
			      apid);
		}
		break;
	case ALPSC_EV_SUSPEND:
	case ALPSC_EV_RESUME:
		// Search for the app matching this apid
		apid = SLURM_ID_HASH(job_ptr->job_id, step_ptr->step_id);
		for (i = 0; i < app_list_size; i++) {
			if (app_list[i].apid == apid) {
				// Found it, update the state
				app_list[i].state =
					(state == ALPSC_EV_SUSPEND) ?
					ALPSC_EV_SUSPEND : ALPSC_EV_START;
				break;
			}
		}

		// Not found
		if (i >= app_list_size) {
			debug("Application %"PRIu64" not found in app list",
			      apid);
		}
		break;
	default:
		break;
	}

	pthread_mutex_unlock(&aeld_mutex);

	_free_event(&app);
	return;
}
Exemple #10
0
static void *_stats_thread(void *arg)
{
    stats_event_t *event;
    stats_event_t *copy;
    event_listener_t *listener;

    if (!kitsune_is_updating()) { /**DSU control */
        stats_event (NULL, "server", ICECAST_VERSION_STRING);
        stats_event_time (NULL, "server_start");

        /* global currently active stats */
        stats_event (NULL, "clients", "0");
        stats_event (NULL, "connections", "0");
        stats_event (NULL, "sources", "0");
        stats_event (NULL, "stats", "0");
        
        /* global accumulating stats */
        stats_event (NULL, "client_connections", "0");
        stats_event (NULL, "source_client_connections", "0");
        stats_event (NULL, "source_relay_connections", "0");
        stats_event (NULL, "source_total_connections", "0");
        stats_event (NULL, "stats_connections", "0");
        stats_event (NULL, "listener_connections", "0");
        INFO0 ("stats thread started");
    }

    while (_stats_running) {
      kitsune_update("stats"); /**DSU updatepoint */
        if (_global_event_queue != NULL) {
            /* grab the next event from the queue */
            thread_mutex_lock(&_global_event_mutex);
            event = (stats_event_t *)_global_event_queue;
            _global_event_queue = event->next;
            thread_mutex_unlock(&_global_event_mutex);

            event->next = NULL;

            thread_mutex_lock(&_stats_mutex);

            /* check if we are dealing with a global or source event */
            if (event->source == NULL)
                process_global_event (event);
            else
                process_source_event (event);
            
            /* now we have an event that's been processed into the running stats */
            /* this event should get copied to event listeners' queues */
            listener = (event_listener_t *)_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;
            }

            /* now we need to destroy the event */
            _free_event(event);

            thread_mutex_unlock(&_stats_mutex);
            continue;
        }

        thread_sleep(300000);
    }

    return NULL;
}