Example #1
0
/* fast send routine */
static int file_send (client_t *client)
{
    int loop = 6, bytes, written = 0;
    fh_node *fh = client->shared_data;
    worker_t *worker = client->worker;
    time_t now;

    if (fserve_change_worker (client)) // allow for balancing
        return 1;

    client->schedule_ms = worker->time_ms;
    now = worker->current_time.tv_sec;
    /* slowdown if max bandwidth is exceeded, but allow for short-lived connections to avoid 
     * this, eg admin requests */
    if (throttle_sends > 1 && now - client->connection.con_time > 1)
    {
        client->schedule_ms += 300;
        loop = 1; 
    }
    while (loop && written < 30000)
    {
        loop--;
        if (fserve_running == 0 || client->connection.error)
            return -1;
        if (client->connection.discon_time && now >= client->connection.discon_time)
            return -1;
        if (format_file_read (client, fh->format, fh->f) < 0)
            return -1;
        bytes = client->check_buffer (client);
        if (bytes < 0)
        {
            client->schedule_ms += (written ? 120 : 250);
            break;
        }
        written += bytes;
        client->schedule_ms += 3;
    }
    return 0;
}
Example #2
0
/* send routine for files sent at a target bitrate, eg fallback files. */
static int throttled_file_send (client_t *client)
{
    int  bytes;
    fh_node *fh = client->shared_data;
    time_t now;
    worker_t *worker = client->worker;
    unsigned long secs; 
    unsigned int  rate = 0;
    unsigned int limit = fh->finfo.limit;

    if (fserve_running == 0 || client->connection.error)
        return -1;
    now = worker->current_time.tv_sec;
    secs = now - client->timer_start; 
    client->schedule_ms = worker->time_ms;
    if (fh->finfo.fallback)
        return fserve_move_listener (client);

    if (fserve_change_worker (client)) // allow for balancing
        return 1;

    if (client->flags & CLIENT_WANTS_FLV) /* increase limit for flv clients as wrapping takes more space */
        limit = (unsigned long)(limit * 1.01);
    rate = secs ? (client->counter+1400)/secs : limit * 2;
    // DEBUG3 ("counter %lld, duration %ld, limit %u", client->counter, secs, rate);
    if (rate > limit)
    {
        if (limit >= 1400)
            client->schedule_ms += 1000/(limit/1400);
        else
            client->schedule_ms += 50; // should not happen but guard against it
        rate_add (fh->out_bitrate, 0, worker->time_ms);
        global_add_bitrates (global.out_bitrate, 0, worker->time_ms);
        if (client->counter > 8192)
            return 0; // allow an initial amount without throttling
    }
    switch (format_file_read (client, fh->format, fh->f))
    {
        case -1: // DEBUG0 ("loop of file triggered");
            client->intro_offset = 0;
            client->schedule_ms += client->throttle ? client->throttle : 150;
            return 0;
        case -2: // DEBUG0 ("major failure on read, better leave");
            return -1;
        default: //DEBUG1 ("reading from offset %ld", client->intro_offset);
            break;
    }
    bytes = client->check_buffer (client);
    if (bytes < 0)
        bytes = 0;
    //DEBUG3 ("bytes %d, counter %ld, %ld", bytes, client->counter, client->worker->time_ms - (client->timer_start*1000));
    rate_add (fh->out_bitrate, bytes, worker->time_ms);
    global_add_bitrates (global.out_bitrate, bytes, worker->time_ms);
    if (limit > 2800)
        client->schedule_ms += (1000/(limit/1400*2));
    else
        client->schedule_ms += 50;

    /* progessive slowdown if max bandwidth is exceeded. */
    if (throttle_sends > 1)
        client->schedule_ms += 300;
    return 0;
}