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 Splay
<DelayUserBucket::Pointer
>::SPLAYFREE DelayUserFree
;
42 DelayUser::~DelayUser()
44 DelayPools::deregisterForUpdates (this);
45 buckets
.destroy(DelayUserFree
);
48 static Splay
<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
);
71 struct DelayUserStatsVisitor
{
73 explicit DelayUserStatsVisitor(StoreEntry
*s
) : se(s
) {}
74 void operator() (DelayUserBucket::Pointer
const ¤t
) {
80 DelayUser::stats(StoreEntry
* sentry
)
82 spec
.stats (sentry
, "Per User");
84 if (spec
.restore_bps
== -1)
87 storeAppendPrintf(sentry
, "\t\tCurrent: ");
89 if (buckets
.empty()) {
90 storeAppendPrintf (sentry
, "Not used yet.\n\n");
94 DelayUserStatsVisitor
visitor(sentry
);
95 buckets
.visit(visitor
);
96 storeAppendPrintf(sentry
, "\n\n");
100 DelayUser::dump(StoreEntry
*entry
) const
105 struct DelayUserUpdater
{
106 DelayUserUpdater (DelaySpec
&_spec
, int _incr
):spec(_spec
),incr(_incr
) {};
113 DelayUserUpdateWalkee(DelayUserBucket::Pointer
const ¤t
, void *state
)
115 DelayUserUpdater
*t
= (DelayUserUpdater
*)state
;
116 /* This doesn't change the value of the DelayUserBucket, so is safe */
117 const_cast<DelayUserBucket
*>(current
.getRaw())->theBucket
.update(t
->spec
, t
->incr
);
120 struct DelayUserUpdateVisitor
{
122 DelayUserUpdateVisitor(DelayUserUpdater
*updater
) : t(updater
) {}
123 void operator() (DelayUserBucket::Pointer
const ¤t
) {
124 const_cast<DelayUserBucket
*>(current
.getRaw())->theBucket
.update(t
->spec
, t
->incr
);
129 DelayUser::update(int incr
)
131 DelayUserUpdater
updater(spec
, incr
);
132 DelayUserUpdateVisitor
visitor(&updater
);
133 buckets
.visit(visitor
);
142 DelayIdComposite::Pointer
143 DelayUser::id(CompositePoolNode::CompositeSelectionDetails
&details
)
145 if (!details
.user
|| !details
.user
->user() || !details
.user
->user()->username())
146 return new NullDelayId
;
148 debugs(77, 3, HERE
<< "Adding a slow-down for User '" << details
.user
->user()->username() << "'");
149 return new Id(this, details
.user
->user());
153 DelayUser::Id::operator new(size_t size
)
155 DelayPools::MemoryUsed
+= sizeof (Id
);
156 return ::operator new (size
);
160 DelayUser::Id::operator delete (void *address
)
162 DelayPools::MemoryUsed
-= sizeof (Id
);
163 ::operator delete (address
);
167 DelayUserBucket::operator new(size_t size
)
169 DelayPools::MemoryUsed
+= sizeof (DelayUserBucket
);
170 return ::operator new (size
);
174 DelayUserBucket::operator delete(void *address
)
176 DelayPools::MemoryUsed
-= sizeof(DelayUserBucket
);
177 ::operator delete(address
);
180 DelayUserBucket::DelayUserBucket(Auth::User::Pointer aUser
) : authUser(aUser
)
182 debugs(77, 3, "DelayUserBucket::DelayUserBucket");
185 DelayUserBucket::~DelayUserBucket()
188 debugs(77, 3, "DelayUserBucket::~DelayUserBucket");
192 DelayUserBucket::stats (StoreEntry
*entry
) const
194 storeAppendPrintf(entry
, " %s:", authUser
->username());
195 theBucket
.stats(entry
);
198 DelayUser::Id::Id(DelayUser::Pointer aDelayUser
, Auth::User::Pointer aUser
) : theUser(aDelayUser
)
200 theBucket
= new DelayUserBucket(aUser
);
201 DelayUserBucket::Pointer
const *existing
= theUser
->buckets
.find(theBucket
, DelayUserCmp
);
204 theBucket
= *existing
;
208 theBucket
->theBucket
.init(theUser
->spec
);
209 theUser
->buckets
.insert (theBucket
, DelayUserCmp
);
214 debugs(77, 3, "DelayUser::Id::~Id");
218 DelayUser::Id::bytesWanted (int min
, int max
) const
220 return theBucket
->theBucket
.bytesWanted(min
,max
);
224 DelayUser::Id::bytesIn(int qty
)
226 theBucket
->theBucket
.bytesIn(qty
);
229 #endif /* USE_DELAY_POOLS && USE_AUTH */