source: trunk/libtransmission/upload.c @ 1

Last change on this file since 1 was 1, checked in by root, 15 years ago

Import from 2005-10-26

File size: 3.5 KB
Line 
1/******************************************************************************
2 * Copyright (c) 2005 Eric Petit
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20 * DEALINGS IN THE SOFTWARE.
21 *****************************************************************************/
22
23#include "transmission.h"
24
25#define FOO 10
26
27struct tr_upload_s
28{
29    tr_lock_t lock;
30    int       limit;      /* Max upload rate in KB/s */
31    int       count;      /* Number of peers currently unchoked */
32    uint64_t  dates[FOO]; /* The last times we uploaded something */
33    int       sizes[FOO]; /* How many bytes we uploaded */
34};
35
36tr_upload_t * tr_uploadInit()
37{
38    tr_upload_t * u;
39
40    u = calloc( sizeof( tr_upload_t ), 1 );
41    tr_lockInit( &u->lock );
42
43    return u;
44}
45
46void tr_uploadSetLimit( tr_upload_t * u, int limit )
47{
48    tr_lockLock( u->lock );
49    u->limit = limit;
50    tr_lockUnlock( u->lock );
51}
52
53int tr_uploadCanUnchoke( tr_upload_t * u )
54{
55    int ret;
56
57    tr_lockLock( u->lock );
58    if( u->limit < 0 )
59    {
60        /* Infinite number of slots */
61        ret = 1;
62    }
63    else
64    {
65        /* One slot per 2 KB/s */
66        ret = ( u->count < ( u->limit + 1 ) / 2 );
67    }
68    tr_lockUnlock( u->lock );
69
70    return ret;
71}
72
73void tr_uploadChoked( tr_upload_t * u )
74{
75    tr_lockLock( u->lock );
76    (u->count)--;
77    tr_lockUnlock( u->lock );
78}
79
80void tr_uploadUnchoked( tr_upload_t * u )
81{
82    tr_lockLock( u->lock );
83    (u->count)++;
84    tr_lockUnlock( u->lock );
85}
86
87int tr_uploadCanUpload( tr_upload_t * u )
88{
89    int ret, i, size;
90    uint64_t now;
91
92    tr_lockLock( u->lock );
93    if( u->limit < 0 )
94    {
95        /* No limit */
96        ret = 1;
97    }
98    else
99    {
100        ret  = 0;
101        size = 0;
102        now  = tr_date();
103
104        /* Check the last four times we sent something and decide if
105           we must wait */
106        for( i = 0; i < FOO; i++ )
107        {
108            size += u->sizes[i];
109            if( (uint64_t) size < 1024ULL *
110                    u->limit * ( now - u->dates[i] ) / 1000 )
111            {
112                ret = 1;
113                break;
114            }
115        }
116    }
117    tr_lockUnlock( u->lock );
118
119    return ret;
120}
121
122void tr_uploadUploaded( tr_upload_t * u, int size )
123{
124    tr_lockLock( u->lock );
125    memmove( &u->dates[1], &u->dates[0], (FOO-1) * sizeof( uint64_t ) );
126    memmove( &u->sizes[1], &u->sizes[0], (FOO-1) * sizeof( int ) );
127    u->dates[0] = tr_date();
128    u->sizes[0] = size;
129    tr_lockUnlock( u->lock );
130}
131
132void tr_uploadClose( tr_upload_t * u )
133{
134    tr_lockClose( u->lock );
135    free( u );
136}
Note: See TracBrowser for help on using the repository browser.