mirror of
https://github.com/zeek/zeek.git
synced 2025-10-05 16:18:19 +00:00
IntrusivePtr: replace the "add_ref" parameter with tag structs
Using a runtime parameter is obscure and error-prone. Avoiding error-prone code and getting reference counting right is the whole point of this class.
This commit is contained in:
parent
7c0863dccf
commit
31b3a56740
7 changed files with 41 additions and 15 deletions
|
@ -2828,7 +2828,7 @@ Val* IndexExpr::Fold(Val* v1, Val* v2) const
|
|||
|
||||
void IndexExpr::Assign(Frame* f, Val* arg_v)
|
||||
{
|
||||
IntrusivePtr v{arg_v, false};
|
||||
IntrusivePtr v{AdoptRef{}, arg_v};
|
||||
|
||||
if ( IsError() )
|
||||
return;
|
||||
|
@ -2849,7 +2849,7 @@ void IndexExpr::Assign(Frame* f, Val* arg_v)
|
|||
// Hold an extra reference to 'arg_v' in case the ownership transfer to
|
||||
// the table/vector goes wrong and we still want to obtain diagnostic info
|
||||
// from the original value after the assignment already unref'd.
|
||||
IntrusivePtr v_extra{arg_v, true};
|
||||
IntrusivePtr v_extra{NewRef{}, arg_v};
|
||||
|
||||
switch ( v1->Type()->Tag() ) {
|
||||
case TYPE_VECTOR:
|
||||
|
|
|
@ -5,6 +5,18 @@
|
|||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
/**
|
||||
* A tag class for the #IntrusivePtr constructor which means: adopt
|
||||
* the reference from the caller.
|
||||
*/
|
||||
struct AdoptRef {};
|
||||
|
||||
/**
|
||||
* A tag class for the #IntrusivePtr constructor which means: create a
|
||||
* new reference to the object.
|
||||
*/
|
||||
struct NewRef {};
|
||||
|
||||
/**
|
||||
* An intrusive, reference counting smart pointer implementation. Much like
|
||||
* @c std::shared_ptr, this smart pointer models shared ownership of an object
|
||||
|
@ -54,13 +66,27 @@ public:
|
|||
/**
|
||||
* Constructs a new intrusive pointer for managing the lifetime of the object
|
||||
* pointed to by @c raw_ptr.
|
||||
*
|
||||
* This overload adopts the existing reference from the caller.
|
||||
*
|
||||
* @param raw_ptr Pointer to the shared object.
|
||||
* @param add_ref Denotes whether the reference count of the object shall be
|
||||
* increased during construction.
|
||||
*/
|
||||
IntrusivePtr(pointer raw_ptr, bool add_ref) noexcept
|
||||
IntrusivePtr(AdoptRef, pointer raw_ptr) noexcept
|
||||
{
|
||||
setPtr(raw_ptr, add_ref);
|
||||
setPtr(raw_ptr, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new intrusive pointer for managing the lifetime of the object
|
||||
* pointed to by @c raw_ptr.
|
||||
*
|
||||
* This overload adds a new reference.
|
||||
*
|
||||
* @param raw_ptr Pointer to the shared object.
|
||||
*/
|
||||
IntrusivePtr(NewRef, pointer raw_ptr) noexcept
|
||||
{
|
||||
setPtr(raw_ptr, true);
|
||||
}
|
||||
|
||||
IntrusivePtr(IntrusivePtr&& other) noexcept : ptr_(other.release())
|
||||
|
@ -69,8 +95,8 @@ public:
|
|||
}
|
||||
|
||||
IntrusivePtr(const IntrusivePtr& other) noexcept
|
||||
: IntrusivePtr(NewRef{}, other.get())
|
||||
{
|
||||
setPtr(other.get(), true);
|
||||
}
|
||||
|
||||
template <class U, class = std::enable_if_t<std::is_convertible_v<U*, T*>>>
|
||||
|
@ -157,7 +183,7 @@ template <class T, class... Ts>
|
|||
IntrusivePtr<T> make_intrusive(Ts&&... args)
|
||||
{
|
||||
// Assumes that objects start with a reference count of 1!
|
||||
return {new T(std::forward<Ts>(args)...), false};
|
||||
return {AdoptRef{}, new T(std::forward<Ts>(args)...)};
|
||||
}
|
||||
|
||||
// -- comparison to nullptr ----------------------------------------------------
|
||||
|
|
|
@ -207,7 +207,7 @@ static IntrusivePtr<EnumVal> lookup_enum_val(const char* module_name, const char
|
|||
|
||||
int index = et->Lookup(module_name, name);
|
||||
assert(index >= 0);
|
||||
IntrusivePtr<EnumVal> rval{et->GetVal(index), false};
|
||||
IntrusivePtr<EnumVal> rval{AdoptRef{}, et->GetVal(index)};
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
|
|
@ -1984,7 +1984,7 @@ void TableVal::CallChangeFunc(const Val* index, Val* old_value, OnChangeType tpe
|
|||
|
||||
try
|
||||
{
|
||||
IntrusivePtr<Val> thefunc{change_func->Eval(nullptr), false};
|
||||
IntrusivePtr<Val> thefunc{AdoptRef{}, change_func->Eval(nullptr)};
|
||||
|
||||
if ( ! thefunc )
|
||||
{
|
||||
|
|
|
@ -792,9 +792,9 @@ static bool data_type_check(const broker::data& d, BroType* t)
|
|||
IntrusivePtr<Val> bro_broker::data_to_val(broker::data d, BroType* type)
|
||||
{
|
||||
if ( type->Tag() == TYPE_ANY )
|
||||
return {bro_broker::make_data_val(move(d)), false};
|
||||
return {AdoptRef{}, bro_broker::make_data_val(move(d))};
|
||||
|
||||
return {caf::visit(val_converter{type}, std::move(d)), false};
|
||||
return {AdoptRef{}, caf::visit(val_converter{type}, std::move(d))};
|
||||
}
|
||||
|
||||
broker::expected<broker::data> bro_broker::val_to_data(const Val* v)
|
||||
|
|
|
@ -1024,7 +1024,7 @@ Supervisor::NodeConfig Supervisor::NodeConfig::FromRecord(const RecordVal* node)
|
|||
|
||||
while ( (v = cluster_table->NextEntry(k, c)) )
|
||||
{
|
||||
IntrusivePtr<ListVal> key{cluster_table_val->RecoverIndex(k), false};
|
||||
IntrusivePtr<ListVal> key{AdoptRef{}, cluster_table_val->RecoverIndex(k)};
|
||||
delete k;
|
||||
auto name = key->Index(0)->AsStringVal()->ToStdString();
|
||||
auto rv = v->Value()->AsRecordVal();
|
||||
|
@ -1100,7 +1100,7 @@ std::string Supervisor::NodeConfig::ToJSON() const
|
|||
{
|
||||
auto re = std::make_unique<RE_Matcher>("^_");
|
||||
auto node_val = ToRecord();
|
||||
IntrusivePtr<StringVal> json_val{node_val->ToJSON(false, re.get()), false};
|
||||
IntrusivePtr<StringVal> json_val{AdoptRef{}, node_val->ToJSON(false, re.get())};
|
||||
auto rval = json_val->ToStdString();
|
||||
return rval;
|
||||
}
|
||||
|
|
|
@ -400,7 +400,7 @@ function terminate%(%): bool
|
|||
// is false).
|
||||
static bool prepare_environment(TableVal* tbl, bool set)
|
||||
{
|
||||
IntrusivePtr<ListVal> idxs{tbl->ConvertToPureList(), false};
|
||||
IntrusivePtr<ListVal> idxs{AdoptRef{}, tbl->ConvertToPureList()};
|
||||
|
||||
for ( int i = 0; i < idxs->Length(); ++i )
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue