Based on work trying to clean up Coverity issues, we have run in to pattern 
that looks like this 


X x = alloc_some_resource();

if (! cond1) { Log("error"); destroy(x); return FAIL; }
if (! cond2) { Log("error"); destroy(x); return FAIL; }
// ... etc ...

return x;


The problem is that frequently not every return case cleans up every resource 
and so resources are leaked. There is an existing class, xptr, in 
lib/ts/ink_memory.h which handles this for some cases. It is a container for a 
single resource which cleans up the resource if the container goes out of 
scope. That means any return will clean up the resource without having any 
explicit code. In addition it permits the resource to be removed from the 
container if it is needed after all of the contingent checks have been done.

The modified code would look like


scoped_X x = alloc_some_resource();

if (! cond1) { Log("error"); return FAIL; }
if (! cond2) { Log("error"); return FAIL; }
// ... etc ...

return x.release();

This is very handy when the checks are not nicely lined up like this but 
convoluted and non-obvious.

The decision at the HackAThon was made that we should have a more general 
version of this that (1) handled more types of resources and (2) had better 
naming.

I have created issue TS-2943 to track this and have attached my proposed patch. 
This creates a base implementation class and specialized subclasses for 
specific resource types. This should allow easily extending this support for 
other types as needed.

The base implementation class is scoped_resource<T,D> where T is the resource 
type and D is a descriptor class that describes how to deal with a resource of 
type T. From this I have built three more usable classes

ats_scoped_fd - holds a file descriptor, closes it if it goes out of scope.

ats_scoped_mem - holds a pointer to memory that is either an array or a class 
instance, created by ats_malloc. ats_free is called on the pointer if the 
container goes out of scope.

ats_scoped_obj - holds a pointer to a class instance created with new. delete 
is called on the pointer if the container goes out of scope.

This is very similar to std::unique_ptr but unfortunately that is a C++ 
eleventy feature which we cannot, at this time, require.

Reply via email to