void fserve_initialize(void) { if (fserve_running) return; ice_config_t *config = config_get_config(); mimetypes = NULL; thread_spin_create (&pending_lock); #ifndef HAVE_PREAD thread_mutex_create (&seekread_lock); #endif fh_cache = avl_tree_new (_compare_fh, NULL); fserve_recheck_mime_types (config); config_release_config(); stats_event_flags (NULL, "file_connections", "0", STATS_COUNTERS); fserve_running = 1; memset (&no_file, 0, sizeof (no_file)); thread_mutex_create (&no_file.lock); no_file.clients = avl_tree_new (client_compare, NULL); no_file.refcount = 1; no_file.expire = (time_t)-1; no_file.f = -1; avl_insert (fh_cache, &no_file); INFO0("file serving started"); }
void stats_initialize(void) { if (_stats_running) return; /* set up global struct */ _stats.global_tree = avl_tree_new(_compare_stats, NULL); _stats.source_tree = avl_tree_new(_compare_source_stats, NULL); _stats.event_listeners = NULL; thread_mutex_create (&_stats.listeners_lock); _stats_running = 1; stats_event_time (NULL, "server_start", STATS_GENERAL); /* global currently active stats */ stats_event_flags (NULL, "clients", "0", STATS_COUNTERS); stats_event_flags (NULL, "connections", "0", STATS_COUNTERS); stats_event_flags (NULL, "sources", "0", STATS_COUNTERS); stats_event_flags (NULL, "stats", "0", STATS_COUNTERS); stats_event_flags (NULL, "banned_IPs", "0", STATS_COUNTERS); stats_event (NULL, "listeners", "0"); /* global accumulating stats */ stats_event_flags (NULL, "client_connections", "0", STATS_COUNTERS); stats_event_flags (NULL, "source_client_connections", "0", STATS_COUNTERS); stats_event_flags (NULL, "source_relay_connections", "0", STATS_COUNTERS); stats_event_flags (NULL, "source_total_connections", "0", STATS_COUNTERS); stats_event_flags (NULL, "stats_connections", "0", STATS_COUNTERS); stats_event_flags (NULL, "listener_connections", "0", STATS_COUNTERS); stats_event_flags (NULL, "outgoing_kbitrate", "0", STATS_COUNTERS|STATS_REGULAR); stats_event_flags (NULL, "stream_kbytes_sent", "0", STATS_COUNTERS|STATS_REGULAR); stats_event_flags (NULL, "stream_kbytes_read", "0", STATS_COUNTERS|STATS_REGULAR); }
void global_initialize(void) { memset (&global, 0, sizeof (global)); global.source_tree = avl_tree_new(source_compare_sources, NULL); #ifdef MY_ALLOC global.alloc_tree = avl_tree_new(compare_allocs, NULL); #endif thread_mutex_create(&_global_mutex); global.out_bitrate = rate_setup (20000, 1000); }
void thread_initialize(void) { thread_type *thread; /* set up logging */ #ifdef THREAD_DEBUG log_initialize(); _logid = log_open("thread.log"); log_set_level(_logid, THREAD_DEBUG); #endif #ifdef DEBUG_MUTEXES /* create all the internal mutexes, and initialize the mutex tree */ _mutextree = avl_tree_new(_compare_mutexes, NULL); /* we have to create this one by hand, because there's no ** mutextree_mutex to lock yet! */ _mutex_create(&_mutextree_mutex); _mutextree_mutex.mutex_id = _next_mutex_id++; avl_insert(_mutextree, (void *)&_mutextree_mutex); #endif thread_mutex_create(&_threadtree_mutex); thread_mutex_create(&_library_mutex); /* initialize the thread tree and insert the main thread */ _threadtree = avl_tree_new(_compare_threads, NULL); thread = (thread_type *)amalloc(sizeof(thread_type)); thread->thread_id = _next_thread_id++; thread->line = 0; thread->file = strdup("main.c"); thread->sys_thread = pthread_self(); thread->create_time = time(NULL); thread->name = strdup("Main Thread"); avl_insert(_threadtree, (void *)thread); _catch_signals(); _initialized = 1; }
void test_avl_tree_to_array(void) { AVLTree *tree; int entries[] = { 89, 23, 42, 4, 16, 15, 8, 99, 50, 30 }; int sorted[] = { 4, 8, 15, 16, 23, 30, 42, 50, 89, 99 }; int num_entries = sizeof(entries) / sizeof(int); int i; int **array; /* Add all entries to the tree */ tree = avl_tree_new((AVLTreeCompareFunc) int_compare); for (i=0; i<num_entries; ++i) { avl_tree_insert(tree, &entries[i], NULL); } assert(avl_tree_num_entries(tree) == num_entries); /* Convert to an array and check the contents */ array = (int **) avl_tree_to_array(tree); for (i=0; i<num_entries; ++i) { assert(*array[i] == sorted[i]); } free(array); }
long stats_handle (const char *mount) { stats_source_t *src_stats; if (mount == NULL) return 0; avl_tree_wlock (_stats.source_tree); src_stats = _find_source(_stats.source_tree, mount); if (src_stats == NULL) { src_stats = (stats_source_t *)calloc (1, sizeof (stats_source_t)); if (src_stats == NULL) abort(); DEBUG1 ("new source stat %s", mount); src_stats->source = (char *)strdup (mount); src_stats->stats_tree = avl_tree_new (_compare_stats, NULL); src_stats->flags = STATS_SLAVE|STATS_GENERAL|STATS_HIDDEN; avl_insert (_stats.source_tree, (void *)src_stats); } avl_tree_wlock (src_stats->stats_tree); avl_tree_unlock (_stats.source_tree); return (long)src_stats; }
void global_initialize(void) { global.server_sockets = 0; global.relays = NULL; global.master_relays = NULL; global.running = 0; global.clients = 0; global.sources = 0; global.source_tree = avl_tree_new(source_compare_sources, NULL); #ifdef MY_ALLOC global.alloc_tree = avl_tree_new(compare_allocs, NULL); #endif thread_mutex_create(&_global_mutex); thread_spin_create (&global.spinlock); global.out_bitrate = rate_setup (20000, 1000); }
void httpp_initialize(http_parser_t *parser, http_varlist_t *defaults) { http_varlist_t *list; parser->req_type = httpp_req_none; parser->uri = NULL; parser->vars = avl_tree_new(_compare_vars, NULL); parser->queryvars = avl_tree_new(_compare_vars, NULL); /* now insert the default variables */ list = defaults; while (list != NULL) { httpp_setvar(parser, list->var.name, list->var.value); list = list->next; } }
void init_trees(void) { if (competitors_tree) avl_tree_free(competitors_tree, free_avl_key); competitors_tree = avl_tree_new(competitors_avl_compare, NULL); avl_set_data(0, "", "", ""); avl_set_data(1000, "", "", ""); }
void global_initialize(void) { global.serversock = 0; global.running = 0; global.clients = 0; global.sources = 0; global.source_tree = avl_tree_new(source_compare_sources, NULL); thread_mutex_create(&_global_mutex); }
/* function to handle the re-populating of the avl tree containing IP addresses * for deciding whether a connection of an incoming request is to be dropped. */ static void recheck_ip_file (cache_file_contents *cache) { time_t now = time(NULL); if (now >= cache->file_recheck) { struct stat file_stat; FILE *file = NULL; int count = 0; avl_tree *new_ips; char line [MAX_LINE_LEN]; cache->file_recheck = now + 10; if (cache->filename == NULL) { if (cache->contents) { avl_tree_free (cache->contents, free_filtered_ip); cache->contents = NULL; } return; } if (stat (cache->filename, &file_stat) < 0) { WARN2 ("failed to check status of \"%s\": %s", cache->filename, strerror(errno)); return; } if (file_stat.st_mtime == cache->file_mtime) return; /* common case, no update to file */ cache->file_mtime = file_stat.st_mtime; file = fopen (cache->filename, "r"); if (file == NULL) { WARN2("Failed to open file \"%s\": %s", cache->filename, strerror (errno)); return; } new_ips = avl_tree_new (compare_ip, NULL); while (get_line (file, line, MAX_LINE_LEN)) { char *str; if(!line[0] || line[0] == '#') continue; count++; str = strdup (line); if (str) avl_insert (new_ips, str); } fclose (file); INFO2 ("%d entries read from file \"%s\"", count, cache->filename); if (cache->contents) avl_tree_free (cache->contents, free_filtered_ip); cache->contents = new_ips; } }
void stats_initialize(void) { _event_listeners = NULL; /* set up global struct */ _stats.global_tree = avl_tree_new(_compare_stats, NULL); _stats.source_tree = avl_tree_new(_compare_source_stats, NULL); /* set up global mutex */ thread_mutex_create(&_stats_mutex); /* set up stats queues */ event_queue_init(&_global_event_queue); thread_mutex_create(&_global_event_mutex); /* fire off the stats thread */ _stats_running = 1; _stats_thread_id = thread_create("Stats Thread", _stats_thread, NULL, THREAD_ATTACHED); }
void global_initialize(void) { memset(global.serversock, 0, sizeof(int)*MAX_LISTEN_SOCKETS); global.server_sockets = 0; global.running = 0; global.clients = 0; global.sources = 0; global.source_tree = avl_tree_new(source_compare_sources, NULL); thread_mutex_create(&_global_mutex); }
static void create_mime_mappings(char *fn) { FILE *mimefile = fopen(fn, "r"); char line[4096]; char *type, *ext, *cur; mime_type *mapping; mimetypes = avl_tree_new(_compare_mappings, NULL); if(!mimefile) return; while(fgets(line, 4096, mimefile)) { line[4095] = 0; if(*line == 0 || *line == '#') continue; type = line; cur = line; while(*cur != ' ' && *cur != '\t' && *cur) cur++; if(*cur == 0) continue; *cur++ = 0; while(1) { while(*cur == ' ' || *cur == '\t') cur++; if(*cur == 0) break; ext = cur; while(*cur != ' ' && *cur != '\t' && *cur != '\n' && *cur) cur++; *cur++ = 0; if(*ext) { void *tmp; /* Add a new extension->type mapping */ mapping = malloc(sizeof(mime_type)); mapping->ext = strdup(ext); mapping->type = strdup(type); if(!avl_get_by_key(mimetypes, mapping, &tmp)) avl_delete(mimetypes, mapping, _delete_mapping); avl_insert(mimetypes, mapping); } } } fclose(mimefile); }
void test_avl_tree_free(void) { AVLTree *tree; /* Try freeing an empty tree */ tree = avl_tree_new((AVLTreeCompareFunc) int_compare); avl_tree_free(tree); /* Create a big tree and free it */ tree = create_tree(); avl_tree_free(tree); }
/* Allocate a new source with the stated mountpoint, if one already * exists with that mountpoint in the global source tree then return * NULL. */ source_t *source_reserve (const char *mount) { source_t *src = NULL; if(mount[0] != '/') WARN1("Source at \"%s\" does not start with '/', clients will be " "unable to connect", mount); do { avl_tree_wlock (global.source_tree); src = source_find_mount_raw (mount); if (src) { src = NULL; break; } src = calloc (1, sizeof(source_t)); if (src == NULL) break; src->client_tree = avl_tree_new(_compare_clients, NULL); src->pending_tree = avl_tree_new(_compare_clients, NULL); /* make duplicates for strings or similar */ src->mount = strdup (mount); src->max_listeners = -1; avl_insert (global.source_tree, src); } while (0); avl_tree_unlock (global.source_tree); return src; }
AVLTree *create_tree(void) { AVLTree *tree; int i; /* Create a tree and fill with nodes */ tree = avl_tree_new((AVLTreeCompareFunc) int_compare); for (i=0; i<NUM_TEST_VALUES; ++i) { test_array[i] = i; avl_tree_insert(tree, &test_array[i], &test_array[i]); } return tree; }
int fserve_set_override (const char *mount, const char *dest, format_type_t type) { fh_node fh, *result; fh.finfo.flags = FS_FALLBACK; fh.finfo.mount = (char *)mount; fh.finfo.fallback = NULL; fh.finfo.type = type; avl_tree_wlock (fh_cache); result = find_fh (&fh.finfo); if (result) { thread_mutex_lock (&result->lock); if (result->refcount > 0) { fh_node *copy = calloc (1, sizeof (*copy)); avl_delete (fh_cache, result, NULL); copy->finfo = result->finfo; copy->finfo.mount = strdup (copy->finfo.mount); copy->prev_count = -1; // trigger stats update copy->expire = (time_t)-1; copy->stats = result->stats; copy->format = result->format; copy->f = result->f; thread_mutex_create (©->lock); copy->out_bitrate = rate_setup (10000, 1000); copy->clients = avl_tree_new (client_compare, NULL); avl_insert (fh_cache, copy); result->finfo.flags |= FS_DELETE; result->finfo.flags &= ~FS_FALLBACK; result->format = NULL; result->stats = 0; result->f = SOCK_ERROR; result->finfo.fallback = strdup (dest); result->finfo.type = type; } avl_tree_unlock (fh_cache); thread_mutex_unlock (&result->lock); INFO2 ("move clients from %s to %s", mount, dest); return 1; } avl_tree_unlock (fh_cache); return 0; }
/* function to handle the re-populating of the avl tree containing IP addresses * for deciding whether a connection of an incoming request is to be dropped. */ static void recheck_cached_file (cache_file_contents *cache, time_t now) { if (now >= cache->file_recheck) { struct stat file_stat; FILE *file = NULL; int count = 0; char line [MAX_LINE_LEN]; cache->file_recheck = now + 10; if (cache->filename == NULL) { cache_prune (cache); return; } if (stat (cache->filename, &file_stat) < 0) { WARN2 ("failed to check status of \"%s\": %s", cache->filename, strerror(errno)); return; } if (file_stat.st_mtime == cache->file_mtime) return; /* common case, no update to file */ cache->file_mtime = file_stat.st_mtime; file = fopen (cache->filename, "r"); if (file == NULL) { WARN2("Failed to open file \"%s\": %s", cache->filename, strerror (errno)); return; } cache_prune (cache); cache->contents = avl_tree_new (cache->compare, &cache->file_recheck); while (get_line (file, line, MAX_LINE_LEN)) { if(!line[0] || line[0] == '#') continue; count++; cache->add_new_entry (cache, line, 0); } fclose (file); INFO2 ("%d entries read from file \"%s\"", count, cache->filename); } }
void test_avl_tree_child(void) { AVLTree *tree; AVLTreeNode *root; AVLTreeNode *left; AVLTreeNode *right; int values[] = { 1, 2, 3 }; int *p; int i; /* Create a tree containing some values. Validate the * tree is consistent at all stages. */ tree = avl_tree_new((AVLTreeCompareFunc) int_compare); for (i=0; i<3; ++i) { avl_tree_insert(tree, &values[i], &values[i]); } /* Check the tree */ root = avl_tree_root_node(tree); p = avl_tree_node_value(root); assert(*p == 2); left = avl_tree_node_child(root, AVL_TREE_NODE_LEFT); p = avl_tree_node_value(left); assert(*p == 1); right = avl_tree_node_child(root, AVL_TREE_NODE_RIGHT); p = avl_tree_node_value(right); assert(*p == 3); /* Check invalid values */ assert(avl_tree_node_child(root, -1) == NULL); assert(avl_tree_node_child(root, 10000) == NULL); assert(avl_tree_node_child(root, 2) == NULL); assert(avl_tree_node_child(root, -100000) == NULL); avl_tree_free(tree); }
void test_avl_tree_insert_lookup(void) { AVLTree *tree; AVLTreeNode *node; int i; int *value; /* Create a tree containing some values. Validate the * tree is consistent at all stages. */ tree = avl_tree_new((AVLTreeCompareFunc) int_compare); for (i=0; i<NUM_TEST_VALUES; ++i) { test_array[i] = i; avl_tree_insert(tree, &test_array[i], &test_array[i]); assert(avl_tree_num_entries(tree) == i + 1); validate_tree(tree); } assert(avl_tree_root_node(tree) != NULL); /* Check that all values can be read back again */ for (i=0; i<NUM_TEST_VALUES; ++i) { node = avl_tree_lookup_node(tree, &i); assert(node != NULL); value = avl_tree_node_key(node); assert(*value == i); value = avl_tree_node_value(node); assert(*value == i); } /* Check that invalid nodes are not found */ i = -1; assert(avl_tree_lookup_node(tree, &i) == NULL); i = NUM_TEST_VALUES + 100; assert(avl_tree_lookup_node(tree, &i) == NULL); avl_tree_free(tree); }
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 test_avl_tree (void) { AVLTree* avl_tree; avl_tree = avl_tree_new (string_compare); avl_tree_free (avl_tree); }
void fserve_recheck_mime_types (ice_config_t *config) { mime_type *mapping; int i; avl_tree *old_mimetypes = NULL, *new_mimetypes = avl_tree_new(_compare_mappings, NULL); mime_type defaults[] = { { "m3u", "audio/x-mpegurl" }, { "pls", "audio/x-scpls" }, { "xspf", "application/xspf+xml" }, { "ogg", "application/ogg" }, { "mp3", "audio/mpeg" }, { "aac", "audio/aac" }, { "aacp", "audio/aacp" }, { "css", "text/css" }, { "txt", "text/plain" }, { "html", "text/html" }, { "jpg", "image/jpg" }, { "png", "image/png" }, { "gif", "image/gif" }, { NULL, NULL } }; for (i=0; defaults[i].ext; i++) { mapping = malloc (sizeof(mime_type)); mapping->ext = strdup (defaults [i].ext); mapping->type = strdup (defaults [i].type); if (avl_insert (new_mimetypes, mapping) != 0) _delete_mapping (mapping); } do { char *type, *ext, *cur; FILE *mimefile = NULL; char line[4096]; if (config->mimetypes_fn == NULL) { INFO0 ("no mime types file defined, using defaults"); break; } mimefile = fopen (config->mimetypes_fn, "r"); if (mimefile == NULL) { WARN1 ("Cannot open mime types file %s, using defaults", config->mimetypes_fn); break; } while (fgets(line, sizeof line, mimefile)) { line[4095] = 0; if(*line == 0 || *line == '#') continue; type = line; cur = line; while(*cur != ' ' && *cur != '\t' && *cur) cur++; if(*cur == 0) continue; *cur++ = 0; while(1) { while(*cur == ' ' || *cur == '\t') cur++; if(*cur == 0) break; ext = cur; while(*cur != ' ' && *cur != '\t' && *cur != '\n' && *cur) cur++; *cur++ = 0; if(*ext) { void *tmp; /* Add a new extension->type mapping */ mapping = malloc(sizeof(mime_type)); mapping->ext = strdup(ext); mapping->type = strdup(type); if (!avl_get_by_key (new_mimetypes, mapping, &tmp)) avl_delete (new_mimetypes, mapping, _delete_mapping); if (avl_insert (new_mimetypes, mapping) != 0) _delete_mapping (mapping); } } } fclose(mimefile); } while (0); thread_spin_lock (&pending_lock); old_mimetypes = mimetypes; mimetypes = new_mimetypes; thread_spin_unlock (&pending_lock); if (old_mimetypes) avl_tree_free (old_mimetypes, _delete_mapping); }
static void htpasswd_recheckfile (htpasswd_auth_state *htpasswd) { FILE *passwdfile; avl_tree *new_users; int num = 0; struct stat file_stat; char *sep; char line [MAX_LINE_LEN]; if (stat (htpasswd->filename, &file_stat) < 0) { WARN1 ("failed to check status of %s", htpasswd->filename); return; } if (file_stat.st_mtime == htpasswd->mtime) { /* common case, no update to file */ return; } INFO1 ("re-reading htpasswd file \"%s\"", htpasswd->filename); passwdfile = fopen (htpasswd->filename, "rb"); if (passwdfile == NULL) { WARN2("Failed to open authentication database \"%s\": %s", htpasswd->filename, strerror(errno)); return; } htpasswd->mtime = file_stat.st_mtime; new_users = avl_tree_new (compare_users, NULL); while (get_line(passwdfile, line, MAX_LINE_LEN)) { int len; htpasswd_user *entry; num++; if(!line[0] || line[0] == '#') continue; sep = strrchr (line, ':'); if (sep == NULL) { WARN2("No separator on line %d (%s)", num, htpasswd->filename); continue; } entry = calloc (1, sizeof (htpasswd_user)); len = strlen (line) + 1; entry->name = malloc (len); *sep = 0; memcpy (entry->name, line, len); entry->pass = entry->name + (sep-line) + 1; avl_insert (new_users, entry); } fclose (passwdfile); thread_rwlock_wlock (&htpasswd->file_rwlock); if (htpasswd->users) avl_tree_free (htpasswd->users, _free_user); htpasswd->users = new_users; thread_rwlock_unlock (&htpasswd->file_rwlock); }
void fserve_recheck_mime_types(ice_config_t *config) { FILE *mimefile; char line[4096]; char *type, *ext, *cur; mime_type *mapping; avl_tree *new_mimetypes; if (config->mimetypes_fn == NULL) return; mimefile = fopen (config->mimetypes_fn, "r"); if (mimefile == NULL) { ICECAST_LOG_WARN("Cannot open mime types file %s", config->mimetypes_fn); return; } new_mimetypes = avl_tree_new(_compare_mappings, NULL); while(fgets(line, 4096, mimefile)) { line[4095] = 0; if(*line == 0 || *line == '#') continue; type = line; cur = line; while(*cur != ' ' && *cur != '\t' && *cur) cur++; if(*cur == 0) continue; *cur++ = 0; while(1) { while(*cur == ' ' || *cur == '\t') cur++; if(*cur == 0) break; ext = cur; while(*cur != ' ' && *cur != '\t' && *cur != '\n' && *cur) cur++; *cur++ = 0; if(*ext) { void *tmp; /* Add a new extension->type mapping */ mapping = malloc(sizeof(mime_type)); mapping->ext = strdup(ext); mapping->type = strdup(type); if (!avl_get_by_key (new_mimetypes, mapping, &tmp)) avl_delete (new_mimetypes, mapping, _delete_mapping); avl_insert (new_mimetypes, mapping); } } } fclose(mimefile); thread_spin_lock (&pending_lock); if (mimetypes) avl_tree_free (mimetypes, _delete_mapping); mimetypes = new_mimetypes; thread_spin_unlock (&pending_lock); }
map_info() { m_tree = avl_tree_new(avl_cmp, this); }
/* find/create handle and return it with the structure in a locked state */ static fh_node *open_fh (fbinfo *finfo) { fh_node *fh, *result; if (finfo->mount == NULL) finfo->mount = ""; fh = calloc (1, sizeof (fh_node)); memcpy (&fh->finfo, finfo, sizeof (fbinfo)); if (avl_get_by_key (fh_cache, fh, (void**)&result) == 0) { free (fh); thread_mutex_lock (&result->lock); avl_tree_unlock (fh_cache); if (finfo->flags & FS_FALLBACK) { if (result->finfo.type != finfo->type && finfo->type != FORMAT_TYPE_UNDEFINED) { WARN1 ("format mismatched for %s", finfo->mount); thread_mutex_unlock (&result->lock); return NULL; } result->expire = (time_t)-1; } return result; } // insert new one if (fh->finfo.mount[0]) { char *fullpath= util_get_path_from_normalised_uri (fh->finfo.mount, fh->finfo.flags&FS_USE_ADMIN); char *contenttype = fserve_content_type (fullpath); format_type_t type = format_get_type (contenttype); if (fh->finfo.type == FORMAT_TYPE_UNDEFINED) fh->finfo.type = type; if (finfo->flags & FS_FALLBACK) { if (fh->finfo.type != type && type != FORMAT_TYPE_UNDEFINED && fh->finfo.type != FORMAT_TYPE_UNDEFINED) { avl_tree_unlock (fh_cache); free (contenttype); free (fullpath); free (fh); WARN1 ("format mismatched for %s", finfo->mount); return NULL; } fh->expire = (time_t)-1; INFO2 ("lookup of fallback file \"%s\" (%d)", finfo->mount, finfo->limit); } else INFO1 ("lookup of \"%s\"", finfo->mount); if (file_open (&fh->f, fullpath) < 0) { INFO1 ("Failed to open \"%s\"", fullpath); avl_tree_unlock (fh_cache); free (contenttype); free (fullpath); free (fh); return NULL; } free (fullpath); fh->format = calloc (1, sizeof (format_plugin_t)); fh->format->type = fh->finfo.type; fh->format->contenttype = strdup (contenttype); free (contenttype); if (fh->finfo.type != FORMAT_TYPE_UNDEFINED) { fh->format->mount = strdup (fh->finfo.mount); if (format_get_plugin (fh->format) < 0) { avl_tree_unlock (fh_cache); file_close (&fh->f); free (fh->format); free (fh); return NULL; } } if (fh->finfo.limit) fh->out_bitrate = rate_setup (10000, 1000); } fh->clients = avl_tree_new (client_compare, NULL); thread_mutex_create (&fh->lock); thread_mutex_lock (&fh->lock); avl_insert (fh_cache, fh); avl_tree_unlock (fh_cache); fh->refcount = 0; fh->peak = 0; fh->finfo.mount = strdup (finfo->mount); fh->finfo.fallback = NULL; return fh; }
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); } }