static void remove_from_fh (fh_node *fh, client_t *client) { thread_mutex_lock (&fh->lock); fh->refcount--; if (fh->clients) { avl_delete (fh->clients, client, NULL); if ((fh->refcount != fh->clients->length && fh->finfo.mount) || ((fh->refcount != fh->clients->length+1) && fh->finfo.mount == NULL)) ERROR3 (" on %s, with ref %d, len %d", fh->finfo.mount, fh->refcount, fh->clients->length); } if (fh->refcount == 0 && fh->finfo.mount) { rate_free (fh->out_bitrate); if ((fh->finfo.flags & FS_FALLBACK) == 0) { fh->out_bitrate = NULL; if (fh->finfo.flags & FS_DELETE) { thread_mutex_unlock (&fh->lock); _delete_fh (fh); return; } DEBUG1 ("setting timeout as no clients on %s", fh->finfo.mount); fh->expire = time(NULL) + 10; } fh->out_bitrate = rate_setup (10000, 1000); } thread_mutex_unlock (&fh->lock); }
static void remove_from_fh (fh_node *fh, client_t *client) { thread_mutex_lock (&fh->lock); avl_delete (fh->clients, client, NULL); fh->refcount--; if (fh->refcount == 0 && fh->finfo.mount) { rate_free (fh->out_bitrate); fh->out_bitrate = rate_setup (10000, 1000); if ((fh->finfo.flags & FS_FALLBACK) == 0) { if (fh->finfo.flags & FS_DELETE) { thread_mutex_unlock (&fh->lock); _delete_fh (fh); return; } else { DEBUG1 ("setting timeout as no clients on %s", fh->finfo.mount); fh->expire = time(NULL) + 10; } } } thread_mutex_unlock (&fh->lock); }
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 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); }
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; }
/* 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; }