1
0
mirror of https://gitlab.xiph.org/xiph/icecast-server.git synced 2024-09-22 04:15:54 -04:00

Fix: Corrected a number of lockings to avoid race conditions

This commit is contained in:
Philipp Schafft 2018-09-20 12:12:59 +00:00
parent 3f3191ce0b
commit 1e171a8e4e
5 changed files with 63 additions and 18 deletions

View File

@ -197,7 +197,9 @@ void auth_release (auth_t *authenticator) {
/* cleanup auth thread attached to this auth */ /* cleanup auth thread attached to this auth */
if (authenticator->running) { if (authenticator->running) {
authenticator->running = 0; authenticator->running = 0;
thread_mutex_unlock(&authenticator->lock);
thread_join(authenticator->thread); thread_join(authenticator->thread);
thread_mutex_lock(&authenticator->lock);
} }
if (authenticator->free) if (authenticator->free)
@ -389,15 +391,18 @@ static void *auth_run_thread (void *arg)
auth_t *auth = arg; auth_t *auth = arg;
ICECAST_LOG_INFO("Authentication thread started"); ICECAST_LOG_INFO("Authentication thread started");
while (auth->running) while (1) {
{ thread_mutex_lock(&auth->lock);
/* usually no clients are waiting, so don't bother taking locks */
if (auth->head) if (!auth->running) {
{ thread_mutex_unlock(&auth->lock);
break;
}
if (auth->head) {
auth_client *auth_user; auth_client *auth_user;
/* may become NULL before lock taken */ /* may become NULL before lock taken */
thread_mutex_lock (&auth->lock);
auth_user = (auth_client*)auth->head; auth_user = (auth_client*)auth->head;
if (auth_user == NULL) if (auth_user == NULL)
{ {
@ -415,6 +420,8 @@ static void *auth_run_thread (void *arg)
__handle_auth_client(auth, auth_user); __handle_auth_client(auth, auth_user);
continue; continue;
} else {
thread_mutex_unlock(&auth->lock);
} }
thread_sleep (150000); thread_sleep (150000);
} }

View File

@ -36,7 +36,9 @@ static thread_type *event_thread = NULL;
static void event_addref(event_t *event) { static void event_addref(event_t *event) {
if (!event) if (!event)
return; return;
thread_mutex_lock(&event_lock);
event->refcount++; event->refcount++;
thread_mutex_unlock(&event_lock);
} }
static void event_release(event_t *event) { static void event_release(event_t *event) {
@ -44,9 +46,13 @@ static void event_release(event_t *event) {
if (!event) if (!event)
return; return;
thread_mutex_lock(&event_lock);
event->refcount--; event->refcount--;
if (event->refcount) if (event->refcount) {
thread_mutex_unlock(&event_lock);
return; return;
}
for (i = 0; i < (sizeof(event->reglist)/sizeof(*event->reglist)); i++) for (i = 0; i < (sizeof(event->reglist)/sizeof(*event->reglist)); i++)
event_registration_release(event->reglist[i]); event_registration_release(event->reglist[i]);
@ -60,6 +66,7 @@ static void event_release(event_t *event) {
event_release(event->next); event_release(event->next);
free(event); free(event);
thread_mutex_unlock(&event_lock);
} }
static void event_push(event_t **event, event_t *next) { static void event_push(event_t **event, event_t *next) {
@ -78,7 +85,7 @@ static void event_push(event_t **event, event_t *next) {
return; return;
} }
event_addref(*event = next); *event = next;
} }
static void event_push_reglist(event_t *event, event_registration_t *reglist) { static void event_push_reglist(event_t *event, event_registration_t *reglist) {
@ -336,6 +343,7 @@ void event_registration_push(event_registration_t **er, event_registration_t *ta
/* event signaling */ /* event signaling */
void event_emit(event_t *event) { void event_emit(event_t *event) {
fastevent_emit(FASTEVENT_TYPE_SLOWEVENT, FASTEVENT_FLAG_NONE, FASTEVENT_DATATYPE_EVENT, event); fastevent_emit(FASTEVENT_TYPE_SLOWEVENT, FASTEVENT_FLAG_NONE, FASTEVENT_DATATYPE_EVENT, event);
event_addref(event);
thread_mutex_lock(&event_lock); thread_mutex_lock(&event_lock);
event_push(&event_queue, event); event_push(&event_queue, event);
thread_mutex_unlock(&event_lock); thread_mutex_unlock(&event_lock);

View File

@ -72,7 +72,7 @@ static int slave_running = 0;
static volatile int update_settings = 0; static volatile int update_settings = 0;
static volatile int update_all_mounts = 0; static volatile int update_all_mounts = 0;
static volatile unsigned int max_interval = 0; static volatile unsigned int max_interval = 0;
static mutex_t _slave_mutex; // protects update_settings, update_all_mounts, max_interval static mutex_t _slave_mutex; // protects slave_running, update_settings, update_all_mounts, max_interval
static inline void relay_config_upstream_free (relay_config_upstream_t *upstream) static inline void relay_config_upstream_free (relay_config_upstream_t *upstream)
{ {
@ -222,9 +222,14 @@ void slave_initialize(void)
void slave_shutdown(void) void slave_shutdown(void)
{ {
if (!slave_running) thread_mutex_lock(&_slave_mutex);
if (!slave_running) {
thread_mutex_unlock(&_slave_mutex);
return; return;
}
slave_running = 0; slave_running = 0;
thread_mutex_unlock(&_slave_mutex);
ICECAST_LOG_DEBUG("waiting for slave thread"); ICECAST_LOG_DEBUG("waiting for slave thread");
thread_join (_slave_thread_id); thread_join (_slave_thread_id);
} }
@ -895,8 +900,12 @@ static void *_slave_thread(void *arg)
global_unlock(); global_unlock();
thread_sleep(1000000); thread_sleep(1000000);
if (slave_running == 0) thread_mutex_lock(&_slave_mutex);
if (slave_running == 0) {
thread_mutex_unlock(&_slave_mutex);
break; break;
}
thread_mutex_unlock(&_slave_mutex);
++interval; ++interval;

View File

@ -154,7 +154,9 @@ void stats_shutdown(void)
return; return;
/* wait for thread to exit */ /* wait for thread to exit */
thread_mutex_lock(&_stats_mutex);
_stats_running = 0; _stats_running = 0;
thread_mutex_unlock(&_stats_mutex);
thread_join(_stats_thread_id); thread_join(_stats_thread_id);
/* wait for other threads to shut down */ /* wait for other threads to shut down */
@ -691,7 +693,14 @@ static void *_stats_thread(void *arg)
stats_event (NULL, "listener_connections", "0"); stats_event (NULL, "listener_connections", "0");
ICECAST_LOG_INFO("stats thread started"); ICECAST_LOG_INFO("stats thread started");
while (_stats_running) { while (1) {
thread_mutex_lock(&_stats_mutex);
if (!_stats_running) {
thread_mutex_unlock(&_stats_mutex);
break;
}
thread_mutex_unlock(&_stats_mutex);
thread_mutex_lock(&_global_event_mutex); thread_mutex_lock(&_global_event_mutex);
if (_global_event_queue.head != NULL) { if (_global_event_queue.head != NULL) {
/* grab the next event from the queue */ /* grab the next event from the queue */
@ -971,7 +980,14 @@ void *stats_connection(void *arg)
_register_listener (&listener); _register_listener (&listener);
while (_stats_running) { while (1) {
thread_mutex_lock(&_stats_mutex);
if (!_stats_running) {
thread_mutex_unlock(&_stats_mutex);
break;
}
thread_mutex_unlock(&_stats_mutex);
thread_mutex_lock (&listener.mutex); thread_mutex_lock (&listener.mutex);
event = _get_event_from_queue (&listener.queue); event = _get_event_from_queue (&listener.queue);
thread_mutex_unlock (&listener.mutex); thread_mutex_unlock (&listener.mutex);

View File

@ -721,10 +721,12 @@ static void delete_marked_yp(struct yp_server *server)
static void *yp_update_thread(void *arg) static void *yp_update_thread(void *arg)
{ {
ICECAST_LOG_INFO("YP update thread started"); ICECAST_LOG_INFO("YP update thread started");
int running;
yp_running = 1; yp_running = 1;
while (yp_running) running = 1;
{
while (running) {
struct yp_server *server; struct yp_server *server;
thread_sleep (200000); thread_sleep (200000);
@ -738,11 +740,10 @@ static void *yp_update_thread(void *arg)
yp_process_server (server); yp_process_server (server);
server = server->next; server = server->next;
} }
thread_rwlock_unlock (&yp_lock);
/* update the local YP structure */ /* update the local YP structure */
if (yp_update) if (yp_update)
{ {
thread_rwlock_unlock(&yp_lock);
thread_rwlock_wlock (&yp_lock); thread_rwlock_wlock (&yp_lock);
check_servers (); check_servers ();
server = (struct yp_server *)active_yps; server = (struct yp_server *)active_yps;
@ -754,8 +755,9 @@ static void *yp_update_thread(void *arg)
server = server->next; server = server->next;
} }
yp_update = 0; yp_update = 0;
thread_rwlock_unlock (&yp_lock);
} }
running = yp_running;
thread_rwlock_unlock(&yp_lock);
} }
thread_rwlock_destroy (&yp_lock); thread_rwlock_destroy (&yp_lock);
thread_mutex_destroy (&yp_pending_lock); thread_mutex_destroy (&yp_pending_lock);
@ -984,8 +986,11 @@ void yp_touch (const char *mount)
void yp_shutdown (void) void yp_shutdown (void)
{ {
thread_rwlock_wlock(&yp_lock);
yp_running = 0; yp_running = 0;
yp_update = 1; yp_update = 1;
thread_rwlock_unlock(&yp_lock);
if (yp_thread) if (yp_thread)
thread_join (yp_thread); thread_join (yp_thread);
free ((char*)server_version); free ((char*)server_version);