2 * Copyright (C) 1996-2014 The Squid Software Foundation and contributors
4 * Squid software is distributed under GPLv2+ license and includes
5 * contributions from numerous individuals and organizations.
6 * Please see the COPYING and CONTRIBUTORS files for details.
9 /* DEBUG: section 77 Delay Pools */
13 #if USE_DELAY_POOLS && USE_AUTH
14 #include "auth/User.h"
15 #include "auth/UserRequest.h"
16 #include "comm/Connection.h"
17 #include "DelayUser.h"
18 #include "NullDelayId.h"
22 DelayUser::operator new(size_t size
)
24 DelayPools::MemoryUsed
+= sizeof (DelayUser
);
25 return ::operator new (size
);
29 DelayUser::operator delete (void *address
)
31 DelayPools::MemoryUsed
-= sizeof (DelayUser
);
32 ::operator delete (address
);
35 DelayUser::DelayUser()
37 DelayPools::registerForUpdates (this);
40 static SplayNode
<DelayUserBucket::Pointer
>::SPLAYFREE DelayUserFree
;
42 DelayUser::~DelayUser()
44 DelayPools::deregisterForUpdates (this);
45 buckets
.head
->destroy (DelayUserFree
);
48 static SplayNode
<DelayUserBucket::Pointer
>::SPLAYCMP DelayUserCmp
;
51 DelayUserCmp(DelayUserBucket::Pointer
const &left
, DelayUserBucket::Pointer
const &right
)
53 /* Verify for re-currance of Bug 2127. either of these missing will crash strcasecmp() */
54 assert(left
->authUser
->username() != NULL
);
55 assert(right
->authUser
->username() != NULL
);
57 /* for rate limiting, case insensitive */
58 return strcasecmp(left
->authUser
->username(), right
->authUser
->username());
62 DelayUserFree(DelayUserBucket::Pointer
&)
66 DelayUserStatsWalkee(DelayUserBucket::Pointer
const ¤t
, void *state
)
68 current
->stats ((StoreEntry
*)state
);
72 DelayUser::stats(StoreEntry
* sentry
)
74 spec
.stats (sentry
, "Per User");
76 if (spec
.restore_bps
== -1)
79 storeAppendPrintf(sentry
, "\t\tCurrent: ");
82 storeAppendPrintf (sentry
, "Not used yet.\n\n");
86 buckets
.head
->walk(DelayUserStatsWalkee
, sentry
);
87 storeAppendPrintf(sentry
, "\n\n");
91 DelayUser::dump(StoreEntry
*entry
) const
96 struct DelayUserUpdater
{
97 DelayUserUpdater (DelaySpec
&_spec
, int _incr
):spec(_spec
),incr(_incr
) {};
104 DelayUserUpdateWalkee(DelayUserBucket::Pointer
const ¤t
, void *state
)
106 DelayUserUpdater
*t
= (DelayUserUpdater
*)state
;
107 /* This doesn't change the value of the DelayUserBucket, so is safe */
108 const_cast<DelayUserBucket
*>(current
.getRaw())->theBucket
.update(t
->spec
, t
->incr
);
112 DelayUser::update(int incr
)
114 DelayUserUpdater
updater(spec
, incr
);
115 buckets
.head
->walk (DelayUserUpdateWalkee
, &updater
);
124 DelayIdComposite::Pointer
125 DelayUser::id(CompositePoolNode::CompositeSelectionDetails
&details
)
127 if (!details
.user
|| !details
.user
->user() || !details
.user
->user()->username())
128 return new NullDelayId
;
130 debugs(77, 3, HERE
<< "Adding a slow-down for User '" << details
.user
->user()->username() << "'");
131 return new Id(this, details
.user
->user());
135 DelayUser::Id::operator new(size_t size
)
137 DelayPools::MemoryUsed
+= sizeof (Id
);
138 return ::operator new (size
);
142 DelayUser::Id::operator delete (void *address
)
144 DelayPools::MemoryUsed
-= sizeof (Id
);
145 ::operator delete (address
);
149 DelayUserBucket::operator new(size_t size
)
151 DelayPools::MemoryUsed
+= sizeof (DelayUserBucket
);
152 return ::operator new (size
);
156 DelayUserBucket::operator delete(void *address
)
158 DelayPools::MemoryUsed
-= sizeof(DelayUserBucket
);
159 ::operator delete(address
);
162 DelayUserBucket::DelayUserBucket(Auth::User::Pointer aUser
) : authUser(aUser
)
164 debugs(77, 3, "DelayUserBucket::DelayUserBucket");
167 DelayUserBucket::~DelayUserBucket()
170 debugs(77, 3, "DelayUserBucket::~DelayUserBucket");
174 DelayUserBucket::stats (StoreEntry
*entry
) const
176 storeAppendPrintf(entry
, " %s:", authUser
->username());
177 theBucket
.stats(entry
);
180 DelayUser::Id::Id(DelayUser::Pointer aDelayUser
, Auth::User::Pointer aUser
) : theUser(aDelayUser
)
182 theBucket
= new DelayUserBucket(aUser
);
183 DelayUserBucket::Pointer
const *existing
= theUser
->buckets
.find(theBucket
, DelayUserCmp
);
186 theBucket
= *existing
;
190 theBucket
->theBucket
.init(theUser
->spec
);
191 theUser
->buckets
.head
= theUser
->buckets
.head
->insert (theBucket
, DelayUserCmp
);
196 debugs(77, 3, "DelayUser::Id::~Id");
200 DelayUser::Id::bytesWanted (int min
, int max
) const
202 return theBucket
->theBucket
.bytesWanted(min
,max
);
206 DelayUser::Id::bytesIn(int qty
)
208 theBucket
->theBucket
.bytesIn(qty
);
211 #endif /* USE_DELAY_POOLS && USE_AUTH */