{
assert (!asyncInProgress());
- cbdataReferenceDone(accessList);
+ changeAcl(nullptr);
debugs(28, 4, "ACLChecklist::~ACLChecklist: destroyed " << this);
}
// Concurrent checks are not supported, but sequential checks are, and they
// may use a mixture of fastCheck(void) and fastCheck(list) calls.
- const Acl::Tree * const savedList = accessList;
-
- accessList = cbdataReference(list);
+ const Acl::Tree * const savedList = changeAcl(list);
// assume DENY/ALLOW on mis/matches due to action-free accessList
// matchAndFinish() takes care of the ALLOW case
if (!finished())
markFinished(ACCESS_DENIED, "ACLs failed to match");
- cbdataReferenceDone(accessList);
- accessList = savedList;
+ changeAcl(savedList);
occupied_ = false;
PROF_stop(aclCheckFast);
return currentAnswer();
virtual bool hasRequest() const = 0;
virtual bool hasReply() const = 0;
+ /// change the current ACL list
+ /// \return a pointer to the old list, or NULL if that is no longer CBDATA-valid
+ const Acl::Tree *changeAcl(const Acl::Tree *t) {
+ const Acl::Tree *old = accessList;
+ if (t != accessList) {
+ accessList = cbdataReference(t);
+ cbdataReferenceDone(accessList);
+ }
+ return cbdataReferenceValid(old) ? old : nullptr;
+ }
+
private:
/// Calls non-blocking check callback with the answer and destroys self.
void checkCallback(allow_t answer);
void changeState(AsyncState *);
AsyncState *asyncState() const;
-public:
const Acl::Tree *accessList;
+public:
ACLCB *callback;
void *callback_data;
dst_addr.setEmpty();
rfc931[0] = '\0';
- // cbdataReferenceDone() is in either fastCheck() or the destructor
- if (A)
- accessList = cbdataReference(A);
+ changeAcl(A);
if (http_request != NULL) {
request = http_request;
/* pools require explicit 'allow' to assign a client into them */
if (pools[pool].access) {
- cbdataReferenceDone(ch.accessList);
- ch.accessList = cbdataReference(pools[pool].access);
+ ch.changeAcl(pools[pool].access);
allow_t answer = ch.fastCheck();
if (answer == ACCESS_ALLOWED) {