static void queue_auth_client (auth_client *auth_user, mount_proxy *mountinfo) { auth_t *auth; client_t *failed = NULL; auth_client **old_tail; if (auth_user == NULL || mountinfo == NULL) return; auth = mountinfo->auth; thread_mutex_lock (&auth->lock); auth_user->next = NULL; auth_user->auth = auth; old_tail = auth->tailp; *auth->tailp = auth_user; auth->tailp = &auth_user->next; auth->pending_count++; if (auth->refcount > auth->handlers) DEBUG0 ("max authentication handlers allocated"); else { int i; for (i=0; i<auth->handlers; i++) { if (auth->handles [i].thread == NULL) { DEBUG1 ("starting auth thread %d", i); auth->refcount++; auth->handles [i].thread = thread_create ("auth thread", auth_run_thread, &auth->handles [i], THREAD_DETACHED); if (auth->handles [i].thread == NULL) { auth->tailp = old_tail; *old_tail = NULL; auth->pending_count--; auth->refcount--; failed = auth_user->client; auth_user->client = NULL; ERROR0 ("failed to start auth thread, system limit probably reached"); } break; } } } DEBUG2 ("auth on %s has %d pending", auth->mount, auth->pending_count); thread_mutex_unlock (&auth->lock); if (failed) { client_send_403redirect (failed, auth_user->mount, "system limit reached"); auth_client_free (auth_user); } }
/* The auth thread main loop. */ static void *auth_run_thread (void *arg) { auth_t *auth = arg; ICECAST_LOG_INFO("Authentication thread started"); while (auth->running) { /* usually no clients are waiting, so don't bother taking locks */ if (auth->head) { auth_client *auth_user; /* may become NULL before lock taken */ thread_mutex_lock (&auth->lock); auth_user = (auth_client*)auth->head; if (auth_user == NULL) { thread_mutex_unlock (&auth->lock); continue; } ICECAST_LOG_DEBUG("%d client(s) pending on %s", auth->pending_count, auth->mount); auth->head = auth_user->next; if (auth->head == NULL) auth->tailp = &auth->head; auth->pending_count--; thread_mutex_unlock (&auth->lock); auth_user->next = NULL; if (auth_user->process) auth_user->process (auth, auth_user); else ICECAST_LOG_ERROR("client auth process not set"); auth_client_free (auth_user); continue; } thread_sleep (150000); } ICECAST_LOG_INFO("Authenication thread shutting down"); return NULL; }
/* The auth thread main loop. */ static void *auth_run_thread (void *arg) { auth_thread_t *handler = arg; auth_t *auth = handler->auth; DEBUG2 ("Authentication thread %d started for %s", handler->id, auth->mount); thread_rwlock_rlock (&auth_lock); while (1) { thread_mutex_lock (&auth->lock); if (auth->head) { auth_client *auth_user = auth->head; DEBUG2 ("%d client(s) pending on %s", auth->pending_count, auth->mount); auth->head = auth_user->next; if (auth->head == NULL) auth->tailp = &auth->head; auth->pending_count--; thread_mutex_unlock (&auth->lock); auth_user->next = NULL; /* associate per-thread data with auth_user here */ auth_user->thread_data = handler->data; auth_user->handler = handler->id; if (auth_user->process) auth_user->process (auth_user); auth_client_free (auth_user); continue; } handler->thread = NULL; break; } DEBUG1 ("Authenication thread %d shutting down", handler->id); auth_release (auth); thread_rwlock_unlock (&auth_lock); return NULL; }