Skip to content

Improve hsRef and simplify ref management in a few places#1872

Open
dgelessus wants to merge 16 commits into
H-uru:masterfrom
dgelessus:simplify_safe_refs
Open

Improve hsRef and simplify ref management in a few places#1872
dgelessus wants to merge 16 commits into
H-uru:masterfrom
dgelessus:simplify_safe_refs

Conversation

@dgelessus
Copy link
Copy Markdown
Contributor

@dgelessus dgelessus commented May 8, 2026

Replaces hsRefCnt_Safe[Un]Ref calls by direct calls to Ref/UnRef if it's clear from context that the pointer cannot be null - because it was already checked, or because it comes directly from new, or because the code path already assumes that the pointer is not null.

This fixes some false positive warnings in CLion about missing null checks - CLion takes the null check inside the "safe" macros as an indication that the pointer can indeed be null, and then warns about any other uses of the same pointer variable without an explicit null check.

That is, call Ref/UnRef directly if it's clear from context that the
pointer cannot be null - because it was already checked, or because it
comes directly from new, or because the code path already assumes that
the pointer is not null.

This fixes some false positive warnings in CLion about missing null
checks - CLion takes the null check inside the "safe" macros as an
indication that the pointer can indeed be null, and then warns about any
other uses of the same pointer variable without an explicit null check.
Copy link
Copy Markdown
Member

@Hoikas Hoikas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is fine, but I wonder if we should take this as an opportunity to use hsRef instead. There are several places where we have vectors of hsRefCnt and hsRefCnt members that we're manually performing the ref count management on, and I think changing those to hsRef would be a good code quality improvement.

Comment on lines 169 to -170
animMsg->AddCallback(eventMsg);
hsRefCnt_SafeUnRef(eventMsg); // AddCallback adds it's own ref, so remove ours (the default of 1)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's quite a bit of this anti-pattern repeated. I wonder if it would make more sense to change AddCallback to accept an hsRef and change all of these call sites to create an hsRef of whatever message is being sent as the callback and std::move it as the callback. That's potentially a larger change though, and I don't think that should be a requirement.

Copy link
Copy Markdown
Contributor Author

@dgelessus dgelessus May 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm wary of using hsRef with messages in particular, because then calling msg->Send() as usual will cause a double unref - you have to remember to use msg->SendAndKeep() instead. Which is unfortunate, because hsRef would definitely be useful for non-straightforward message fiddling code.

I wonder if we should add a dedicated plMessageRef class with its own Send method that automatically nulls out the ref after sending. Sadly, that still doesn't prevent you from calling msg->Send() (wrong) instead of msg.Send() (correct).

dgelessus added 11 commits May 9, 2026 03:03
No longer using hsRefCnt - that was only needed to support sharing the
global plAccessGeometry with external DLLs, which isn't used by
anything. All non-global plAccessGeometry instances were already not
refcounted.
And ensure that all fields are initialized. Previously, fCommand and
fPageID were left uninitialized by the overloads without a corresponding
parameter.
@dgelessus
Copy link
Copy Markdown
Contributor Author

Yes, hsRef would definitely be the nicer solution in many cases. I've changed some of the raw pointers to hsRef/hsWeakRef, in a few places where it doesn't require too many changes. I'm not going to hsRef-ify everything touched by this PR, otherwise I'd be busy for a while with the rendering pipelines :D

// Remove ourselves from the stack
plInputIfaceMgrMsg *msg = new plInputIfaceMgrMsg( plInputIfaceMgrMsg::kRemoveInterface );
msg->SetIFace( this );
msg->SetIFace(hsRef<plInputInterface>(this));
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The implicit conversion from a raw pointer to hsRef doesn't seem to work if the raw pointer points to a subclass of the expected class. Adding an explicit constructor call like this fixes it for some reason (I'm calling exactly the type expected by the method).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I fixed this by adding an explicit hsRef(_Ref* copy) constructor overload. That works even if the pointer type doesn't match exactly (unlike the indirect conversion via hsWeakRef that was previously used here).

Comment thread Sources/Plasma/PubUtilLib/plMessage/plInputIfaceMgrMsg.h
@dgelessus dgelessus changed the title Simplify hsRefCnt_Safe[Un]Ref calls where possible Improve hsRef and simplify ref management in a few places May 15, 2026
@dgelessus dgelessus force-pushed the simplify_safe_refs branch from 3845898 to e322cd9 Compare May 15, 2026 22:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants