I have a bunch of unique_ptrs for database connections. They get checked out by different parts of the code to run database queries, then returned (std::move) back to the container for next use.
I want to keep track of all instances of these unique_ptrs (db connections) by a weak_ptr to close the connections on a termination signal.
When unique pointers are checked out, I don't have a good way to call on all of them to close their connections immediately, since I don't have a link to them. Can I keep track of them by a container of weak_ptrs and access them via that container?
Is is possible to move a weak_ptr reference to a unique_ptr?
I am new to C++. I see other questions on SO, but they are different than what I want to do.
How can I do something like this:
unique_ptr<sql::Connection> conn_to_kill = std::move(weak_ptr_to_connection);
Related
I have been working with boost::asio for a while now and while I do understand the concept of the asynchronous calls I am still somewhat befuddled by the memory management implications. In normal synchrous code the object lifetime is clear. But consider a scenario similar to the case of the daytime server:
There might be multiple active connections which have been accepted. Each connection now sends and receives some data from a socket, does some work internally and then decides to close the connection. It is safe to assume that the data related to the connection needs to stay accessible during the processing but the memory can be freed as soon as the connection is closed. But how can I implement the creation/destruction of the data correctly? Assuming that I use classes and bind the callback to member functions, should I create a class using new and call delete this; as soon as the processing is done or is there a better way?
But how can I implement the creation/destruction of the data correctly?
Use shared_ptr.
Assuming that I use classes and bind the callback to member functions, should I create a class using new and call delete this; as soon as the processing is done or is there a better way?
Make your class inherit from enable_shared_from_this, create instances of your classes using make_shared, and when you bind your callbacks bind them to shared_from_this() instead of this. The destruction of your instances will be done automatically when they have gone out of the last scope where they are needed.
Please note - these builds are for VS2008/VS2010 builds I cannot use any 11 constructs.
Imagine I have subscribers listening to some publisher. My publisher has a container of subscriber pointers. In my void detach(ISubscriber *), instead of locking the subscriber list, I will "NULL" out the pointer, for lack of a better word, for that subscriber.
//My container in the publisher. Inserts to not invalidate, removals only invalidate iterators pointing to the removed element, for this reason we NULL
Container<ISubscriber *> myContainer;
Now in the publisher...
void NotifySubscribers(){
foreach(subscriber in container){
if(subscriber)//This is my problem
subscriber->notify()
}
}
Line 3 - pointer is tested and is pointing to valid object.
Before line 4 is executed, another thread NULLs the subscriber.
Line 4 - Boom.
My Question, is there a way that I can use some sort of Interlocked something such that the test and call is atomic.
e.g. for a reference counted object in the destructor, something like this works
RefCountObject::~RefCountObject(){
if(InterlockedDecrement(&m_count) == 0)
delete m_data;
}
Here, the reference counter is decremented and tested against zero automically, then and only then if equal to zero, the data is released.
Is there a way for me to do this for calling a function based on the validity of a pointer?
Edit 1: I need to clarify a little based on the comments and thank you for your replies. The publisher is not responsible for the "releasing of memory" of the Subscribers, so there will be no leak. After the notify, the publisher will go through a loop that cleans up the container by removing nulled out subscribers.
Now as for the subscribers themselves. When they detach, they are just detaching from listening to the publisher. They themselves will live on in static objects (This is the contract we are requiring). Why? Because we cannot afford to hold a lock during notification. The only other option was to use Share_Ptr, which was decided not to be incorporated into this DLL, due to versioning in the future.
I created a hand written shared_ptr, but then it occurred to me that any reference to an object that was not wrapped in a resource management class would fall into the same pitfall and just push the "requirement" that subscribers would have to make sure to not refer to any dangling references within their implementation of said subscriber.
Which brings us back to just saying, subscribers cannot be "released", and currently all the clients that will use this are static objects. We were just looking towards the future. Some of the users are legacy apps and would not be easy to bring in enabled_shared_from_this etc.
is there a way that I can use some sort of Interlocked something such that the test and call is atomic.
For the test, yes there will be a way. You just want to compare a pointer.
To do the call, i doubt it. You will need a guard around the call, i.e. a Critical Section.
You can use a "smart pointer" strategy to do a deferred nulling of the pointer. As long as someone has a reference to the pointer, as determined by an interlocked reference count, keep the pointer valid; when the count goes to zero it's safe to null.
I have a log system that collects messages in different queues. Also, the system accepts listeners (references to listeners) that system calls to write messages (listeners = consumers). Also, note that the whole log system is a singleton.
My problem is into destructor. You could send messages to different queues, and you can suscribe a listener to listen more than one queue, so every message queue could have a list of listeners. When destructor is called, if a listener is added to two or more queues, destructor try to delete the same listener 2 times (or more).
A dirty solution is to do not delete the listeners (there are few and little and is a singleton, so the leak is little, but I don't like).
Another solution is to maintain another structure to hold all listeners, and delete pointers from this structure instead from the queues. But nothing grants me that two different pointers points to the same listener and the problem would be the same.
I think I need a different solution. Some ideas?
Thanks!!!!
Why don't you just use shared_pointers? They come along with the Boost library (I don't know if they were included in the lastest C++ standard) and it looks that they are exactly what you need.
The shared_ptr class template stores a pointer to a dynamically allocated object, typically with a C++ new-expression. The object pointed to is guaranteed to be deleted when the last shared_ptr pointing to it is destroyed or reset.
See http://www.boost.org/doc/libs/1_48_0/libs/smart_ptr/shared_ptr.htm for more informations.
I have an object (Client * client) which starts multiple threads to handle various tasks (such as processing incoming data). The threads are started like this:
// Start the thread that will process incoming messages and stuff them into the appropriate queues.
mReceiveMessageThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)receiveRtpMessageFunction, this, 0, 0);
These threads all have references back to the initial object, like so:
// Thread initialization function for receiving RTP messages from a newly connected client.
static int WINAPI receiveRtpMessageFunction(LPVOID lpClient)
{
LOG_METHOD("receiveRtpMessageFunction");
Client * client = (Client *)lpClient;
while(client ->isConnected())
{
if(client ->receiveMessage() == ERROR)
{
Log::log("receiveRtpMessageFunction Failed to receive message");
}
}
return SUCCESS;
}
Periodically, the Client object gets deleted (for various good and sufficient reasons). But when that happens, the processing threads that still have references to the (now deleted) object throw exceptions of one sort or another when trying to access member functions on that object.
So I'm sure that there's a standard way to handle this situation, but I haven't been able to figure out a clean approach. I don't want to just terminate the thread, as that doesn't allow for cleaning up resources. I can't set a property on the object, as it's precisely properties on the object that become inaccessible.
Thoughts on the best way to handle this?
I would solve this problem by introducing a reference count to your object. The worker thread would hold a reference and so would the creator of the object. Instead of using delete, you decrement from the reference count and whoever drops the last reference is the one that actually calls delete.
You can use existing reference counting mechanisms (shared_ptr etc.), or you can roll your own with the Win32 APIs InterlockedIncrement() and InterlockedDecrement() or similar (maybe the reference count is a volatile DWORD starting out at 1...).
The only other thing that's missing is that when the main thread releases its reference, it should signal to the worker thread to drop its own reference. One way you can do this is by an event; you can rewrite the worker thread's loop as calls to WaitForMultipleObjects(), and when a certain event is signalled, you take that to mean that the worker thread should clean up and drop the reference.
You don't have much leeway because of the running threads.
No combination of shared_ptr + weak_ptr may save you... you may call a method on the object when it's valid and then order its destruction (using only shared_ptr would).
The only thing I can imagine is to first terminate the various processes and then destroy the object. This way you ensure that each process terminate gracefully, cleaning up its own mess if necessary (and it might need the object to do that).
This means that you cannot delete the object out of hand, since you must first resynchronize with those who use it, and that you need some event handling for the synchronization part (since you basically want to tell the threads to stop, and not wait indefinitely for them).
I leave the synchronization part to you, there are many alternatives (events, flags, etc...) and we don't have enough data.
You can deal with the actual cleanup from either the destructor itself or by overloading the various delete operations, whichever suits you.
You'll need to have some other state object the threads can check to verify that the "client" is still valid.
One option is to encapsulate your client reference inside some other object that remains persistent, and provide a reference to that object from your threads.
You could use the observer pattern with proxy objects for the client in the threads. The proxies act like smart pointers, forwarding access to the real client. When you create them, they register themselves with the client, so that it can invalidate them from its destructor. Once they're invalidated, they stop forwarding and just return errors.
This could be handled by passing a (boost) weak pointer to the threads.
So I have a container(any kind, probably std::map or std::vector) which contains objects of a class with some network thing running in a thread that checks if it is still connected (the thread is defined inside that class and launches when constructed).
Is there any way I can make the object delete itself from the container when its disconnected or should I move the thread outside the object and use that class just to store data?
In order for the object to delete itself from the container, it will have to know which container it is in. You will need to maintain a pointer to the container in the object. You will also have to protect the container with a lock to stop multiple threads accessing the container at the same time.
I think I prefer your second solution - some managing object looks after removing dead objects from the collection. If nothing else, this will be quite a bit easier to debug and the locking logic becomes centralised in a single object.
I would have am unload queue.
When a thread notices that the connection is down it registers the object (and continer) with the unload queue tides everything up as much as possible then the thred terminates.
A separate thread is then inside the unload queue. Its sole purpose is to monitor the queue. When it sees a new object on the queue, remove it from the container and then destroy it (syncing with the objects thread as required).
STL containers tend to assume they're storing values; objects that can be copied and where copies are identical. Typically, objects which have threads fit poorly into that model. They have a much stronger sense of identity. In this case, you definitely have indentity - a copy of the object in a container is distinct from a copy outside.
I had a problem very similar to yours, which I solved by emitting a boost::signal from the "network thing" when it detected the disconnection, being caught by the object managing the container. Upon receiving that signal, it would iterate through the container, removing the dead network session from it. It might be worth looking at it here:
How to make a C++ boost::signal be caught from an object which encapsulates the object which emits it?
Cheers,
Claudio