shared, weak and lazy pointers in C++ - c++

Is anyone aware of an implementation of shared_ptr and weak_ptr together with a lazy initialization partner? The requirements of the classes were:
A lazy_ptr class that allows a client to construct the object later (if at all), without needing the constructor implementation
A weak_lazy_ptr class that has three possible states: not yet constructed (won't lock to a shared_ptr), constructed (will lock to a shared_ptr) and destroyed (won't lock to a shared_ptr)
I created some classes that didn't do the job completely a while ago (see CVu article here) that used shared_ptr and weak_ptr in their implementation. The main problems with a model that USES shared and weak pointers instead of integrating with them follow:
Once all lazy_ptr objects go out of scope, any weak references can no longer be locked, even if other clients are holding shared_ptr versions
Construction of objects on different threads can't be controlled
I'd appreciate any pointers to other attempts to reconcile these problems, or to any work in progress there may be in this area.

To create deferred construction that requires no parameters:
boost::bind( boost::factory<T*>(), param1, param2 ) will create a function object that performs the equivalent of new T(param1, param2) without needing the parameters at the time of construction.
To create a shared_ptr that supports this deferred construction:
Bundle your factory with the standard boost::shared_ptr (in a class of your creation, for example), and you'llget the results you describe, including the appropriate weak_ptr functionality...
Whatever code triggers the deferred construction by the client should run:
your_shared_ptr.reset( your_factory() );
Whatever code triggers the object's destruction should run:
your_shared_ptr.reset();
The shared pointer will evauluate to true only during the object's lifetime. And if you want you differentiate "not yet constructed" from "destroyed", you can set a bool after the factory is run.

Related

Swig: simple idiomatic wrapper usage when weak_ptr are used?

note: this question is related to weak_ptr usage, but is not about wrapping weak_ptrs.
I am currently evaluating Swig and I have found an "inconvenience" in the usage of the wrappers by the client languages, that I have not found described online and for which I have no satisfactory solution.
In C++ if you have a complex graph of objects that are managed using shared_ptrs, you must take special care when the graph can have a cycle (i.e. if it is not a DAG) or else you will get memory leaks. By that I mean that if you must (cannot avoid) to have a cycle, it must contain at least one weak_ptr. This means that you will have to handle the cases where you cannot lock the weak_ptr, because the related shared_ptr has died. This management is something that one can expect C++ programmers to be used to deal with. Now let's look at what can happen for a user of the wrappers:
So let's take the following example:
object a, held by a shared_ptr, has a shared_ptr to b
object b, held by a shared_ptr, has a weak_ptr to a
The following could happen to a user of the wrapper:
A a
B b = a->GetB()
// here let's suppose that a gets out of scope, so it can be garbage collected
b->GetA() // fails if a has been garbage collected
The failure could be cleanly managed by propagating a C++ exception to the client code (throw if cannot lock the weak_ptr to create a shared_ptr). However this is not idiomatic to Python/C#/Java users: they do not except to have to manually keep some objects alive to access others.
I have a draft of a an alternative solution which involves creating a C++ "Co-Owner" of objects a and b that would be locked by the SWIG wrappers when any of a or b are accessed via the wrappers, thus keeping both a and b alive when any of them is accessed via the wrappers. The downsides are that this starts to look like I am implementing a proto-garbage-collection in C++, also this modifies the C++ implementation & API of objects a & b and finally the objects a & b will have to be notified by the wrappers that they are used via the wrappers (not something I think I can do without patching SWIG to add function calls in constructor and destructor of shadow objects ??).
Have I missed anything ? Is there another solution to this problem ?
Publicly available weak pointers
If weak ownership is actually part of the interface, it is possible to bind extra types manually that exhibit the behavior of weak pointers. In this example they create a type FooWeakPtr providing the relevant interface. But as you can see, this is not taking advantage of the language-specific classes in every language.
Internal weak pointers
If the weak pointers are not part of the interface, then SWIG-generated bindings should not care about them, and treat the bound objects as shared pointers (at least in Python and Java). Therefore, for as long as your objects are available from the other language, you must make sure they all stay alive.
That means it is up to you to design your hierarchy of objects in a way that clients can never face a case where an internal weak pointer is invalid, and that dropping every reference actually leads to the destruction of the hierarchy.
The solution actually resides in the details of your object hierarchy, and SWIG cannot do much about it.

How to deal with Resource-waiting in RAII

I'm new to C++, and I'm currently learning the RAII (Resource Acquisition is Initialization) pattern.
I was curious how one would deal with resources that they needed to wait on.
In Java, something that might be done is:
MyClass obj = new MyClass();
new Thread(
() -> obj.initialize(); // resource acquisition
).start()
...
if (obj.initialized()) {
// Use object
}
In other words, we can perform a time-intensive resource-acquisition in the background.
How can we do that in C++, with RAII? Or is this a limitation with RAII?
RAII means that resources are defined by some object. Ideally, the constructor of that object gets the resource, and the destructor releases it. During the time when the object is valid, you can use the object to interact with the resource.
If a resource "needs to be waited on", then by the rules of RAII, that means you don't have an object that represents that resource yet. You instead have an object that represents a resource that will be available in the future.
Which is why C++ calls this type std::future. It's a template, with the argument being the type of the object whose creation you are waiting on.
Conceptually, a future is just a means to forward an object (or exception) from the piece of code that generates it (possibly asynchronously) to the receiver.
Now given your example, we need to remove initialize from MyClass and make that a function which returns a MyClass instance. It could be a static member of MyClass, or it could be just a namespace-scoped function.
So the code would essentially look like this:
auto future = std::async(initialize);
...
if(future.wait_for(std::chrono::seconds(0)) == std::future_status::ready)
{
MyClass resource = future.get(); //The `future` is now empty. Any exceptions will be thrown here.
//use resource
}
RAII addresses an antipattern when it's possible to obtain an object that is not yet ready for use. In particular, your Java code suffers from the same antipattern - it's easy for a user of MyClass to forget to run the initialize method immediately after constructing the object.
The easiest way to enforce RAII when complex initialization needs to happen is via a factory method. Make the potentially unsafe constructor private and expose a public static function that will construct and initialize the object for you. In particular, if you want to run the initialization concurrently, there is nothing stopping you from making the return type of that factory method into an std::future or similar.
The key takeway is the purpose of RAII - it must not be possible to acquire a resource that is not initialized. By making the only way to acquire into a function that always initializes the resource, you get RAII.

Managing the lifetime of member functions bound by `std::bind`

I am currently experimenting with writing an event queue in C++11. I am using std::bind to obtain std::function objects which are called when certain events happen. The code for this roughly looks like this:
class A
{
public:
void handle();
};
class B { ... };
// Later on, somewhere else...
std::vector< std::function< void() > functions;
A a;
B b;
functions.push_back( std::bind( &A::handle, &a ) );
functions.push_back( std::bind( &B::handle, &b ) );
// Even later:
for( auto&& f : functions )
f(); // <--- How do I know whether f is still "valid"?
Is there any way to guarantee the validity of the function object so that I can avoid stumbling over undefined behaviour here?
I have already taken a look at this question here, std::function to member function of object and lifetime of object, but it only discussed whether deleting a pointer to a bound object raises undefined behaviour. I am more interested in how to handle the destruction of such an object. Is there any way to detect this?
EDIT: To clarify, I know that I cannot guarantee a lifetime for non-static, non-global objects. It would be sufficient to be notified about their destruction so that the invalid function objects can be removed.
As #Joachim has stated, no lifetime is associated to the member function (it's a code section, not data). So you're asking if there is a way to know if the object still exists prior to execute the callback call.
You've to make a sort of framework, where the object dctor notify the container when it is destroyed, so the container could delete it from its "observers", the vector containing all the objects. To do that, the object must memorize in its instance the ptr to the container.
UPDATE
#Jason talks about the use of shared_ptr. It's okay to use them, but in this case, is not addressing the case of HOW to destroy the object linked in other object-notification list. Shared_ptr postponed the destruction of an instance until all "managed" references to it are deleted. But if you need to destroy object A, AND delete all reference to it because that object MUST be deleted, you've to look into all containers that store a shared_ptr and remove it. A very painful activity. The simplest solution (using raw ptr or shared_ptr, if you can use them, is irrelevant) is a two-link connection between the observer and the observed, in such way each one can notify its destruction to the other. How to store this information? many ways to accomplish it: hash tables, slots in observer, etc
One hack/workaround that achieves the desired result would be to use a parameter of type std::shared_ptr. When the bind is destructed, so is the shared pointer - which will do the right thing when it is the last reference. However this involves changes to the signature used. To make it slightly less awkward, you can use static methods that take in a std::shared_ptr this - sort of like the self parameter concept in python, if you are familiar.
Or if you are fine with C++11, you can just use a lambda capture of the shared pointer.
You'd need to dynamically allocate the instances to use this method.

Applying RAII outside the scope of a single (member) function

I have a singleton "manager" object which gets instantiated at process-start and lives for the duration of the process (effectively).
This object creates multiple temporary tasks (which are themselves objects) during it's lifetime, using "new" and later destroys them with "delete". These two operations are carried out in two different functions - one function is called by external objects to perform a specific task, the other function is a callback that is called when the task has been completed, hence the task object is then destroyed.
Due to the fact that the task objects are not created/destroyed in a scope that is "temporary" (e.g. a single member function), am I wasting my time trying to apply RAII in this instance? Or is there a mechanism I should be using to deal with this?
Regards,
Richard.
You could use smart pointers (e.g. shared_ptr). The singleton should hold a container of pointers to these tasks (e.g. a map), and remove it from the vector when completed.
For example (not compiling, just for illustration):
class MySingleton
{
typedef std::shared_ptr<Task> TaskPtr;
std::map<int, TaskPtr> m_tasks;
StartTask()
{
TaskPtr task = std::make_shared<Task>();
m_tasks[index] = task;
...
}
OnTaskEnd()
{
TaskPtr task = m_tasks[index];
m_tasks.remove(index);
taskCompletedHandler(task);
// Unless taskCompletedHandler copies task, it will be destroyed when this leaves scope.
}
Your pointer to sub tasks is stored somewhere between the first creating and second destroying function.
Change that pointer to a unique_ptr and it will reflect the fact that it owns the lifetime of the resource. Documenting ownership with types, prevents resource handle duplication, and can make your code more safe.
A more advanced technique would be to replace the 'return resource' stage entirely with RAII. Return a unique_ptr to some dqta or token from the crearion function that implicitly calls the destroying function when reset: push the RAII up a level of abstraction. Rhis is not always easy, desireable or useful, but is still worth considering.

boost shared_from_this<>()

could someone summarize in a few succinct words how the boost shared_from_this<>() smart pointer should be used, particularly from the perspective of registering handlers in the io_service using the bind function.
EDIT: Some of the responses have asked for more context. Basically, I'm looking for "gotchas", counter-intuitive behaviour people have observed using this mechanism.
The biggest "gotcha" I've run into is that it's illegal to call shared_from_this from the constructor. This follows directly from the rule that a shared_ptr to the object must exist before you can call shared_from_this.
From my understanding, sometimes in your code you want a class to offer up shared_ptr's to itself so that other parts of your code can obtain shared_ptr's to an object of your class after it has been constructed.
The problem is that if your class just has a shared_ptr<> to itself as a member variable, it will never get automatically destructed, since there is always "one last reference" hanging around to itself. Inheriting from enable_shared_from_this gives your class an automatic method which not only returns a shared_ptr, but only holds a weak shared pointer as a member variable so as not to affect the reference count. This way, your class will be freed as usual when the last reference to it is gone.
I've never used it, but this is my understanding of how it works.
shared_from_this<> is used if an object wants to get access to a shared_ptr<> pointing to itself.
Usually an object only knows about the implicit this pointer, but not about any shared_ptr<> managing it. Also, this cannot easily be converted into a shared_ptr<> that shares ownership with other existing shared_ptr<> instances, so there is no easy way for an object to get a valid shared_ptr<> to itself.
shared_from_this<> can be used to solve this problem. For example:
struct A : boost::enable_shared_from_this<A> {
server *io;
// ...
void register_self() {
io->add_client(shared_from_this());
}
};
the boost::asio::io_service destructor documentation explains it fairly well
The destruction sequence described
above permits programs to simplify
their resource management by using
shared_ptr<>. Where an object's
lifetime is tied to the lifetime of a
connection (or some other sequence of
asynchronous operations), a shared_ptr
to the object would be bound into the
handlers for all asynchronous
operations associated with it. This
works as follows:
When a single connection ends, all associated asynchronous operations
complete. The corresponding handler
objects are destroyed, and all
shared_ptr references to the objects
are destroyed.
To shut down the whole program, the io_service function stop() is called
to terminate any run() calls as soon
as possible. The io_service destructor
defined above destroys all handlers,
causing all shared_ptr references to
all connection objects to be
destroyed.
Typically your objects will chain asynchronous operations where the handlers are bound to member functions using boost::bind and boost::shared_from_this(). There are some examples that use this concept.
Stuff is missing from some of the comments above. Here's an example that helped me:
Boost enable_shared_from_this example
For me, I was struggling with errors about bad weak pointers. You HAVE to allocate your object in a shared_ptr fashion:
class SyncSocket: public boost::enable_shared_from_this<SyncSocket>
And allocate one like this:
boost::shared_ptr<SyncSocket> socket(new SyncSocket);
Then you can do things like:
socket->connect(...);
Lots of examples show you how to use shared_from_this() something like this:
boost::asio::async_read_until(socket, receiveBuffer, haveData,
boost::bind(&SyncSocket::dataReceived, shared_from_this(), boost::asio::placeholders::error));
But was missing for me was using a shared_ptr to allocate the object to begin with.