/*
- * Copyright (C) 1996-2015 The Squid Software Foundation and contributors
+ * Copyright (C) 1996-2018 The Squid Software Foundation and contributors
*
* Squid software is distributed under GPLv2+ license and includes
* contributions from numerous individuals and organizations.
#ifndef SQUID_SRC_CBDATA_H
#define SQUID_SRC_CBDATA_H
-#include "typedefs.h"
-
/**
\page CBDATA Callback Data Allocator API
*
* \note For internal CBDATA use only.
*/
-cbdata_type cbdataInternalAddType(cbdata_type type, const char *label, int size, FREE * free_func);
+cbdata_type cbdataInternalAddType(cbdata_type type, const char *label, int size);
-/**
- * This needs to be defined FIRST in the class definition.
- * It plays with private/public states in C++.
- */
-#define CBDATA_CLASS(type) \
+/// declaration-generator used internally by CBDATA_CLASS() and CBDATA_CHILD()
+#define CBDATA_DECL_(type, methodSpecifiers) \
public: \
void *operator new(size_t size) { \
assert(size == sizeof(type)); \
- if (!CBDATA_##type) CBDATA_##type = cbdataInternalAddType(CBDATA_##type, #type, sizeof(type), NULL); \
+ if (!CBDATA_##type) CBDATA_##type = cbdataInternalAddType(CBDATA_##type, #type, sizeof(type)); \
return (type *)cbdataInternalAlloc(CBDATA_##type,__FILE__,__LINE__); \
} \
void operator delete (void *address) { \
if (address) cbdataInternalFree(address,__FILE__,__LINE__); \
} \
- void *toCbdata() { return this; } \
+ void *toCbdata() methodSpecifiers { return this; } \
private: \
static cbdata_type CBDATA_##type;
+/// Starts cbdata-protection in a class hierarchy.
+/// Child classes in the same hierarchy should use CBDATA_CHILD().
+class CbdataParent
+{
+public:
+ virtual ~CbdataParent() {}
+ virtual void *toCbdata() = 0;
+};
+
+/// cbdata-enables a stand-alone class that is not a CbdataParent child
+/// sets the class declaration section to "private"
+/// use this at the start of your class declaration for consistency sake
+#define CBDATA_CLASS(type) CBDATA_DECL_(type, noexcept)
+
+/// cbdata-enables a CbdataParent child class (including grandchildren)
+/// sets the class declaration section to "private"
+/// use this at the start of your class declaration for consistency sake
+#define CBDATA_CHILD(type) CBDATA_DECL_(type, override final)
+
/**
* Creates a global instance pointer for the CBDATA memory allocator
* to allocate and free objects for the matching CBDATA_CLASS().
void *data;
};
+// Discouraged: Use CbcPointer<> and asynchronous calls instead if possible.
+/// an old-style void* callback parameter
+class CallbackData
+{
+public:
+ CallbackData(): data_(nullptr) {}
+ CallbackData(void *data): data_(cbdataReference(data)) {}
+ CallbackData(const CallbackData &other): data_(cbdataReference(other.data_)) {}
+ CallbackData(CallbackData &&other): data_(other.data_) { other.data_ = nullptr; }
+ ~CallbackData() { cbdataReferenceDone(data_); }
+
+ CallbackData &operator =(const CallbackData &other);
+ CallbackData &operator =(CallbackData &&other) { cbdataReferenceDone(data_); data_ = other.data_; other.data_ = nullptr; return *this; }
+
+ bool valid() const { return cbdataReferenceValid(data_); }
+ void *validDone() { void *result; return cbdataReferenceValidDone(data_, &result) ? result : nullptr; }
+
+private:
+ void *data_; ///< raw callback data, maybe invalid
+};
+
#endif /* SQUID_CBDATA_H */