#define SQUID_HTTPACCESSLOGENTRY_H
#include "anyp/PortCfg.h"
+#include "base/RefCount.h"
#include "comm/Connection.h"
#include "HttpHeader.h"
#include "HttpVersion.h"
#include "adaptation/icap/Elements.h"
#endif
#include "Notes.h"
-#include "RefCount.h"
#if USE_SSL
#include "ssl/gadgets.h"
#endif
#ifndef SQUID_CLIENTREQUESTCONTEXT_H
#define SQUID_CLIENTREQUESTCONTEXT_H
+#include "base/RefCount.h"
#include "cbdata.h"
-#include "RefCount.h"
#include "ipcache.h"
#if USE_ADAPTATION
#define DELAYIDCOMPOSITE_H
#if USE_DELAY_POOLS
+#include "base/RefCount.h"
#include "fatal.h"
-#include "RefCount.h"
class DeferredRead;
assert (M->requestor);
ReadRequest::Pointer readRequest = dynamic_cast<ReadRequest *>(M->requestor);
/* remove the free protection */
- readRequest->RefCountDereference();
+ readRequest->unlock();
if (M->status < 0) {
++diskd_stats.read.fail;
assert (M->requestor);
WriteRequest::Pointer writeRequest = dynamic_cast<WriteRequest *>(M->requestor);
/* remove the free protection */
- writeRequest->RefCountDereference();
+ writeRequest->unlock();
if (M->status < 0) {
errorOccured = true;
if (M->newstyle) {
DiskdFile *theFile = (DiskdFile *)M->callback_data;
- theFile->RefCountDereference();
+ theFile->unlock();
theFile->completed (M);
} else
switch (M->mtype) {
}
int
-DiskdIOStrategy::send(int mtype, int id, DiskdFile *theFile, size_t size, off_t offset, ssize_t shm_offset, RefCountable_ *requestor)
+DiskdIOStrategy::send(int mtype, int id, DiskdFile *theFile, size_t size, off_t offset, ssize_t shm_offset, Lock *requestor)
{
diomsg M;
M.callback_data = cbdataReference(theFile);
- theFile->RefCountReference();
+ theFile->lock();
M.requestor = requestor;
M.newstyle = true;
if (requestor)
- requestor->RefCountReference();
+ requestor->lock();
return SEND(&M, mtype, id, size, offset, shm_offset);
}
class DiskFile;
class DiskdFile;
-
+class Lock;
class ReadRequest;
/// \ingroup diskd
virtual void init();
virtual void sync();
virtual int callback();
- virtual void statfs(StoreEntry & sentry)const;
- int send(int mtype, int id, DiskdFile *theFile, size_t size, off_t offset, ssize_t shm_offset, RefCountable_ *requestor);
+ virtual void statfs(StoreEntry & sentry) const;
+ int send(int mtype, int id, DiskdFile *theFile, size_t size, off_t offset, ssize_t shm_offset, Lock *requestor);
/** public for accessing return address's */
SharedMemory shm;
_MQD_UNLINK
};
-struct RefCountable_;
+class Lock;
struct diomsg {
mtyp_t mtype;
int id;
int seq_no;
void * callback_data;
- RefCountable_ * requestor;
+ Lock * requestor;
size_t size;
off_t offset;
int status;
#ifndef SQUID_DISKFILE_H
#define SQUID_DISKFILE_H
+#include "base/RefCount.h"
#include "typedefs.h"
-#include "RefCount.h"
-
class IORequestor;
class ReadRequest;
#ifndef SQUID_DISKIOSTRATEGY_H
#define SQUID_DISKIOSTRATEGY_H
+#include "base/RefCount.h"
#include "Store.h"
-#include "RefCount.h"
class DiskFile;
#ifndef SQUID_IOREQUESTOR_H
#define SQUID_IOREQUESTOR_H
-#include "RefCount.h"
+#include "base/RefCount.h"
class ReadRequest;
#ifndef SQUID_READREQUEST_H
#define SQUID_READREQUEST_H
+#include "base/RefCount.h"
#include "cbdata.h"
-#include "RefCount.h"
class ReadRequest : public RefCountable
{
#ifndef SQUID_WRITEREQUEST_H
#define SQUID_WRITEREQUEST_H
+#include "base/RefCount.h"
#include "cbdata.h"
-#include "RefCount.h"
class WriteRequest : public RefCountable
{
<< "mem:" << static_cast<void*>(mem)
<< ",capacity:" << capacity
<< ",size:" << size
- << ",refs:" << RefCountCount() << "; ";
+ << ",refs:" << LockCount() << "; ";
return os;
}
#define MEMBLOB_DEBUGSECTION 24
#include "base/InstanceId.h"
+#include "base/RefCount.h"
#include "MemPool.h"
-#include "RefCount.h"
/// Various MemBlob class-wide statistics.
class MemBlobStats
#define NULLDELAYID_H
#if USE_DELAY_POOLS
-#include "RefCount.h"
+#include "base/RefCount.h"
#include "DelayIdComposite.h"
class NullDelayId : public DelayIdComposite
*/
#include "acl/AclAddress.h"
+#include "base/RefCount.h"
#include "ClientDelayConfig.h"
#include "DelayConfig.h"
#include "HelperChildConfig.h"
#include "icmp/IcmpConfig.h"
#include "ip/Address.h"
#include "Notes.h"
-#include "RefCount.h"
#include "YesNoNone.h"
#if USE_SSL
\ingroup FileSystems
*/
+#include "base/RefCount.h"
#include "comm/forward.h"
#include "CommRead.h"
#include "hash.h"
#include "HttpReply.h"
#include "HttpRequestMethod.h"
#include "Range.h"
-#include "RefCount.h"
#include "RemovalPolicy.h"
#include "StoreIOBuffer.h"
#include "StoreStats.h"
#ifndef SQUID_STOREIOSTATE_H
#define SQUID_STOREIOSTATE_H
+#include "base/RefCount.h"
#include "cbdata.h"
-#include "RefCount.h"
class StoreIOState : public RefCountable
{
#ifndef SQUID_STORESEARCH_H
#define SQUID_STORESEARCH_H
-#include "RefCount.h"
+#include "base/RefCount.h"
#include "Store.h"
class StoreSearch : public RefCountable
#include "adaptation/DynamicGroupCfg.h"
#include "Array.h"
+#include "base/RefCount.h"
#include "HttpHeader.h"
#include "Notes.h"
-#include "RefCount.h"
#include "SquidString.h"
namespace Adaptation
#ifndef SQUID__ADAPTATION__MESSAGE_H
#define SQUID__ADAPTATION__MESSAGE_H
-#include "RefCount.h"
+#include "base/RefCount.h"
class HttpMsg;
class BodyPipe;
#define SQUID_ADAPTATION__SERVICE_H
#include "SquidString.h"
-#include "RefCount.h"
#include "adaptation/forward.h"
#include "adaptation/Elements.h"
#include "adaptation/ServiceConfig.h"
+#include "base/RefCount.h"
// TODO: Move src/ICAP/ICAPServiceRep.h API comments here and update them
#define SQUID_ADAPTATION__SERVICE_CONFIG_H
#include "SquidString.h"
-#include "RefCount.h"
+#include "base/RefCount.h"
#include "adaptation/Elements.h"
namespace Adaptation
#include "SquidString.h"
#include "Array.h"
-#include "RefCount.h"
#include "adaptation/Elements.h"
#include "adaptation/forward.h"
+#include "base/RefCount.h"
namespace Adaptation
{
#ifndef SQUID_ICAPHISTORY_H
#define SQUID_ICAPHISTORY_H
+#include "base/RefCount.h"
#include "enums.h"
-#include "RefCount.h"
#include "SquidString.h"
namespace Adaptation
#define ICAP_LOG_H_
#include "AccessLogEntry.h"
-#include "RefCount.h"
+#include "base/RefCount.h"
typedef RefCount<AccessLogEntry> AccessLogEntryPointer;
class AccessLogEntry;
#if USE_AUTH
#include "Array.h"
-#include "RefCount.h"
+#include "base/RefCount.h"
/**
\defgroup AuthSchemeAPI Authentication Scheme API
Auth::User::~User()
{
debugs(29, 5, HERE << "Freeing auth_user '" << this << "'.");
- assert(RefCountCount() == 0);
+ assert(LockCount() == 0);
/* free cached acl results */
aclCacheMatchFlush(&proxy_match_cache);
auth_user->auth_type << "\n\tUsername: " << username <<
"\n\texpires: " <<
(long int) (auth_user->expiretime + ::Config.authenticateTTL) <<
- "\n\treferences: " << (long int) auth_user->RefCountCount());
+ "\n\treferences: " << auth_user->LockCount());
if (auth_user->expiretime + ::Config.authenticateTTL <= current_time.tv_sec) {
debugs(29, 5, HERE << "Removing user " << username << " from cache due to timeout.");
#include "auth/CredentialState.h"
#include "auth/Type.h"
+#include "base/RefCount.h"
#include "dlink.h"
#include "ip/Address.h"
-#include "RefCount.h"
class AuthUserHashPointer;
class StoreEntry;
Auth::UserRequest::~UserRequest()
{
- assert(RefCountCount()==0);
+ assert(LockCount()==0);
debugs(29, 5, HERE << "freeing request " << this);
if (user() != NULL) {
MEMPROXY_CLASS(Auth::Basic::UserRequest);
UserRequest() {}
- virtual ~UserRequest() { assert(RefCountCount()==0); }
+ virtual ~UserRequest() { assert(LockCount()==0); }
virtual int authenticated() const;
virtual void authenticate(HttpRequest * request, ConnStateData *conn, http_hdr_type type);
*/
Auth::Digest::UserRequest::~UserRequest()
{
- assert(RefCountCount()==0);
+ assert(LockCount()==0);
safe_free(nonceb64);
safe_free(cnonce);
Auth::Negotiate::UserRequest::~UserRequest()
{
- assert(RefCountCount()==0);
+ assert(LockCount()==0);
safe_free(server_blob);
safe_free(client_blob);
Auth::Ntlm::UserRequest::~UserRequest()
{
- assert(RefCountCount()==0);
+ assert(LockCount()==0);
safe_free(server_blob);
safe_free(client_blob);
--- /dev/null
+#ifndef SQUID_SRC_BASE_LOCK_H
+#define SQUID_SRC_BASE_LOCK_H
+
+/**
+ * This class provides a tracking counter and presents
+ * lock(), unlock() and LockCount() accessors.
+ *
+ * All locks must be cleared with unlock() before this object
+ * is destroyed.
+ *
+ * Accessors provided by this interface are not private,
+ * to allow class hierarchies.
+ *
+ * Build with -DLOCKCOUNT_DEBUG flag to enable lock debugging.
+ * It is disabled by default due to the cost of debug output.
+ */
+class Lock {
+public:
+ Lock():count_(0) {}
+
+ virtual ~Lock() { assert(count_ == 0); }
+
+ /// Register one lock / reference against this object.
+ /// All locks must be cleared before it may be destroyed.
+ void lock() const {
+#if defined(LOCKCOUNT_DEBUG)
+ old_debug(0,1)("Incrementing this %p from count %u\n",this,count_);
+#endif
+ ++count_;
+ }
+
+ /// Clear one lock / reference against this object.
+ /// All locks must be cleared before it may be destroyed.
+ unsigned unlock() const {
+#if defined(LOCKCOUNT_DEBUG)
+ old_debug(0,1)("Decrementing this %p from count %u\n",this,count_);
+#endif
+ assert(count_ > 0);
+ return --count_;
+ }
+
+ /// Inspect the current count of references.
+ unsigned LockCount() const { return count_; }
+
+private:
+ mutable unsigned count_; ///< number of references currently being tracked
+};
+
+// For clarity we provide some aliases for the tracking mechanisms
+// using Lock so that we can easily see what type of smart pointers
+// are to be used for the child object.
+// NP: CbcPointer<> and RefCount<> pointers should be used consistently
+// for any given child class type
+
+/// The locking interface for use on Reference-Counted classes
+#define RefCountable virtual Lock
+
+#endif /* SQUID_SRC_BASE_LOCK_H */
TidyPointer.h \
CbcPointer.h \
InstanceId.h \
+ Lock.h \
RunnersRegistry.cc \
RunnersRegistry.h \
Subscription.h \
TextException.cc \
TextException.h \
StringArea.h
+
+check_PROGRAMS += testRefCount
+
+testRefCount_SOURCES= \
+ Lock.h \
+ RefCount.h \
+ testRefCount.cc
+
+testRefCount_LDADD = \
+ libbase.la \
+ $(top_builddir)/lib/libmiscutil.la \
+ $(COMPAT_LIB) \
+ $(XTRA_LIBS)
+
#ifndef SQUID_REFCOUNT_H_
#define SQUID_REFCOUNT_H_
+// reference counting requires the Lock API on base classes
+#include "base/Lock.h"
+
#if HAVE_IOSTREAM
#include <iostream>
#endif
+/**
+ * Template for Reference Counting pointers.
+ *
+ * Objects of type 'C' must inherit from 'Lockable' in base/Lock.h
+ * which provides the locking interface used by reference counting.
+ */
template <class C>
class RefCount
{
C const (*tempP_) (p_);
p_ = newP;
- if (tempP_ && tempP_->RefCountDereference() == 0)
+ if (tempP_ && tempP_->unlock() == 0)
delete tempP_;
}
void reference (const RefCount& p) {
if (p.p_)
- p.p_->RefCountReference();
+ p.p_->lock();
}
C const *p_;
};
-struct RefCountable_ {
- RefCountable_():count_(0) {}
-
- virtual ~RefCountable_() { assert(count_ == 0); }
-
- /* Not private, to allow class hierarchies */
- void RefCountReference() const {
-#if REFCOUNT_DEBUG
- old_debug(0,1)("Incrementing this %p from count %u\n",this,count_);
-#endif
-
- ++count_;
- }
-
- unsigned RefCountDereference() const {
-#if REFCOUNT_DEBUG
- old_debug(0,1)("Decrementing this %p from count %u\n",this,count_);
-#endif
-
- return --count_;
- }
-
- unsigned RefCountCount() const { return count_; } // for debugging only
-
-private:
- mutable unsigned count_;
-};
-
-#define RefCountable virtual RefCountable_
-
template <class C>
inline std::ostream &operator <<(std::ostream &os, const RefCount<C> &p)
{
if (p != NULL)
- return os << p.getRaw() << '*' << p->RefCountCount();
+ return os << p.getRaw() << '*' << p->LockCount();
else
return os << "NULL";
}
-
/*
* DEBUG: section -- Refcount allocator
* AUTHOR: Robert Collins
*/
#include "squid.h"
-#include "RefCount.h"
+#include "base/RefCount.h"
-class _ToRefCount :public RefCountable
-{
+// XXX: upgrade these tests to CPPUnit testing framework
+class _ToRefCount : public RefCountable
+{
public:
_ToRefCount () {++Instances;}
-
~_ToRefCount() {--Instances;}
int someMethod() {
}
static int Instances;
-
-private:
};
typedef RefCount<_ToRefCount> ToRefCount;
class AlsoRefCountable : public RefCountable, public _ToRefCount
{
-
public:
typedef RefCount<AlsoRefCountable> Pointer;
#ifndef SQUID_CLIENTSTREAM_H
#define SQUID_CLIENTSTREAM_H
+#include "base/RefCount.h"
#include "dlink.h"
-#include "RefCount.h"
#include "StoreIOBuffer.h"
/**
*/
/// \ingroup ClientStreamAPI
-typedef RefCount<RefCountable_> ClientStreamData;
+typedef RefCount<Lock> ClientStreamData;
class clientStreamNode;
class ClientHttpRequest;
#define SQUID_CLIENTSIDE_H
#include "base/AsyncJob.h"
+#include "base/RefCount.h"
#include "BodyPipe.h"
#include "comm.h"
#include "CommCalls.h"
#include "HttpRequest.h"
#include "HttpControlMsg.h"
#include "HttpParser.h"
-#include "RefCount.h"
#include "StoreIOBuffer.h"
#if USE_AUTH
#include "auth/UserRequest.h"
#ifndef SQUID_CLIENTSIDEREPLY_H
#define SQUID_CLIENTSIDEREPLY_H
+#include "base/RefCount.h"
#include "client_side_request.h"
#include "clientStream.h"
#include "HttpHeader.h"
-#include "RefCount.h"
#include "RequestFlags.h"
#include "StoreClient.h"
#ifndef _SQUIDCONNECTIONDETAIL_H_
#define _SQUIDCONNECTIONDETAIL_H_
+#include "base/RefCount.h"
#include "comm/forward.h"
#include "defines.h"
#include "hier_code.h"
#include "ip/Address.h"
#include "MemPool.h"
-#include "RefCount.h"
#include "typedefs.h"
#if USE_SQUID_EUI
#include "eui/Eui48.h"
#define _SQUID_COMM_FORWARD_H
#include "Array.h"
-#include "RefCount.h"
+#include "base/RefCount.h"
namespace Comm
{
#ifndef SQUID_ESIELEMENT_H
#define SQUID_ESIELEMENT_H
+#include "base/RefCount.h"
#include "Debug.h"
#include "esi/Segment.h"
-#include "RefCount.h"
typedef enum {
ESI_PROCESS_COMPLETE = 0,
virtual ~ESIParserClient() {};
};
-/* for RefCountable */
-#include "RefCount.h"
+#include "base/RefCount.h"
class ESIParser : public RefCountable
{
* or perhaps use membuffers here?
*/
+#include "base/RefCount.h"
#include "cbdata.h"
#include "defines.h"
-#include "RefCount.h"
#include "SquidString.h"
class ESISegment : public RefCountable
#ifndef _SQUID_FORMAT_FORMAT_H
#define _SQUID_FORMAT_FORMAT_H
-#include "RefCount.h"
+#include "base/RefCount.h"
/*
* Squid configuration allows users to define custom formats in
* several components.
#define SQUID_FORWARD_H
#include "Array.h"
+#include "base/RefCount.h"
#include "comm.h"
#include "comm/Connection.h"
#include "err_type.h"
#include "fde.h"
#include "HttpStatusCode.h"
#include "ip/Address.h"
-#include "RefCount.h"
/* forward decls */
// XXX: SwapDirs aren't refcounted. We make IORequestor calls, which
// are refcounted. We up our count once to avoid implicit delete's.
- RefCountReference();
+ lock();
Must(!map);
map = new DirMap(path);
#ifndef SQUID_FS_UFS_REBUILDSTATE_H
#define SQUID_FS_UFS_REBUILDSTATE_H
-#include "RefCount.h"
+#include "base/RefCount.h"
#include "UFSSwapDir.h"
#include "UFSSwapLogParser.h"
#include "store_rebuild.h"
#ifndef SQUID_IPC_REQUEST_H
#define SQUID_IPC_REQUEST_H
+#include "base/RefCount.h"
#include "ipc/forward.h"
-#include "RefCount.h"
namespace Ipc
{
#ifndef SQUID_IPC_RESPONSE_H
#define SQUID_IPC_RESPONSE_H
+#include "base/RefCount.h"
#include "ipc/forward.h"
-#include "RefCount.h"
namespace Ipc
{
#ifndef SQUID_IPC_MEM_POINTER_H
#define SQUID_IPC_MEM_POINTER_H
+#include "base/RefCount.h"
#include "base/TextException.h"
#include "ipc/mem/Segment.h"
-#include "RefCount.h"
namespace Ipc
{
#define _SQUID_LOG_FORMATS_H
#include "AccessLogEntry.h"
-#include "RefCount.h"
+#include "base/RefCount.h"
typedef RefCount<AccessLogEntry> AccessLogEntryPointer;
class AccessLogEntry;
#ifndef SQUID_MGR_QUERY_PARAM_H
#define SQUID_MGR_QUERY_PARAM_H
+#include "base/RefCount.h"
#include "ipc/forward.h"
-#include "RefCount.h"
namespace Mgr
{
#ifndef SQUID_MGR_FORWARD_H
#define SQUID_MGR_FORWARD_H
-#include "RefCount.h"
+#include "base/RefCount.h"
namespace Mgr
{
#ifndef _SQUID_SSL_ERRORDETAILMANAGER_H
#define _SQUID_SSL_ERRORDETAILMANAGER_H
+#include "base/RefCount.h"
#include "ssl/gadgets.h"
#include "ssl/support.h"
-#include "RefCount.h"
#include "SquidString.h"
#if HAVE_MAP
syntheticoperators \
VirtualDeleteOperator \
StackTest \
- refcount\
splay\
MemPoolTest\
mem_node_test\
MemPoolTest\
mem_node_test\
mem_hdr_test \
- refcount\
splay \
StackTest \
syntheticoperators \
MemPoolTest_SOURCES = MemPoolTest.cc
-refcount_SOURCES = refcount.cc
-
splay_SOURCES = splay.cc
StackTest_SOURCES = StackTest.cc $(DEBUG_SOURCE)