ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Coro/myhttpd/tbf.pl
Revision: 1.6
Committed: Sat Dec 8 21:01:17 2007 UTC (16 years, 7 months ago) by root
Content type: text/plain
Branch: MAIN
CVS Tags: rel-4_91, rel-5_0, rel-4_748, rel-4_8, rel-4_9, rel-4_741, rel-4_743, rel-4_742, rel-4_744, rel-4_747, rel-4_74, rel-4_71, rel-4_72, rel-4_73, rel-4_802, rel-4_803, rel-4_801, rel-4_804, rel-4_479, rel-4_50, rel-4_51, rel-4_4, rel-4_45, rel-4_745, rel-4_901, rel-4_49, rel-4_48, rel-4_746, rel-4_47, rel-4_46, rel-4_7, rel-4_911, rel-4_912, rel-4_32, rel-4_33, rel-4_34, rel-4_35, rel-4_36, rel-4_37
Changes since 1.5: +3 -9 lines
Log Message:
convert from Event to EV

File Contents

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