Ejemplo n.º 1
0
int queue_interrupt_all(queue_t *queue)
{
    int rv;
    if ((rv = thread_mutex_lock(queue->one_big_mutex)) != 0) {
        return rv;
    }
    thread_cond_broadcast(queue->not_empty);
    thread_cond_broadcast(queue->not_full);

    if ((rv = thread_mutex_unlock(queue->one_big_mutex)) != 0) {
        return rv;
    }

    return 0;
}
Ejemplo n.º 2
0
void connection_accept_loop(void)
{
    connection_t *con;

    _build_pool();

    while (global.running == ICE_RUNNING)
    {
        if (global . schedule_config_reread)
        {
            /* reread config file */
            INFO0("Scheduling config reread ...");

            connection_inject_event(EVENT_CONFIG_READ, NULL);
            global . schedule_config_reread = 0;
        }

        con = _accept_connection();

        if (con) {
            _add_connection(con);
        }
    }

    /* Give all the other threads notification to shut down */
    thread_cond_broadcast(&global.shutdown_cond);

    _destroy_pool();

    /* wait for all the sources to shutdown */
    thread_rwlock_wlock(&_source_shutdown_rwlock);
    thread_rwlock_unlock(&_source_shutdown_rwlock);
}
Ejemplo n.º 3
0
static int
read_frame(void)
{
    struct v4l2_buffer buf;

    CLEAR (buf);

    buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    buf.memory = V4L2_MEMORY_MMAP;

    if (-1 == _ioctl (video.fd, VIDIOC_DQBUF, &buf)) {
        switch (errno) {
            case EAGAIN:
                return 0;

            case EIO:
                /* Could ignore EIO, see spec. */
                /* fall through */

            default:
                assert(0, "failure on ioctl.VIDIOC_DQBUF");
        }
    }

    assert(buf.index < n_buffers, "non-fatal assert");

    thread_lock(video.array);
    video.array.val = buffers[buf.index].start;
    thread_cond_broadcast(&video.array_new);

    assert_fatal(-1 != _ioctl (video.fd, VIDIOC_QBUF, &buf),
            "failure on ioctl.VIDIOC_QBUF");

    return 1;
}
Ejemplo n.º 4
0
void signal_usr1_handler(int signum)
{
    LOG_INFO0("Metadata update requested");
    metadata_update_signalled = 1;
    thread_cond_broadcast(&ices_config->event_pending_cond);

    signal(SIGUSR1, signal_usr1_handler);
}
Ejemplo n.º 5
0
int pthread_cond_broadcast(pthread_cond_t *cond)
{
    if (cond == NULL)
        return_errno(EINVAL, EINVAL);
    if (*cond == PTHREAD_COND_INITIALIZER)
        if (pthread_cond_init(cond, NULL) != OK)
            return errno;
    if (!thread_cond_broadcast((cond_t *)(*cond)))
        return errno;
    return OK;
}
Ejemplo n.º 6
0
void submit_job(JOB_CRUNCHER f, void *data)
{
set_concurrency(get_max_threads());

thread_mutex_lock(&jobs_mutex);
if(jobs_free>=jobs_size)expand_jobs();
jobs_submitted++;
job[jobs_free].data=data;
job[jobs_free].job=f;
jobs_free++;
thread_cond_broadcast(&wait_for_more_jobs_condition);
thread_mutex_unlock(&jobs_mutex);
}
Ejemplo n.º 7
0
void signal_int_handler(int signum)
{
    /* Is a mutex needed here? Probably */
    if (!ices_config->shutdown) 
    {
        LOG_INFO0("Shutdown requested...");
        ices_config->shutdown = 1;
        thread_cond_broadcast(&ices_config->queue_cond);

        /* If user gives a second sigint, just die. */
        signal(SIGINT, SIG_DFL);
    }
}
Ejemplo n.º 8
0
void set_concurrency(int num)
{
int i;
thread_mutex_lock(&thread_num_mutex);
num_threads=num-1;
if(num_threads>max_threads)num_threads=max_threads;
for(i=threads_started;i<num_threads;i++)
	if(pthread_create(&(thread_id[i]), NULL,(void * (*)(void *))  thread_cruncher, (void *)i)<0){
		fprintf(stderr,"Could not spawn thread %d:", i);
		perror("");
		}
if(num_threads>threads_started)
	threads_started=num_threads;
thread_cond_broadcast(&thread_not_needed);
thread_mutex_unlock(&thread_num_mutex);
}
Ejemplo n.º 9
0
void connection_accept_loop (void)
{
    connection_queue_t *node;
    connection_t *con;
    ice_config_t *config;
    int duration = 3000;
    int timeout = 0;

    config = config_get_config ();
    get_ssl_certificate (config);
    timeout = config->header_timeout;
    config_release_config ();

    while (global.running == ICE_RUNNING)
    {
        con = _accept_connection (duration);

        if (!con) {
            duration = 30000; /* use longer timeouts when nothing waiting */
            continue;
        }

        con->con_timeout = time(NULL) + timeout;

        /* add connection async to the connection queue, then the
         * connection loop will do all the dirty work */
        node =_connection_node_new (con);
        _add_connection (node);
        duration = 3000;
    }

    /* Give all the other threads notification to shut down */
    thread_cond_broadcast(&global.shutdown_cond);

    /* wait for all the sources to shutdown */
    thread_rwlock_wlock(&_source_shutdown_rwlock);
    thread_rwlock_unlock(&_source_shutdown_rwlock);
}
Ejemplo n.º 10
0
int main(void)
{
	int rv;
	thread_mutex_t *thread_mutex = NULL;
    thread_cond_t *thread_cond = NULL;
	thread_mutex_create(&thread_mutex,THREAD_MUTEX_DEFAULT);
	thread_cond_create(&thread_cond);

	rv = thread_cond_signal(thread_cond);                                                         
	rv = thread_mutex_lock(thread_mutex);                                                         
	rv = thread_cond_timedwait(thread_cond, thread_mutex, 10000);                                        
	printf("rv:%d\n",rv);
	rv = thread_mutex_unlock(thread_mutex);                                                       
	rv = thread_cond_broadcast(thread_cond);                                                      
	rv = thread_mutex_lock(thread_mutex);                                                         
	rv = thread_cond_timedwait(thread_cond, thread_mutex, 10000);                                        
	rv = thread_mutex_unlock(thread_mutex);


	thread_cond_destroy(thread_cond);
	thread_mutex_destroy(thread_mutex);
	return 0;
}
Ejemplo n.º 11
0
int do_single_job(int thread_id)
{
long i;
thread_mutex_lock(&jobs_mutex);
i=next_job_to_do;
if(i>=jobs_free){
	thread_mutex_unlock(&jobs_mutex);
	return 0;
	}
next_job_to_do++;
thread_mutex_unlock(&jobs_mutex);
job[i].job(thread_id, job[i].data);
thread_mutex_lock(&jobs_mutex);
jobs_done++;
if(jobs_done==jobs_submitted) {
	thread_cond_broadcast(&all_done_condition);
	set_concurrency(1);
	thread_mutex_unlock(&jobs_mutex);
	return 0;
	}
thread_mutex_unlock(&jobs_mutex);
return 1;
}
Ejemplo n.º 12
0
void input_loop(void)
{
    input_module_t *inmod=NULL;
    instance_t *instance, *prev, *next;
    queue_item *queued;
    int shutdown = 0;
    int current_module = 0;
    int valid_stream = 1;
    int inc_count;
    int not_waiting_for_critical;
    int foundmodule = 0;

    thread_cond_create(&ices_config->queue_cond);
    thread_cond_create(&ices_config->event_pending_cond);
    thread_mutex_create(&ices_config->refcount_lock);
    thread_mutex_create(&ices_config->flush_lock);

    memset (&control, 0, sizeof (control));

    while(ices_config->playlist_module && modules[current_module].open)
    {
        if(!strcmp(ices_config->playlist_module, modules[current_module].name))
        {
            foundmodule = 1;
            inmod = modules[current_module].open(ices_config->module_params);
            break;
        }
        current_module++;
    }

    if(!inmod)
    {
        if(foundmodule)
            LOG_ERROR1("Couldn't initialise input module \"%s\"", 
                    ices_config->playlist_module);
        else
            LOG_ERROR1("No input module named \"%s\" could be found", 
                    ices_config->playlist_module);
        return;
    }

    ices_config->inmod = inmod;


    /* ok, basic config stuff done. Now, we want to start all our listening
     * threads.
     */

    instance = ices_config->instances;

    while(instance) 
    {
        stream_description *arg = calloc(1, sizeof(stream_description));
        arg->stream = instance;
        arg->input = inmod;
        /*
        if(instance->savefilename != NULL)
            thread_create("savefile", savefile_stream, arg, 1);
         */
        thread_create("stream", ices_instance_stream, arg, 1);

        instance = instance->next;
    }
    /* treat as if a signal has arrived straight away */
    signal_usr1_handler (0);

    /* now we go into the main loop
     * We shut down the main thread ONLY once all the instances
     * have killed themselves.
     */
    while(!shutdown) 
    {
        ref_buffer *chunk = calloc(1, sizeof(ref_buffer));
        buffer_queue *current;
        int ret;

        instance = ices_config->instances;
        prev = NULL;

        while(instance)
        {
            /* if an instance has died, get rid of it
            ** this should be replaced with something that tries to 
            ** restart the instance, probably.
            */
            if (instance->died) 
            {
                LOG_DEBUG0("An instance died, removing it");
                next = instance->next;

                if (prev)
                    prev->next = next;
                else
                    ices_config->instances = next;

                /* Just in case, flush any existing buffers
                 * Locks shouldn't be needed, but lets be SURE */
                thread_mutex_lock(&ices_config->flush_lock);
                input_flush_queue(instance->queue, 0);
                thread_mutex_unlock(&ices_config->flush_lock);

                config_free_instance(instance);
                free(instance);

                instance = next;
                continue;
            }

            prev = instance;
            instance = instance->next;
        }

        instance = ices_config->instances;

        if(!instance)
        {
            shutdown = 1;
            free(chunk);
            continue;
        }

        if(ices_config->shutdown) /* We've been signalled to shut down, but */
        {                          /* the instances haven't done so yet... */
            timing_sleep(250); /* sleep for quarter of a second */
            free(chunk);
            continue;
        }

        /* If this is the first time through, set initial time. This should
         * be done before the call to inmod->getdata() below, in order to
         * properly keep time if this input module blocks.
         */
        if (control.starttime == 0)
            control.starttime = timing_get_time();

        /* get a chunk of data from the input module */
        ret = inmod->getdata(inmod->internal, chunk);

        /* input module signalled non-fatal error. Skip this chunk */
        if(ret==0)
        {
            free(chunk);
            continue;
        }

        /* Input module signalled fatal error, shut down - nothing we can do
         * from here */
        if(ret < 0)
        {
            ices_config->shutdown = 1;
            thread_cond_broadcast(&ices_config->queue_cond);
            free(chunk);
            continue;
        }

        if(chunk->critical)
            valid_stream = 1;

        if(ret < 0) {
            /* Tell the input module to go to the next track, hopefully allowing
             * resync. */
            ices_config->inmod->handle_event(ices_config->inmod,
                    EVENT_NEXTTRACK,NULL);
            valid_stream = 0;
        }

        inc_count = 0;
        not_waiting_for_critical = 0;

        if(valid_stream) 
        {
            while(instance)
            {
                if(instance->wait_for_critical && !chunk->critical)
                {
                    instance = instance->next;
                    continue;

                }

                not_waiting_for_critical = 1;

                if(instance->skip)
                {
                    instance = instance->next;
                    continue;
                }

                queued = malloc(sizeof(queue_item));

                queued->buf = chunk;
                current = instance->queue;

                inc_count++;

                thread_mutex_lock(&current->lock);

                if(current->head == NULL)
                {
                    current->head = current->tail = queued;
                    current->head->next = current->tail->next = NULL;
                }
                else
                {
                    current->tail->next = queued;
                    queued->next = NULL;
                    current->tail = queued;
                }

                current->length++;
                thread_mutex_unlock(&current->lock);

                instance = instance->next;
            }
        }

        /* If everything is waiting for a critical buffer, force one
         * early. (This will take effect on the next pass through)
         */
        if(valid_stream && !not_waiting_for_critical) {
            ices_config->inmod->handle_event(ices_config->inmod,
                    EVENT_NEXTTRACK,NULL);
            instance = ices_config->instances;
            while(instance) {
                thread_mutex_lock(&ices_config->flush_lock);
                input_flush_queue(instance->queue, 0);
                instance->wait_for_critical = 0;
                thread_mutex_unlock(&ices_config->flush_lock);
                instance = instance->next;
            }
        }

        /* Make sure we don't end up with a 0-refcount buffer that 
         * will never hit any of the free points. (this happens
         * if all threads are set to skip, for example).
         */
        thread_mutex_lock(&ices_config->refcount_lock);
        chunk->count += inc_count;
        if(!chunk->count)
        {
            free(chunk->buf);
            free(chunk);
        }
        thread_mutex_unlock(&ices_config->refcount_lock);

        if(valid_stream) {
            /* wake up the instances */
            thread_cond_broadcast(&ices_config->queue_cond);

        }
    }

    LOG_INFO0 ("All instances removed, shutting down...");

    ices_config->shutdown = 1;
    thread_cond_broadcast(&ices_config->event_pending_cond);
    timing_sleep(250); /* sleep for quarter of a second */

    thread_cond_destroy(&ices_config->queue_cond);
    thread_cond_destroy(&ices_config->event_pending_cond);
    thread_mutex_destroy(&ices_config->flush_lock);
    thread_mutex_destroy(&ices_config->refcount_lock);

    inmod->handle_event(inmod, EVENT_SHUTDOWN, NULL);

    return;
}
Ejemplo n.º 13
0
void wake_crunchers(void)
{
thread_mutex_lock(&jobs_mutex);
thread_cond_broadcast(&wait_for_more_jobs_condition);
thread_mutex_unlock(&jobs_mutex);
}
Ejemplo n.º 14
0
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;
}
Ejemplo n.º 15
0
void connection_accept_loop (void)
{
    connection_t *con;
    ice_config_t *config;
    int duration = 300;

    config = config_get_config ();
    get_ssl_certificate (config);
    config_release_config ();

    while (global.running == ICE_RUNNING)
    {
        con = _accept_connection (duration);

        if (con)
        {
            client_queue_t *node;
            ice_config_t *config;
            client_t *client = NULL;
            listener_t *listener;

            global_lock();
            if (client_create (&client, con, NULL) < 0)
            {
                global_unlock();
                client_send_403 (client, "Icecast connection limit reached");
                /* don't be too eager as this is an imposed hard limit */
                thread_sleep (400000);
                continue;
            }

            /* setup client for reading incoming http */
            client->refbuf->data [PER_CLIENT_REFBUF_SIZE-1] = '\000';

            if (sock_set_blocking (client->con->sock, 0) || sock_set_nodelay (client->con->sock))
            {
                global_unlock();
                WARN0 ("failed to set tcp options on client connection, dropping");
                client_destroy (client);
                continue;
            }

            node = calloc (1, sizeof (client_queue_t));
            if (node == NULL)
            {
                global_unlock();
                client_destroy (client);
                continue;
            }
            node->client = client;

            config = config_get_config();
            listener = config_get_listen_sock (config, client->con);

            if (listener)
            {
                if (listener->shoutcast_compat)
                    node->shoutcast = 1;
                if (listener->ssl && ssl_ok)
                    connection_uses_ssl (client->con);
                if (listener->shoutcast_mount)
                    node->shoutcast_mount = strdup (listener->shoutcast_mount);
            }
            global_unlock();
            config_release_config();

            _add_request_queue (node);
            stats_event_inc (NULL, "connections");
            duration = 5;
        }
        else
        {
            if (_req_queue == NULL)
                duration = 300; /* use longer timeouts when nothing waiting */
        }
        process_request_queue ();
    }

    /* Give all the other threads notification to shut down */
    thread_cond_broadcast(&global.shutdown_cond);

    /* wait for all the sources to shutdown */
    thread_rwlock_wlock(&_source_shutdown_rwlock);
    thread_rwlock_unlock(&_source_shutdown_rwlock);
}
Ejemplo n.º 16
0
void connection_accept_loop(void)
{
    connection_t *con;

    if (!kitsune_is_updating()) /**DSU control */
        tid = thread_create("connection thread", _handle_connection, NULL, THREAD_ATTACHED);

    while (global.running == ICE_RUNNING)
    {
      kitsune_update("connection_accept"); /**DSU updatepoint */

        con = _accept_connection();

        if (con)
        {
            client_queue_t *node;
            ice_config_t *config;
            int i;
            client_t *client = NULL;

            global_lock();
            if (client_create (&client, con, NULL) < 0)
            {
                global_unlock();
                client_send_404 (client, "Icecast connection limit reached");
                continue;
            }
            global_unlock();

            /* setup client for reading incoming http */
            client->refbuf->data [PER_CLIENT_REFBUF_SIZE-1] = '\000';

            node = calloc (1, sizeof (client_queue_t));
            if (node == NULL)
            {
                client_destroy (client);
                continue;
            }
            node->client = client;

            /* Check for special shoutcast compatability processing */
            config = config_get_config();
            for (i = 0; i < global.server_sockets; i++)
            {
                if (global.serversock[i] == con->serversock)
                {
                    if (config->listeners[i].shoutcast_compat)
                        node->shoutcast = 1;
                }
            }
            config_release_config(); 

            sock_set_blocking (client->con->sock, SOCK_NONBLOCK);
            sock_set_nodelay (client->con->sock);

            _add_request_queue (node);
            stats_event_inc (NULL, "connections");
        }
        process_request_queue ();
    }

    /* Give all the other threads notification to shut down */
    thread_cond_broadcast(&global.shutdown_cond);

    if (tid)
        thread_join (tid);

    /* wait for all the sources to shutdown */
    thread_rwlock_wlock(&_source_shutdown_rwlock);
    thread_rwlock_unlock(&_source_shutdown_rwlock);
}
Ejemplo n.º 17
0
void connection_accept_loop(void)
{
    connection_t *con;
    ice_config_t *config;

    config = config_get_config ();
    get_ssl_certificate (config);
    config_release_config ();

    tid = thread_create ("connection thread", _handle_connection, NULL, THREAD_ATTACHED);

    while (global.running == ICE_RUNNING)
    {
        con = _accept_connection();

        if (con)
        {
            client_queue_t *node;
            ice_config_t *config;
            client_t *client = NULL;
            listener_t *listener;

            global_lock();
            if (client_create (&client, con, NULL) < 0)
            {
                global_unlock();
                client_send_403 (client, "Icecast connection limit reached");
                /* don't be too eager as this is an imposed hard limit */
                thread_sleep (400000);
                continue;
            }
            global_unlock();

            /* setup client for reading incoming http */
            client->refbuf->data [PER_CLIENT_REFBUF_SIZE-1] = '\000';

            node = calloc (1, sizeof (client_queue_t));
            if (node == NULL)
            {
                client_destroy (client);
                continue;
            }
            node->client = client;

            config = config_get_config();
            listener = config_get_listen_sock (config, client->con);

            if (listener)
            {
                if (listener->shoutcast_compat)
                    node->shoutcast = 1;
                if (listener->ssl && ssl_ok)
                    connection_uses_ssl (client->con);
                if (listener->shoutcast_mount)
                    node->shoutcast_mount = strdup (listener->shoutcast_mount);
            }
            config_release_config();

            sock_set_blocking (client->con->sock, SOCK_NONBLOCK);
            sock_set_nodelay (client->con->sock);

            _add_request_queue (node);
            stats_event_inc (NULL, "connections");
        }
        process_request_queue ();
    }

    /* Give all the other threads notification to shut down */
    thread_cond_broadcast(&global.shutdown_cond);

    if (tid)
        thread_join (tid);

    /* wait for all the sources to shutdown */
    thread_rwlock_wlock(&_source_shutdown_rwlock);
    thread_rwlock_unlock(&_source_shutdown_rwlock);
}