2 * Copyright (C) 1996-2021 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"
21 DelayUser::DelayUser()
23 DelayPools::registerForUpdates (this);
26 static Splay
<DelayUserBucket::Pointer
>::SPLAYFREE DelayUserFree
;
28 DelayUser::~DelayUser()
30 DelayPools::deregisterForUpdates (this);
31 buckets
.destroy(DelayUserFree
);
34 static Splay
<DelayUserBucket::Pointer
>::SPLAYCMP DelayUserCmp
;
37 DelayUserCmp(DelayUserBucket::Pointer
const &left
, DelayUserBucket::Pointer
const &right
)
39 /* Verify for re-currance of Bug 2127. either of these missing will crash strcasecmp() */
40 assert(left
->authUser
->username() != NULL
);
41 assert(right
->authUser
->username() != NULL
);
43 /* for rate limiting, case insensitive */
44 return strcasecmp(left
->authUser
->username(), right
->authUser
->username());
48 DelayUserFree(DelayUserBucket::Pointer
&)
52 DelayUserStatsWalkee(DelayUserBucket::Pointer
const ¤t
, void *state
)
54 current
->stats ((StoreEntry
*)state
);
57 struct DelayUserStatsVisitor
{
59 explicit DelayUserStatsVisitor(StoreEntry
*s
) : se(s
) {}
60 void operator() (DelayUserBucket::Pointer
const ¤t
) {
66 DelayUser::stats(StoreEntry
* sentry
)
68 spec
.stats (sentry
, "Per User");
70 if (spec
.restore_bps
== -1)
73 storeAppendPrintf(sentry
, "\t\tCurrent: ");
75 if (buckets
.empty()) {
76 storeAppendPrintf (sentry
, "Not used yet.\n\n");
80 DelayUserStatsVisitor
visitor(sentry
);
81 buckets
.visit(visitor
);
82 storeAppendPrintf(sentry
, "\n\n");
86 DelayUser::dump(StoreEntry
*entry
) const
91 struct DelayUserUpdater
{
92 DelayUserUpdater (DelaySpec
&_spec
, int _incr
):spec(_spec
),incr(_incr
) {};
99 DelayUserUpdateWalkee(DelayUserBucket::Pointer
const ¤t
, void *state
)
101 DelayUserUpdater
*t
= (DelayUserUpdater
*)state
;
102 /* This doesn't change the value of the DelayUserBucket, so is safe */
103 const_cast<DelayUserBucket
*>(current
.getRaw())->theBucket
.update(t
->spec
, t
->incr
);
106 struct DelayUserUpdateVisitor
{
108 DelayUserUpdateVisitor(DelayUserUpdater
*updater
) : t(updater
) {}
109 void operator() (DelayUserBucket::Pointer
const ¤t
) {
110 const_cast<DelayUserBucket
*>(current
.getRaw())->theBucket
.update(t
->spec
, t
->incr
);
115 DelayUser::update(int incr
)
117 DelayUserUpdater
updater(spec
, incr
);
118 DelayUserUpdateVisitor
visitor(&updater
);
119 buckets
.visit(visitor
);
128 DelayIdComposite::Pointer
129 DelayUser::id(CompositePoolNode::CompositeSelectionDetails
&details
)
131 if (!details
.user
|| !details
.user
->user() || !details
.user
->user()->username())
132 return new NullDelayId
;
134 debugs(77, 3, HERE
<< "Adding a slow-down for User '" << details
.user
->user()->username() << "'");
135 return new Id(this, details
.user
->user());
138 DelayUserBucket::DelayUserBucket(Auth::User::Pointer aUser
) : authUser(aUser
)
140 debugs(77, 3, "DelayUserBucket::DelayUserBucket");
143 DelayUserBucket::~DelayUserBucket()
146 debugs(77, 3, "DelayUserBucket::~DelayUserBucket");
150 DelayUserBucket::stats (StoreEntry
*entry
) const
152 storeAppendPrintf(entry
, " %s:", authUser
->username());
153 theBucket
.stats(entry
);
156 DelayUser::Id::Id(DelayUser::Pointer aDelayUser
, Auth::User::Pointer aUser
) : theUser(aDelayUser
)
158 theBucket
= new DelayUserBucket(aUser
);
159 DelayUserBucket::Pointer
const *existing
= theUser
->buckets
.find(theBucket
, DelayUserCmp
);
162 theBucket
= *existing
;
166 theBucket
->theBucket
.init(theUser
->spec
);
167 theUser
->buckets
.insert (theBucket
, DelayUserCmp
);
172 debugs(77, 3, "DelayUser::Id::~Id");
176 DelayUser::Id::bytesWanted (int min
, int max
) const
178 return theBucket
->theBucket
.bytesWanted(min
,max
);
182 DelayUser::Id::bytesIn(int qty
)
184 theBucket
->theBucket
.bytesIn(qty
);
187 #endif /* USE_DELAY_POOLS && USE_AUTH */