ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Coro/myhttpd/tbf.pl
Revision: 1.10
Committed: Wed Jan 20 21:26:17 2010 UTC (14 years, 6 months ago) by root
Content type: text/plain
Branch: MAIN
CVS Tags: rel-6_0, rel-6_5, rel-6_10, rel-6_09, rel-6_08, rel-6_07, rel-6_06, rel-6_05, rel-6_04, rel-6_03, rel-6_02, rel-6_01, rel-5_371, rel-5_372, rel-6_512, rel-6_513, rel-6_511, rel-6_514, rel-5_22, rel-5_23, rel-5_24, rel-5_25, rel-6_32, rel-6_33, rel-6_31, rel-6_36, rel-6_37, rel-6_38, rel-6_39, rel-5_37, rel-5_36, rel-6_23, rel-6_29, rel-6_28, rel-6_46, rel-6_45, rel-6_51, rel-6_52, rel-6_53, rel-6_54, rel-6_55, rel-6_56, rel-6_57, rel-6_43, rel-6_42, rel-6_41, rel-6_47, rel-6_44, rel-6_49, rel-6_48, HEAD
Changes since 1.9: +3 -1 lines
Log Message:
*** empty log message ***

File Contents

# User Rev Content
1 root 1.1 package tbf;
2    
3 root 1.10 use List::Util ();
4    
5 root 1.1 # kind of token-bucket-filter
6    
7 root 1.8 our $max_per_client = $::TBF_MAX_PER_CLIENT || 118000;
8 root 1.1
9     sub new {
10     my $class = shift;
11     my %arg = @_;
12     my $self = bless \%arg, $class;
13    
14 root 1.9 $self->{maxbucket} ||= $::TBF_MAX_BUCKET || $self->{rate} * 5; # max bucket
15 root 1.1 $self->{minbucket} ||= $self->{rate}; # minimum bucket to share
16 root 1.10 $self->{interval} ||= List::Util::min 0.1, $::BUFSIZE / $max_per_client; # good default interval
17 root 1.1
18     if ($self->{rate}) {
19 root 1.6 $self->{w} = EV::periodic 0, $self->{interval}, undef, sub {
20     $self->inject ($self->{rate} * $self->{interval});
21     };
22 root 1.1 } else {
23     die "chaining not yet implemented\n";
24     }
25    
26     $self;
27     }
28    
29     sub inject {
30     my ($self, $bytes) = @_;
31    
32     $self->{bucket} += $bytes;
33    
34     while ($self->{bucket} >= $self->{minbucket}) {
35     if ($self->{waitw}) {
36     my $rate = $self->{bucket} / $self->{waitw};
37    
38     for my $v (values %{$self->{waitq}}) {
39     $self->{bucket} -= $rate * $v->[0];
40     $v->[1] += $rate * $v->[0];
41    
42     if ($v->[1] >= $v->[2]) {
43     $self->{bucket} += $v->[1] - $v->[2];
44     $v->[3]->();
45     }
46     }
47    
48     }
49 root 1.3 last;
50     }
51 root 1.1
52 root 1.3 if ($self->{maxbucket} < $self->{bucket}) {
53     ::unused_bandwidth ($self->{bucket} - $self->{maxbucket});
54     $self->{bucket} = $self->{maxbucket};
55 root 1.1 }
56     }
57    
58     my $_tbf_id;
59    
60     sub request {
61     my ($self, $bytes, $weight) = @_;
62    
63     $weight ||= 1;
64    
65 root 1.7 my $id = $_tbf_id++;
66     my $cb = Coro::rouse_cb;
67 root 1.2
68     $self->{waitw} += $weight;
69     $self->{waitq}{$id} = [$weight, 0, $bytes, sub {
70     delete $self->{waitq}{$id};
71     $self->{waitw} -= $weight;
72 root 1.7 &$cb;
73 root 1.2 }];
74    
75 root 1.7 Coro::rouse_wait;
76 root 1.1 }
77    
78     1;