mirror of
https://gitlab.xiph.org/xiph/icecast-server.git
synced 2024-12-04 14:46:30 -05:00
Fix previous changes to source creation - misunderstood requirements for
unlocking rwlocks. Move more checks and some other logic into source.c svn path=/trunk/icecast/; revision=4354
This commit is contained in:
parent
469ac14e11
commit
83b41e2beb
@ -296,7 +296,6 @@ static connection_t *_get_connection(void)
|
|||||||
int connection_create_source(client_t *client, connection_t *con, http_parser_t *parser, char *mount) {
|
int connection_create_source(client_t *client, connection_t *con, http_parser_t *parser, char *mount) {
|
||||||
source_t *source;
|
source_t *source;
|
||||||
char *contenttype;
|
char *contenttype;
|
||||||
int bytes;
|
|
||||||
|
|
||||||
/* check to make sure this source wouldn't
|
/* check to make sure this source wouldn't
|
||||||
** be over the limit
|
** be over the limit
|
||||||
@ -328,25 +327,7 @@ int connection_create_source(client_t *client, connection_t *con, http_parser_t
|
|||||||
source = source_create(client, con, parser, mount, format);
|
source = source_create(client, con, parser, mount, format);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We did a preliminary check earlier, to catch the common case before
|
source->send_return = 1;
|
||||||
* we do any unneccesary processing. Now, we do a check that must be
|
|
||||||
* correct - so we have to take a write lock out, since we need to
|
|
||||||
* add this source if it doesn't already exist.
|
|
||||||
*/
|
|
||||||
avl_tree_wlock(global.source_tree);
|
|
||||||
if (source_find_mount(mount) != NULL) {
|
|
||||||
INFO1("Source tried to log in as %s, but mountpoint is already used",
|
|
||||||
mount);
|
|
||||||
avl_tree_unlock(global.source_tree);
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
/* Keep the tree locked - it gets unlocked in source_main */
|
|
||||||
|
|
||||||
client->respcode = 200;
|
|
||||||
bytes = sock_write(client->con->sock,
|
|
||||||
"HTTP/1.0 200 OK\r\n\r\n");
|
|
||||||
if(bytes > 0) client->con->sent_bytes = bytes;
|
|
||||||
|
|
||||||
source->shutdown_rwlock = &_source_shutdown_rwlock;
|
source->shutdown_rwlock = &_source_shutdown_rwlock;
|
||||||
sock_set_blocking(con->sock, SOCK_NONBLOCK);
|
sock_set_blocking(con->sock, SOCK_NONBLOCK);
|
||||||
thread_create("Source Thread", source_main, (void *)source, THREAD_DETACHED);
|
thread_create("Source Thread", source_main, (void *)source, THREAD_DETACHED);
|
||||||
|
24
src/source.c
24
src/source.c
@ -56,6 +56,7 @@ source_t *source_create(client_t *client, connection_t *con, http_parser_t *pars
|
|||||||
src->running = 1;
|
src->running = 1;
|
||||||
src->num_yp_directories = 0;
|
src->num_yp_directories = 0;
|
||||||
src->listeners = 0;
|
src->listeners = 0;
|
||||||
|
src->send_return = 0;
|
||||||
for (i=0;i<config_get_config()->num_yp_directories;i++) {
|
for (i=0;i<config_get_config()->num_yp_directories;i++) {
|
||||||
if (config_get_config()->yp_url[i]) {
|
if (config_get_config()->yp_url[i]) {
|
||||||
src->ypdata[src->num_yp_directories] = yp_create_ypdata();
|
src->ypdata[src->num_yp_directories] = yp_create_ypdata();
|
||||||
@ -157,13 +158,32 @@ void *source_main(void *arg)
|
|||||||
/* grab a read lock, to make sure we get a chance to cleanup */
|
/* grab a read lock, to make sure we get a chance to cleanup */
|
||||||
thread_rwlock_rlock(source->shutdown_rwlock);
|
thread_rwlock_rlock(source->shutdown_rwlock);
|
||||||
|
|
||||||
/* The caller has ensured we have a write lock on the tree... */
|
avl_tree_wlock(global.source_tree);
|
||||||
|
/* Now, we must do a final check with write lock taken out that the
|
||||||
|
* mountpoint is available..
|
||||||
|
*/
|
||||||
|
if (source_find_mount(source->mount) != NULL) {
|
||||||
|
avl_tree_unlock(global.source_tree);
|
||||||
|
if(source->send_return) {
|
||||||
|
client_send_404(source->client, "Mountpoint in use");
|
||||||
|
}
|
||||||
|
thread_exit(0);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
/* insert source onto source tree */
|
/* insert source onto source tree */
|
||||||
avl_insert(global.source_tree, (void *)source);
|
avl_insert(global.source_tree, (void *)source);
|
||||||
/* release write lock on global source tree */
|
/* release write lock on global source tree */
|
||||||
avl_tree_unlock(global.source_tree);
|
avl_tree_unlock(global.source_tree);
|
||||||
|
|
||||||
|
/* If we connected successfully, we can send the message (if requested)
|
||||||
|
* back
|
||||||
|
*/
|
||||||
|
if(source->send_return) {
|
||||||
|
source->client->respcode = 200;
|
||||||
|
bytes = sock_write(source->client->con->sock,
|
||||||
|
"HTTP/1.0 200 OK\r\n\r\n");
|
||||||
|
if(bytes > 0) source->client->con->sent_bytes = bytes;
|
||||||
|
}
|
||||||
|
|
||||||
/* start off the statistics */
|
/* start off the statistics */
|
||||||
stats_event(source->mount, "listeners", "0");
|
stats_event(source->mount, "listeners", "0");
|
||||||
|
@ -30,6 +30,7 @@ typedef struct source_tag
|
|||||||
int num_yp_directories;
|
int num_yp_directories;
|
||||||
long listeners;
|
long listeners;
|
||||||
long max_listeners;
|
long max_listeners;
|
||||||
|
int send_return;
|
||||||
} source_t;
|
} source_t;
|
||||||
|
|
||||||
source_t *source_create(client_t *client, connection_t *con, http_parser_t *parser, const char *mount, format_type_t type);
|
source_t *source_create(client_t *client, connection_t *con, http_parser_t *parser, const char *mount, format_type_t type);
|
||||||
|
Loading…
Reference in New Issue
Block a user