ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/cvsroot/Coro/myhttpd/tbf.pl
Revision: 1.10
Committed: Wed Jan 20 21:26:17 2010 UTC (14 years, 5 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

# Content
1 package tbf;
2
3 use List::Util ();
4
5 # kind of token-bucket-filter
6
7 our $max_per_client = $::TBF_MAX_PER_CLIENT || 118000;
8
9 sub new {
10 my $class = shift;
11 my %arg = @_;
12 my $self = bless \%arg, $class;
13
14 $self->{maxbucket} ||= $::TBF_MAX_BUCKET || $self->{rate} * 5; # max bucket
15 $self->{minbucket} ||= $self->{rate}; # minimum bucket to share
16 $self->{interval} ||= List::Util::min 0.1, $::BUFSIZE / $max_per_client; # good default interval
17
18 if ($self->{rate}) {
19 $self->{w} = EV::periodic 0, $self->{interval}, undef, sub {
20 $self->inject ($self->{rate} * $self->{interval});
21 };
22 } 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 last;
50 }
51
52 if ($self->{maxbucket} < $self->{bucket}) {
53 ::unused_bandwidth ($self->{bucket} - $self->{maxbucket});
54 $self->{bucket} = $self->{maxbucket};
55 }
56 }
57
58 my $_tbf_id;
59
60 sub request {
61 my ($self, $bytes, $weight) = @_;
62
63 $weight ||= 1;
64
65 my $id = $_tbf_id++;
66 my $cb = Coro::rouse_cb;
67
68 $self->{waitw} += $weight;
69 $self->{waitq}{$id} = [$weight, 0, $bytes, sub {
70 delete $self->{waitq}{$id};
71 $self->{waitw} -= $weight;
72 &$cb;
73 }];
74
75 Coro::rouse_wait;
76 }
77
78 1;