Example #1
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);
}
Example #2
0
void connection_inject_event(int eventnum, void *event_data) {
    connection_t *con = calloc(1, sizeof(connection_t));

    con->event_number = eventnum;
    con->event = event_data;

    _add_connection(con);
}
Example #3
0
static void *_connection_thread (void *arg)
{
    connection_queue_t *node;
    int err;

    WARN("Launched connection thread");
    while (_connection_running)
    {
        /* XXX(xaiki): this needs to wait on a fd, so we don't kill polar bears */
        node = _get_connection();
        INFO("got node");
        if (!node) {
            continue;
        }
        err = _connection_process (node);
        if (err > 0) {
            free(node);
            continue;
        }

        switch (-err) {
        case EAGAIN:     /* put it again at the end of the queue */
            _add_connection (node);
            break;
        case EINPROGRESS:	/* already handled */
            free(node);
            break;
        default:
            ERROR ("droping node (%p, client => %p), error = %d", node, node->client, err);
            _connection_node_destroy (node);
            break;
        }
    }

    while (_con_queue) {
        node = _get_connection();
        _connection_node_destroy (node);
    }

    INFO0 ("Connection thread shutdown complete");
    return NULL;
}
Example #4
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);
}
Example #5
0
/* run along queue checking for any data that has come in or a timeout */
static void process_request_queue (void)
{
    client_queue_t **node_ref = (client_queue_t **)&_req_queue;
    ice_config_t *config = config_get_config ();
    int timeout = config->header_timeout;
    config_release_config();

    while (*node_ref)
    {
        client_queue_t *node = *node_ref;
        client_t *client = node->client;
        int len = PER_CLIENT_REFBUF_SIZE - 1 - node->offset;
        char *buf = client->refbuf->data + node->offset;

        if (len > 0)
        {
            if (client->con->con_time + timeout <= time(NULL))
                len = 0;
            else
                len = client_read_bytes (client, buf, len);
        }

        if (len > 0)
        {
            int pass_it = 1;
            char *ptr;

            /* handle \n, \r\n and nsvcap which for some strange reason has
             * EOL as \r\r\n */
            node->offset += len;
            client->refbuf->data [node->offset] = '\000';
            do
            {
                if (node->shoutcast == 1)
                {
                    /* password line */
                    if (strstr (client->refbuf->data, "\r\r\n") != NULL)
                        break;
                    if (strstr (client->refbuf->data, "\r\n") != NULL)
                        break;
                    if (strstr (client->refbuf->data, "\n") != NULL)
                        break;
                }
                /* stream_offset refers to the start of any data sent after the
                 * http style headers, we don't want to lose those */
                ptr = strstr (client->refbuf->data, "\r\r\n\r\r\n");
                if (ptr)
                {
                    node->stream_offset = (ptr+6) - client->refbuf->data;
                    break;
                }
                ptr = strstr (client->refbuf->data, "\r\n\r\n");
                if (ptr)
                {
                    node->stream_offset = (ptr+4) - client->refbuf->data;
                    break;
                }
                ptr = strstr (client->refbuf->data, "\n\n");
                if (ptr)
                {
                    node->stream_offset = (ptr+2) - client->refbuf->data;
                    break;
                }
                pass_it = 0;
            } while (0);

            if (pass_it)
            {
                if ((client_queue_t **)_req_queue_tail == &(node->next))
                    _req_queue_tail = (volatile client_queue_t **)node_ref;
                *node_ref = node->next;
                node->next = NULL;
                _add_connection (node);
                continue;
            }
        }
        else
        {
            if (len == 0 || client->con->error)
            {
                if ((client_queue_t **)_req_queue_tail == &node->next)
                    _req_queue_tail = (volatile client_queue_t **)node_ref;
                *node_ref = node->next;
                client_destroy (client);
                free (node);
                continue;
            }
        }
        node_ref = &node->next;
    }
    _handle_connection();
}