What alternatives does one have to the following code for performing safe asynchronous callbacks on an object?
class MyClass : public std::enable_shared_from_this<MyClass>
{
private:
void fetchResults()
{
std::weak_ptr<MyClass> weakSelf = shared_from_this();
m_service.getResultAsync(
/* args... */,
/* Callback */
[weakSelf](Result r)
{
auto self = weakSelf.lock();
if (self)
{
self->workFinishedWithResult(std::move(r));
}
});
}
void workFinishedWithResult(Result r) { // ... continue workflow }
std::shared_ptr<Service> m_service;
};
I would like to avoid using enable_shared_from_this (and avoid clients of m_service requiring it for what is a very common use case), but it seems difficult to extend the lifetime of MyClass once inside the callback without it.
Capturing this in the lambda instead and trying to deregister it in MyClass' destructor, or preventing MyClass from being destructed until the callback is finished is a path that leads to races, deadlocks and a loss of simplicity. I'm almost certain that capturing 'this' can't be made safe.
It seems if MyClass is asking a shared_ptr<Service> to call it back, it can only guarantee that it remains valid if it can manage or extend its own lifetime (via enable_shared_from_this) since it doesn't know how long the callback will live for. Otherwise it would have to be the responsibility of whoever owns MyClass, or whoever knows the lifetime of both the Service and MyClass to deal with this, but it all becomes very error-prone and impractical.
It seems the only viable solutions are:
Use enable_shared_from_this with the "capture weakly" pattern (as in the above code)
Have MyClass be given a Service& so it is the caller's responsibility to ensure the service outlives it.
Use a static method/function as the callback and pass everything it needs in by-value (problem is that sometimes you really do want to pass control back into MyClass and you have the same problem).
What are the alternatives here? Or does using enable_shared_from_this just become inevitable when doing async C++?
The exact thing that you're looking for would be std::future<T>::then(). It does not exist in C++11, but boost::future offers it.
However, in the general case, it would be the responsibility of the caller to ensure that the service and MyClass instances live long enough, although it would be also acceptable if the method takes an owning reference to the service.
Related
Using async I/O operations from boost::asio I often need shared pointers (and enable_shared_from_this and shared_from_this in callbacks) to avoid deleting objects too early.
I think that it could be done by keeping unique_ptr or just object (ownership) in class (as a member)
For example:
Only foo method use sender.
1st (popular solution):
class C {
public:
void foo
{
std::shared_ptr<Sender> sender = std::make_shared<Sender>();
sender->send();
// class Sender use async_write
// inheritance: enable_shared_from_this
// callback in async operation created with argument shared_from_this
}
};
Why nobody(?) use this solution:
class D {
public:
void foo
{
sender.reset(new Sender);
sender->send();
}
private:
std::unique_ptr<Sender> sender;
};
I know that sender will not be deleted to early. I have no shared_ptrs. I think it's good to avoid them because if callback in Sender class also use async operations I need another shared pointers etc. I think that class D is more friendly to read.
But I wonder if it's a good style... and I always see solution with shared_ptrs in the net.
You can only have one unique_ptr to an object. What happens if you have both a send and a receive operation pending? What happens if you have both a receive operation and a timer?
Yes, you could use a unique_ptr, but then you'd have to implement your own count of the number of outstanding operations. You'd have to increment and decrement that count in a thread-safe way. And you'd have to constantly check if that count was zero to invoke the destructor. To clean this up, you'd likely bundle all this functionality into its own class. And you'd have reinvented shared_ptr.
The latter usage is fragile and makes no guarantee that the sender will not be deleted too early. For instance, consider the case where D::foo() is called consecutively, before the asynchronous operations have completed. The previous Sender object could be deleted with outstanding operations that may depend on the Sender object:
public: Sender
{
public:
void send()
{
boost::asio::async_write(socket_, boost::asio::buffer(buffer_), ...);
}
private:
std::array<char, 64> buffer_;
boost::asio::ip::tcp::socket socket_;
...
};
D d;
d.foo(); // Create Sender1, initiate async_write.
d.foo(); // Delete Sender1, create Sender2, initiate async_write.
io_service.run(); // Sender1's async_write invokes undefined behavior.
In the above code, the second call to d.foo() will delete the first Sender object that has outstanding operations, resulting in undefined behavior. On the other hand, if Sender inherits from enable_shared_from_this, and the result of shared_from_this() is bound to the handlers for asynchronous operations, then the Sender object's lifetime would extend to be at least as long as the operations.
Have you looked at asio::spawn? Basically, it takes most of the complexity out of async C++ programming, and allow you to just put your objects on the stack.
Here is a simple example: modern.cpp
Using this approach saves a lot of time implementing and debugging an async application, and it makes the code really easy to understand. (I once implemented a RTP over TCP proxy, using traditional callbacks. It turned out to be a nightmare to maintain later on).
Regarding shard versus unique pointers - my experience is that shared pointers are simpler to use with asio. There were some problems moving unique pointers around, and when the program becomes slightly complex, it's really easy to make mistake mistakes. I think I would stick with shared and weak pointers as default - and only switch to unique pointers for objects where the profiler outputs suggests that it's worth the while.
I'm working with code, which has a lot of observer pattern implementations. All of them are organized in such a manner:
Some interface to be implemented by observers:
class ObserverInterface {
virtual void FooOccurs() = 0;
};
Some class, which implements Register, Unregister and notifications:
class ObservableImpl {
public:
Register(ObserverInterface *observer);
Unregister(ObserverInterface *observer);
private:
void SomeMethod() {
// foo things
for(auto &observer: observers) {
observer.FooOccurs();
}
}
};
Every time there is a copy-paste of Register and Unregister as well as implementation of notification for each method of ObserverInterface. And every time a programmer has to remember about calling Unregister(), if its observer is going to be destructed.
I wish to enclose the observer pattern in two class templates. So far I've got something like that:
http://rextester.com/UZGG86035
But I'm not sure if I'm not reinventing the wheel. Are there any easier, commonly known approach to do that?
In C++11, I'd advise a token-based approach.
You register an observer. An observer is just a std::function<void(Signature...)>.
The registration function return a token, a std::shared_ptr<void>. So long as that returned shared_ptr is valid, the broadcaster will continue to broadcast to that listener.
The listener is now responsible for maintaining that std::shared_ptr lifetime.
Inside the broadcaster, you hold a weak_ptr and .lock() it before broadcasting. If I don't really need to unregister (usually I do not), I lazily clean up my list of weak_ptrs. Otherwise, I the shared_ptr I return has a deletion function that does the unregistration.
Alternatively, your listeners are shared_ptr<std::function<void(Args...)>>, and internally you store weak_ptr to same.
In this model, you cannot inject an unregistraiton function easily. However, it does mean they can use the aliasing constructor themselves to tightly bind the lifetime of the callback to themselves, assuming they are managed by a shared_ptr.
In my experience, simply having listeners maintain a std::vector<token> is sufficient. If they have a more complex listening relationship they can do more work, maintaining keys and the like.
Hybrid models are also possible.
Both of these are acceptable for not-thread-safe broadcasting, and can be written in a few dozen lines of code.
Thread-safe broadcasting gets tricky. Often I find you are better off using a message-passing pattern for this rather than the alternatives, as this reduces the difficulty in reasoning about concurrency slightly.
This also doesn't deal with situations where you want to register listeners willy-nilly, and broadcaster and listener lifetime is like popcorn.
I have to following code:
class Timer;
typedef boost::signals2::signal<void (void)> signal_type;
void Timer::create(long expiration, signal_type::slot_type const& slot);
The normal usage of that is to call,
timer.create(2000, boost::bind(&some_callback));
and that works correctly.
However, now I need to 'restart' this timer a lot, which would require a lot of calls to boost::bind(&some_callback) -- I don't want to do that because that seems a waste of CPU.
I would like to do the call to boost::bind once and then reuse whatever it returned on subsequent call to the create() function. I'm not sure if this can work though. I can imagine that it will leak memory and worse, use freed memory and crash or something.
I think that the above should be sufficient information to give a general answer, but let me add information about what this 'create' function exactly does.
The effect of calling create() is that an object 'Signal' is created with new,
where Signal is:
struct Signal {
signal_type mSignal;
};
and then mSignal is connected to the slot value passed to create:
mCallback = new Signal;
mCallback->mSignal.connect(slot);
When I have to 'restart' the timer (before it expires), I first call
a cancel() function, and then call create() again. The function cancel()
effectively calls 'delete mCallback' - so, doesn't do anything else
than freeing the memory allocated by the 'new' call above.
Hence, I guess that storing the return value of boost::bind and repeatedly using it effectively comes down to:
signal_type::slot_type slot(boost::bind(&callback));
while (--several_times)
{
signal_type* signal = new signal_type;
signal->connect(slot);
delete signal;
}
Is that allowed, or do the calls to 'connect' and delete do something to 'slot' so I can't reuse it without side effects?
In general,
bind expressions are pretty lightweight (the compiler would usually inline the whole shebang)
bind expressions do copy their bound parameters, but this is easily mitigated doing boost::bind(&MyClass::fpp, boost::ref( object))
boost::function<> and std::function<> are ideally suited to storing bound expressions:
boost::function<void()> stored_bind =
boost::bind(&MyClass::fpp, boost::ref(object));
Recently I am following the tutorials on rastertek and find that they suggest use a Shutdown() method for cleaning up instead of the class own destructor.The reason they mention is that the destructor is not guaranteed to be executed when calling some unsafe function like ExitThread().
However, I doubt if that method would get executed when even the destructor cannot be called. Indeed you can always call Shutdown() before you call ExitThread() but why not the same for the destructor? If I can do something before calling ExitThread(), I can certainly call the destructor as well.
Isn't placing the clean up code in the destructor more or less safer than using another method to do the trick? I know that releasing some vital resources like closing a file may need this separate method to do the trick. But are there any reasons other than that since this does not seem to be the case in the tutorials?
For the record, I know there is a similar question out there. But that one got no answer.
Isn't placing the clean up code in the destructor more or less safer than using another method to do the trick?
The problem here is that while ExitThread (and other functions like it) is a perfect API for C, with C++ code, it breaks stack unwinding.
The correct solution for C++ is to make sure you do not call ExitThread (and such) in code using anything with destructors.
Problem:
void thread_function()
{
raii_resource r { acquire_resource() };
ExitThread();
// problem: r.~raii_resource() not called
}
The shutdown solution:
void thread_function()
{
raii_resource r { acquire_resource() };
r.shutdown(); // release resources here
ExitThread();
// r.~raii_resource() still not called
}
The shutdown solution is not obvious at all in client code. As #stefan said, kill it with fire.
Better solution (than the Shutdown thing):
void thread_function()
{
{ // artificial scope where RAII objects live
raii_resource r { acquire_resource() };
}
// this space does not support RAII life
ExitThread();
}
RAII works fine here, but the artificial scope is not very elegant. On top, it's as inelegant as the shutdown solution (it requires a non-obvious artifice in client code).
Better (cleaner) solution:
template<typename F>
void run_thread(F functor)
{
functor(); // all RAII resources inside functor; this is simple and
// obvious from client code
ExitThread();
}
The only advantage to moving initialization out of the constructor, and for removing cleanup out of the destructor is when you've got a base class framework where you want to reliably call virtual methods during these stages.
Since the vtable is changing during construction/destruction calls to virtual functions don't resolve to the most derived instance. By having explicit Initialize/Shutdown methods you can be sure the virtual functions dispatch correctly.
Please note, this isn't an answer that advocates this approach, just one that is trying to work out why they've suggested it!
destructors are guaranteed to be called when an object is destroyed however thread clean up can require a tad more than just object destruction. Generally speaking cleanup methods are added when you need to handle releasing of shared resources, dealing with ancient libraries, etc.
Specifically you're dealing with the Win32 API which qualifies as an ancient c-style library considering ExitThread has been around longer than I have ...
With such approach you'll need to call Shutdown in all cases where the object should be destroyed - each time when it leaves the scope. In the case of exceptions (if they are used) you'll cannot call it. Destructor will be called automatically in these cases.
"I can certainly call the destructor as well" - calling the destructor explicitly is highly not recommended because it will be called automatically in any case. This should be avoided except only in special cases. If you mean this code from the tutorial:
System->Shutdown();
delete System;
then I don't see the difference because delete System; will call the destructor anyway.
In any case I would prefer
{
// work with System
...
}
mentioned in #utnapistim answer. I do not see any minuses in such way of coding, and also it is common way to specify scope. Even not going deep in the details of legacy ::ExitThread you gain auto cleanup. It is possible to work with WinApi with C++ RAII technique, look for instance at my code: multithreading sample project. Initial commit was bare WinAPI, and next commit introduced resource wrappers. You can compare both variants - second is much clearer, imho.
I would like to create a singleton class that is instantiated once in each thread where it is used. I would like to store the instance pointers in TLS slots. I have come up with the following solution but I am not sure whether there are any special considerations with multithreaded access to the singelton factory when thread local storage is involved. Maybe there is also a better solution to implement thread local singletons.
class ThreadLocalSingleton
{
static DWORD tlsIndex;
public:
static ThreadLocalSingleton *getInstance()
{
ThreadLocalSingleton *instance =
static_cast<ThreadLocalSingleton*>(TlsGetValue(tlsIndex));
if (!instance) {
instance = new ThreadLocalSingleton();
TlsSetValue(tlsIndex, instance);
}
return instance;
}
};
DWORD ThreadLocalSingleton::tlsIndex = TlsAlloc();
The Tls*-functions are of course win32 specific but portability is not the main issue here. Your thoughts concerning other platforms would still be valuable.
Major Edit: I had originally asked about using double-checked locking in this scenario. However as DavidK pointed out, the singletons are to be created on a per thread basis anyway.
The two remaining questions are:
is it appropriate to reply on TlsGetValue/TlsSetValue to ensure that each thread gets one instance and that the instance is created only once for each thread?
Is it possible to register a callback that allows me to clean up an instance that was associated with a particular thread when that thread finishes?
Since your objects are thread-local, why do you need locking to protect them at all? Each threads that calls getInstance() will be independent of any other thread, so why not just check that the singleton exists and create it if needed? The locking would only be needed if multiple threads tried to access the same singleton, which isn't possible in your design as it is above.
EDIT: Moving on to the two other questions... I can't see any reason why using TlsAlloc/TlsGetValue etc. wouldn't work as you'd expect. Since the memory holding the pointer to your singleton is only accessible to the relevant thread, there won't be any problems with a lazy initialization of it. However there's no explicit callback interface to clean them up.
The obvious solution to that would be to have a method that is called by all your thread main functions that clears up the created singleton, if any.
If it's very likely that the thread will create a singelton, a simpler pattern might be to create the singleton at the start of the thread main function and delete it at the end. You could then use RAII by either creating the singleton on the stack, or holding it in a std::auto_ptr<>, so that it gets deleted when the thread ends. (Unless the thread terminates abnormally, but if that happens all bets are off and a leaked object is the least of your problems.) You could then just pass the singleton around, or store it in TLS, or store it in a member of a class, if most of the thread functionality is in one class.
Have a look at this paper to understand why double-checked locking doesn't work in general (even though it might work in special cases).
We use a class that stores a map of thread id to data to implement our thread local storage. This seems to work very well, then an instance of this class can be placed anywhere you require thread local storage. Normally clients use an instance of as a static private field.
Here is a rough outline of the code
template <class T>
struct ThreadLocal {
T & value()
{
LockGuard<CriticalSection> lock(m_cs);
std::map<int, T>::iterator itr = m_threadMap.find(Thread::getThreadID());
if(itr != m_threadMap.end())
return itr->second;
return m_threadMap.insert(
std::map<int, T>::value_type(BWThread::getThreadID(), T()))
.first->second;
}
CriticalSection m_cs;
std::map<int, T> m_threadMap;
};
This is then used as
class A {
// ...
void doStuff();
private:
static ThreadLocal<Foo> threadLocalFoo;
};
ThreadLocal<Foo> A::threadLocalFoo;
void A::doStuff() {
// ...
threadLocalFoo.value().bar();
// ...
}
This is simple and works on any platform where you can get the thread id. Note the Critical Section is only used to return/create the reference, once you have the reference all calls are outside the critical section.