C++ lambda pointer/reference memory occupation struggle - c++

I've decided to start learning C++ lately; coming from scripting background (Ruby, JavaScript, PHP). I've started building a very simple observer. What I am trying to achieve, is a custom callback for notify method as shown below:
#include <iostream>
#include <functional>
using namespace std;
template<class StateT>
class Observer{
typedef function<void(StateT)> LambdaT;
LambdaT callback;
~Observer(){
//delete callback;
};
public:
void setCallback(LambdaT &callback)
{
this->callback = callback;
};
void notify(StateT state){
this->callback(state);
};
};
int main(int argc, char** argv) {
Observer<string>* obs = new Observer<string>;
std::function<void(string)> customCallback = [](string state){
cout << state << endl;
};
obs->setCallback(customCallback);
obs->notify("State has changed");
return 0;
}
Then I have a Subject to observe, and when Subject instance is being destroyed, all of it's attached observers are being destroyed too, in order to free memory. This was just an idea, which could be wrong in terms of "ideal" implementation, also not sure if that's how I am supposed to clean memory, I haven't tried smart pointers yet.
~Subject(){
for(listIterator......){
delete (*it); //observer instances pointers are stored in a list
}
};
I was planning to pass callback for my observer, as a pointer to setCallback() function, so i can delete it as I delete observer instances from subject. Now my main question is how do I de-allocate memory, which has been occupied by my callback (which is now an observer property)?

You don't. The callback property is not dynamically allocated. You only need to make sure to deallocate your observer. As a rule of thumb, there should be one delete for each new. Since you never use new for a LambdaT, then there is no need for delete.
Since the setCallback method takes a reference to your callback, this method sees the same value as your main method. But, you do not store a reference to the callback, you store a copy of the callback. So to make this clear:
customCallback is the original value.
callback is a reference to customCallback.
Observer::callback is a copy of callback.

Related

Using member shared_ptr from a member callback function running in different thread (ROS topic subscription)

I am not completely sure how to best title this question since I am not completely sure what the nature of the problem actually is (I guess "how fix segfault" is not a good title).
The situation is, I have written this code:
template <typename T> class LatchedSubscriber {
private:
ros::Subscriber sub;
std::shared_ptr<T> last_received_msg;
std::shared_ptr<std::mutex> mutex;
int test;
void callback(T msg) {
std::shared_ptr<std::mutex> thread_local_mutex = mutex;
std::shared_ptr<T> thread_local_msg = last_received_msg;
if (!thread_local_mutex) {
ROS_INFO("Mutex pointer is null in callback");
}
if (!thread_local_msg) {
ROS_INFO("lrm: pointer is null in callback");
}
ROS_INFO("Test is %d", test);
std::lock_guard<std::mutex> guard(*thread_local_mutex);
*thread_local_msg = msg;
}
public:
LatchedSubscriber() {
last_received_msg = std::make_shared<T>();
mutex = std::make_shared<std::mutex>();
test = 42;
if (!mutex) {
ROS_INFO("Mutex pointer is null in constructor");
}
else {
ROS_INFO("Mutex pointer is not null in constructor");
}
}
void start(ros::NodeHandle &nh, const std::string &topic) {
sub = nh.subscribe(topic, 1000, &LatchedSubscriber<T>::callback, this);
}
T get_last_msg() {
std::lock_guard<std::mutex> guard(*mutex);
return *last_received_msg;
}
};
Essentially what it is doing is subscribing to a topic (channel), meaning that a callback function is called each time a message arrives. The job of this class is to store the last received message so the user of the class can always access it.
In the constructor I allocate a shared_ptr to the message and for a mutex to synchronize access to this message. The reason for using heap memory here is so the LatchedSubscriber can be copied and the same latched message can still be read. (the Subscriber already implements this kind of behavior where copying it doesn't do anything except for the fact that the callback stops being called once the last instance goes out of scope).
The problem is basically that the code segfaults. I am pretty sure the reason for this is that my shared pointers become null in the callback function, despite not being null in the constructor.
The ROS_INFO calls print:
Mutex pointer is not null in constructor
Mutex pointer is null in callback
lrm: pointer is null in callback
Test is 42
I don't understand how this can happen. I guess I have either misunderstood something about shared pointers, ros topic subscriptions, or both.
Things I have done:
At first I had the subscribe call happening in the constructor. I think giving the this pointer to another thread before the constructor has returned can be bad, so I moved this into a start function which is called after the object has been constructed.
There are many aspects to the thread safety of shared_ptrs it seems. At first I used mutex and last_received_msg directly in the callback. Now I have copied them into local variables hoping this would help. But it doesn't seem to make a difference.
I have added a local integer variable. I can read the integer I assigned to this variable in the constructor from the callback. Just a sanity check to make sure that the callback is actually called on an instance created by my constructor.
I think I have figured out the problem.
When subscribing I am passing the this pointer to the subscribe function along with the callback. If the LatchedSubscriber is ever copied and the original deleted, that this pointer becomes invalid, but the sub still exists so the callback keeps being called.
I didn't think this happened anywhere in my code, but the LatcedSubscriber was stored as a member inside an object which was owned by a unique pointer. It looks like make_unique might be doing some copying internally? In any case it is wrong to use the this pointer for the callback.
I ended up doing the following instead
void start(ros::NodeHandle &nh, const std::string &topic) {
auto l_mutex = mutex;
auto l_last_received_msg = last_received_msg;
boost::function<void(const T)> callback =
[l_mutex, l_last_received_msg](const T msg) {
std::lock_guard<std::mutex> guard(*l_mutex);
*l_last_received_msg = msg;
};
sub = nh.subscribe<T>(topic, 1000, callback);
}
This way copies of the two smart pointers are used with the callback instead.
Assigning the closure to a variable of type boost::function<void(const T)> seems to be necessary. Probably due to the way the subscribe function is.
This appears to have fixed the issue. I might also move the subscription into the constructor again and get rid of the start method.

Create unique pointer inside a function

Is it possible to declare a unique_ptr inside a class (nullptr), then pass its raw value (with get()) to a function which create the instance it will point to?
I have to run an application with a Qt made interface. Qt needs the Qapplication to start in the same thread in which the UI will be updated. To do so, since I cannot do that into my main because i'm also using QP framework(which has a blocking function similar to the qt exec()), i created a class that contais 2 unique_ptr:
//MyClass.h
std::unique_ptr<Qapplication> Core;
std::unique_ptr<MainWindow> UI;
then in my code inside the constructor of MyClass i start the thread:
std::thread(&MyClass::threadfunc,this, UI.get(), Core.get());
the thread is:
int MyClass::threadfunc(MainWindow* UI,Qapplication* Core){
int dummy=0;
Core = new QApplication(dummy,nullptr);
UI= new MainWindows();
UI->show;
return Core ->exec();
}
I need the pointer in MyClass since I need to update the UI, so with the pointer to mainwindows I should be able to call its methods, but since it has to be created after QApplication, i cannot istance it in my class constructor.
Then I decided to create all in the separated thread, and since I can guarantee that the pointer in my class will be destroyed after Qt is stopped, I read that it is possible to declare the pointer as unique ones (I could just use the shared pointer, but I want to understand if it is possible to use unique pointers).
To create unique poiters i need make_unique function, but since i passed the raw pointers I cannot use that. I cannot even pass the pointer since they have to be unique (and I use them in MyClass)
The question is, is there a better solution to implement what i want to obtain? or can I obtain it with the implementation I'm using just by doing something different?
thanks
Your code is so messy it is impossible to fix it.
Looks like you are using Qt, so only proper use of QApplication looks like this:
int main(int argc, char* argv[])
{
QApplication app(argc, argv);
MainWindow window;
window.show();
return app.exec();
}
You do not have need or skill do do anything else with it.
The only exception from this pattern is described in documentation when application have no UI mode.
Do no use threads. I know they are fashionable now, and this is a buzz word, but they are very hard to master (muti threading bugs are extremly hard to fix and understand and it is easy to write code which will work on 90% computers and will fail always on 10% of machines), so this feature should be avoided by beginners as long as possible.
First master basics of developing Qt applications without threads of any kind.
Is it possible to declare a unique_ptr inside a class (nullptr), then pass its raw value (with get()) to a function which create the instance it will point to?
You can, but the way you're going about this (from the limited code snipped you've posted) sounds convoluted. Why does threadfunc need to take in raw pointers? Can't it take unique pointers? Seems it can, since you control MyClass.
At any rate, maybe something like this will accomplish what you want. We're basically stuffing the raw pointer inside threadfunc into the class's unique ptr.
#include <iostream>
#include <memory>
#include <thread>
#include <chrono>
struct A {
std::unique_ptr<int> p;
std::thread t1;
A() {
p = nullptr; //happens by default, but explicit for OP
}
void start()
{
//int *rawp_;
t1 = std::thread(&A::threadfunc, this, p.get());
//p = std::unique_ptr<int>{rawp_};
}
void threadfunc(int* rawp){
rawp = new int(5);
p = std::unique_ptr<int>{rawp};
std::cout << "A::p " << *(p) << std::endl;
std::cout << "Sleeping for 5 seconds" << std::endl;
std::this_thread::sleep_for(std::chrono::milliseconds(1000 * (*rawp)));
}
void end()
{
t1.join();
}
};
int main()
{
A a;
// std::cout << *(a.p) << std::endl; //--> SEGFAULT
a.start();
a.end();
}

Resetting a shared pointer captured in a lambda function

(I'm very unsure about the phrasing of the question title. I'm hoping it's not misleading because I really don't know how to summarize this. But I'll try to explain my problem as well as I can.)
In a project, there is something like this (written from memory and simplified):
Class A {
private:
boost::weak_ptr<SomeClassB> b;
public:
static boost::shared_ptr<SomeClassB> StopSomeProcesses () {
boost::shared_ptr<SomeClassB> temp (new SomeClassB());
b = temp;
return temp;
}
}
Now in another project, I need to do something similar to the following:
boost::shared_ptr<SomeClassB> obj;
void someFunction () {
obj = A::StopSomeProcesses();
auto callback = [](){
//some other stuff here
obj.reset();
};
NamespaceFromYetAnotherProject::DoSomething(callback);
}
What this basically does is while b holds a valid object from A::StopSomeProcesses, as the name implies, some processes will be stopped. In this case, the processes are stopped while DoSomething is executed. At the end, DoSomething will call callback where obj is reset and the stopped processes can now finally continue.
I've done this and it works. However, as much as possible, I'd like to avoid using global variables. I tried doing the following:
void someFunction () {
boost::shared_ptr<SomeClassB> obj;
obj = A::StopSomeProcesses();
auto callback = [&obj](){
//some other stuff here
obj.reset();
};
NamespaceFromYetAnotherProject::DoSomething(callback);
}
The above code works. But I'm not sure if I was already in "undefined behavior" territory and just got lucky. Doesn't obj's scope end already? Or does the fact that the lambda was passed as an argument help extend its "life"? If this is safe to do, is that safety lost if callback is run on another thread?
I also tried doing this:
void someFunction () {
boost::shared_ptr<SomeClassB> obj;
obj = A::StopSomeProcesses();
auto callback = [obj](){
//some other stuff here
boost::shared_ptr<SomeClassB> tempObj (new SomeClassB(*obj));
tempObj.reset();
};
NamespaceFromYetAnotherProject::DoSomething(callback);
}
But this was something I tried randomly. I wrote it while completely focused on just deleting the object held by the shared pointer. It worked, but I'm not even sure if it's just roundabout or even valid.
Are these attempts going anywhere? Or am I completely going the wrong way? Or should I just stick to using a global variable? Would appreciate any help on how to go about this problem. Thanks!
You are using a shared_ptr and StopSomeProcesses will internally allocate the memory it points to. Pointers are passed by value so the lifetime of obj is irelevant. Every function call makes a new copy of it as does the binding in the lambda. What matters is what the pointer points too and that was allocated with new and lives on.

How to handle failure to release a resource which is contained in a smart pointer?

How should an error during resource deallocation be handled, when the
object representing the resource is contained in a shared pointer?
EDIT 1:
To put this question in more concrete terms: Many C-style interfaces
have a function to allocate a resource, and one to release
it. Examples are open(2) and close(2) for file descriptors on POSIX
systems, XOpenDisplay and XCloseDisplay for a connection to an X
server, or sqlite3_open and sqlite3_close for a connection to an
SQLite database.
I like to encapsulate such interfaces in a C++ class, using the Pimpl
idiom to hide the implementation details, and providing a factory
method returning a shared pointer to ensure that the resource is
deallocated when no references to it remain.
But, in all the examples given above and many others, the function
used to release the resource may report an error. If this function is
called by the destructor, I cannot throw an exception because
generally destructors must not throw.
If, on the other hand, I provide a public method to release the
resource, I now have a class with two possible states: One in which
the resource is valid, and one in which the resource has already been
released. Not only does this complicate the implementation of the
class, it also opens a potential for wrong usage. This is bad, because
an interface should aim to make usage errors impossible.
I would be grateful for any help with this problem.
The original statement of the question, and thoughts about a possible
solution follow below.
EDIT 2:
There is now a bounty on this question. A solution must meet these
requirements:
The resource is released if and only if no references to it remain.
References to the resource may be destroyed explicitly. An exception is thrown if an error occured while releasing the resource.
It is not possible to use a resource which has already been released.
Reference counting and releasing of the resource are thread-safe.
A solution should meet these requirements:
It uses the shared pointer provided by boost, the C++ Technical Report 1 (TR1), and the upcoming C++ standard, C++0x.
It is generic. Resource classes only need to implement how the resource is released.
Thank you for your time and thoughts.
EDIT 3:
Thanks to everybody who answered my question.
Alsk's answer met everything asked for in the bounty, and
was accepted. In multithreaded code, this solution would require
a separate cleanup thread.
I have added another answer where any exceptions during
cleanup are thrown by the thread that actually used the resource,
without need for a separate cleanup thread. If you are still
interested in this problem (it bothered me a lot), please
comment.
Smart pointers are a useful tool to manage resources safely. Examples
of such resources are memory, disk files, database connections, or
network connections.
// open a connection to the local HTTP port
boost::shared_ptr<Socket> socket = Socket::connect("localhost:80");
In a typical scenario, the class encapsulating the resource should be
noncopyable and polymorphic. A good way to support this is to provide
a factory method returning a shared pointer, and declare all
constructors non-public. The shared pointers can now be copied from
and assigned to freely. The object is automatically destroyed when no
reference to it remains, and the destructor then releases the
resource.
/** A TCP/IP connection. */
class Socket
{
public:
static boost::shared_ptr<Socket> connect(const std::string& address);
virtual ~Socket();
protected:
Socket(const std::string& address);
private:
// not implemented
Socket(const Socket&);
Socket& operator=(const Socket&);
};
But there is a problem with this approach. The destructor must not
throw, so a failure to release the resource will remain undetected.
A common way out of this problem is to add a public method to release
the resource.
class Socket
{
public:
virtual void close(); // may throw
// ...
};
Unfortunately, this approach introduces another problem: Our objects
may now contain resources which have already been released. This
complicates the implementation of the resource class. Even worse, it
makes it possible for clients of the class to use it incorrectly. The
following example may seem far-fetched, but it is a common pitfall in
multi-threaded code.
socket->close();
// ...
size_t nread = socket->read(&buffer[0], buffer.size()); // wrong use!
Either we ensure that the resource is not released before the object
is destroyed, thereby losing any way to deal with a failed resource
deallocation. Or we provide a way to release the resource explicitly
during the object's lifetime, thereby making it possible to use the
resource class incorrectly.
There is a way out of this dilemma. But the solution involves using a
modified shared pointer class. These modifications are likely to be
controversial.
Typical shared pointer implementations, such as boost::shared_ptr,
require that no exception be thrown when their object's destructor is
called. Generally, no destructor should ever throw, so this is a
reasonable requirement. These implementations also allow a custom
deleter function to be specified, which is called in lieu of the
destructor when no reference to the object remains. The no-throw
requirement is extended to this custom deleter function.
The rationale for this requirement is clear: The shared pointer's
destructor must not throw. If the deleter function does not throw, nor
will the shared pointer's destructor. However, the same holds for
other member functions of the shared pointer which lead to resource
deallocation, e.g. reset(): If resource deallocation fails, no
exception can be thrown.
The solution proposed here is to allow custom deleter functions to
throw. This means that the modified shared pointer's destructor must
catch exceptions thrown by the deleter function. On the other hand,
member functions other than the destructor, e.g. reset(), shall not
catch exceptions of the deleter function (and their implementation
becomes somewhat more complicated).
Here is the original example, using a throwing deleter function:
/** A TCP/IP connection. */
class Socket
{
public:
static SharedPtr<Socket> connect(const std::string& address);
protected:
Socket(const std::string& address);
virtual Socket() { }
private:
struct Deleter;
// not implemented
Socket(const Socket&);
Socket& operator=(const Socket&);
};
struct Socket::Deleter
{
void operator()(Socket* socket)
{
// Close the connection. If an error occurs, delete the socket
// and throw an exception.
delete socket;
}
};
SharedPtr<Socket> Socket::connect(const std::string& address)
{
return SharedPtr<Socket>(new Socket(address), Deleter());
}
We can now use reset() to free the resource explicitly. If there is
still a reference to the resource in another thread or another part of
the program, calling reset() will only decrement the reference
count. If this is the last reference to the resource, the resource is
released. If resource deallocation fails, an exception is thrown.
SharedPtr<Socket> socket = Socket::connect("localhost:80");
// ...
socket.reset();
EDIT:
Here is a complete (but platform-dependent) implementation of the deleter:
struct Socket::Deleter
{
void operator()(Socket* socket)
{
if (close(socket->m_impl.fd) < 0)
{
int error = errno;
delete socket;
throw Exception::fromErrno(error);
}
delete socket;
}
};
We need to store allocated resources somewhere (as it was already mentioned by DeadMG) and explicitly call some reporting/throwing function outside of any destructor. But that doesn't prevent us from taking advantage of reference counting implemented in boost::shared_ptr.
/** A TCP/IP connection. */
class Socket
{
private:
//store internally every allocated resource here
static std::vector<boost::shared_ptr<Socket> > pool;
public:
static boost::shared_ptr<Socket> connect(const std::string& address)
{
//...
boost::shared_ptr<Socket> socket(new Socket(address));
pool.push_back(socket); //the socket won't be actually
//destroyed until we want it to
return socket;
}
virtual ~Socket();
//call cleanupAndReport() as often as needed
//probably, on a separate thread, or by timer
static void cleanupAndReport()
{
//find resources without clients
foreach(boost::shared_ptr<Socket>& socket, pool)
{
if(socket.unique()) //there are no clients for this socket, i.e.
//there are no shared_ptr's elsewhere pointing to this socket
{
//try to deallocate this resource
if (close(socket->m_impl.fd) < 0)
{
int error = errno;
socket.reset(); //destroys Socket object
//throw an exception or handle error in-place
//...
//throw Exception::fromErrno(error);
}
else
{
socket.reset();
}
}
} //foreach socket
}
protected:
Socket(const std::string& address);
private:
// not implemented
Socket(const Socket&);
Socket& operator=(const Socket&);
};
The implementation of cleanupAndReport() should be a little more complicated: in the present version the pool is populated with null pointers after cleanup, and in case of throwing exception we have to call the function until it doesn't throw anymore etc, but I hope, it illustrates well the idea.
Now, more general solution:
//forward declarations
template<class Resource>
boost::shared_ptr<Resource> make_shared_resource();
template<class Resource>
void cleanupAndReport(boost::function1<void,boost::shared_ptr<Resource> deallocator);
//for every type of used resource there will be a template instance with a static pool
template<class Resource>
class pool_holder
{
private:
friend boost::shared_ptr<Resource> make_shared_resource<Resource>();
friend void cleanupAndReport(boost::function1<void,boost::shared_ptr<Resource>);
static std::vector<boost::shared_ptr<Resource> > pool;
};
template<class Resource>
std::vector<boost::shared_ptr<Resource> > pool_holder<Resource>::pool;
template<class Resource>
boost::shared_ptr<Resource> make_shared_resource()
{
boost::shared_ptr<Resource> res(new Resource);
pool_holder<Resource>::pool.push_back(res);
return res;
}
template<class Resource>
void cleanupAndReport(boost::function1<void,boost::shared_ptr<Resource> > deallocator)
{
foreach(boost::shared_ptr<Resource>& res, pool_holder<Resource>::pool)
{
if(res.unique())
{
deallocator(res);
}
} //foreach
}
//usage
{
boost::shared_ptr<A> a = make_shared_resource<A>();
boost::shared_ptr<A> a2 = make_shared_resource<A>();
boost::shared_ptr<B> b = make_shared_resource<B>();
//...
}
cleanupAndReport<A>(deallocate_A);
cleanupAndReport<B>(deallocate_B);
If releasing some resource can actually fail, then a destructor is clearly a wrong abstraction to use. Destructors are meant to clean up without fail, regardless of the circumstances. A close() method (or whatever you want to name it) is probably the only way to go.
But think closely about it. If releasing a resource actually fails, what can you do? Is such an error recoverable? If it is, which part of your code should handle it? The way to recover is probably highly application-specific and tied to other parts of the application. It is highly unlikely that you actually want that to happen automatically, in an arbitrary place in the code that happened to release the resource and trigger the error. A shared pointer abstraction does not really model what you're trying to achieve. If so, then you clearly need to create your own abstraction which models your requested behavior. Abusing shared pointers to do something they're not supposed to do is not the right way.
Also, please read this.
EDIT:
If all you want to do is to inform the user what happened before crashing, then consider wrapping the Socket in another wrapper object that would call the deleter on its destruction, catch any exceptions thrown and handle them by showing the user a message box or whatever. Then put this wrapper object inside a boost::shared_ptr.
Quoting Herb Sutter, author of "Exceptional C++" (from here):
If a destructor throws an exception,
Bad Things can happen. Specifically,
consider code like the following:
// The problem
//
class X {
public:
~X() { throw 1; }
};
void f() {
X x;
throw 2;
} // calls X::~X (which throws), then calls terminate()
If a destructor throws an exception
while another exception is already
active (i.e., during stack unwinding),
the program is terminated. This is
usually not a good thing.
In other words, regardless of what you would want to believe is elegant in this situation, you cannot blithely throw an exception in a destructor unless you can guarantee that it will not be thrown while handling another exception.
Besides, what can you do if you can't successfully get rid of a resource? Exceptions should be thrown for things that can be handled higher up, not bugs. If you want to report odd behavior, log the release failure and simply go on. Or terminate.
As announced in the question, edit 3:
Here is another solution which, as far as I can judge, fulfills the
requirements in the question. It is similar to the solution described
in the original question, but uses boost::shared_ptr instead of a
custom smart pointer.
The central idea of this solution is to provide a release()
operation on shared_ptr. If we can make the shared_ptr give up its
ownership, we are free to call a cleanup function, delete the object,
and throw an exception in case an error occurred during cleanup.
Boost has a good
reason
to not provide a release() operation on shared_ptr:
shared_ptr cannot give away ownership unless it's unique() because the
other copy will still destroy the object.
Consider:
shared_ptr<int> a(new int);
shared_ptr<int> b(a); // a.use_count() == b.use_count() == 2
int * p = a.release();
// Who owns p now? b will still call delete on it in its destructor.
Furthermore, the pointer returned by release() would be difficult to
deallocate reliably, as the source shared_ptr could have been created
with a custom deleter.
The first argument against a release() operation is that, by the
nature of shared_ptr, many pointers share ownership of the object,
so no single one of them can simply release that ownership. But what
if the release() function returned a null pointer if there were
still other references left? The shared_ptr can reliably determine
this, without race conditions.
The second argument against the release() operation is that, if a
custom deleter was passed to the shared_ptr, you should use that to
deallocate the object, rather than simply deleting it. But release()
could return a function object, in addition to the raw pointer, to
enable its caller to deallocate the pointer reliably.
However, in our specific szenario, custom deleters will not be an
issue, because we do not have to deal with arbitrary custom
deleters. This will become clearer from the code given below.
Providing a release() operation on shared_ptr without modifying
its implementation is, of course, not possible without a hack. The
hack which is used in the code below relies on a thread-local variable
to prevent our custom deleter from actually deleting the object.
That said, here's the code, consisting mostly of the header
Resource.hpp, plus a small implementation file Resource.cpp. Note
that it must be linked with -lboost_thread-mt due to the
thread-local variable.
// ---------------------------------------------------------------------
// Resource.hpp
// ---------------------------------------------------------------------
#include <boost/assert.hpp>
#include <boost/ref.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/thread/tss.hpp>
/// Factory for a resource.
template<typename T>
struct ResourceFactory
{
/// Create a resource.
static boost::shared_ptr<T>
create()
{
return boost::shared_ptr<T>(new T, ResourceFactory());
}
template<typename A1>
static boost::shared_ptr<T>
create(const A1& a1)
{
return boost::shared_ptr<T>(new T(a1), ResourceFactory());
}
template<typename A1, typename A2>
static boost::shared_ptr<T>
create(const A1& a1, const A2& a2)
{
return boost::shared_ptr<T>(new T(a1, a2), ResourceFactory());
}
// ...
/// Destroy a resource.
static void destroy(boost::shared_ptr<T>& resource);
/// Deleter for boost::shared_ptr<T>.
void operator()(T* resource);
};
namespace impl
{
// ---------------------------------------------------------------------
/// Return the last reference to the resource, or zero. Resets the pointer.
template<typename T>
T* release(boost::shared_ptr<T>& resource);
/// Return true if the resource should be deleted (thread-local).
bool wantDelete();
// ---------------------------------------------------------------------
} // namespace impl
template<typename T>
inline
void ResourceFactory<T>::destroy(boost::shared_ptr<T>& ptr)
{
T* resource = impl::release(ptr);
if (resource != 0) // Is it the last reference?
{
try
{
resource->close();
}
catch (...)
{
delete resource;
throw;
}
delete resource;
}
}
// ---------------------------------------------------------------------
template<typename T>
inline
void ResourceFactory<T>::operator()(T* resource)
{
if (impl::wantDelete())
{
try
{
resource->close();
}
catch (...)
{
}
delete resource;
}
}
namespace impl
{
// ---------------------------------------------------------------------
/// Flag in thread-local storage.
class Flag
{
public:
~Flag()
{
m_ptr.release();
}
Flag& operator=(bool value)
{
if (value != static_cast<bool>(*this))
{
if (value)
{
m_ptr.reset(s_true); // may throw boost::thread_resource_error!
}
else
{
m_ptr.release();
}
}
return *this;
}
operator bool()
{
return m_ptr.get() == s_true;
}
private:
boost::thread_specific_ptr<char> m_ptr;
static char* s_true;
};
// ---------------------------------------------------------------------
/// Flag to prevent deletion.
extern Flag t_nodelete;
// ---------------------------------------------------------------------
/// Return the last reference to the resource, or zero.
template<typename T>
T* release(boost::shared_ptr<T>& resource)
{
try
{
BOOST_ASSERT(!t_nodelete);
t_nodelete = true; // may throw boost::thread_resource_error!
}
catch (...)
{
t_nodelete = false;
resource.reset();
throw;
}
T* rv = resource.get();
resource.reset();
return wantDelete() ? rv : 0;
}
// ---------------------------------------------------------------------
} // namespace impl
And the implementation file:
// ---------------------------------------------------------------------
// Resource.cpp
// ---------------------------------------------------------------------
#include "Resource.hpp"
namespace impl
{
// ---------------------------------------------------------------------
bool wantDelete()
{
bool rv = !t_nodelete;
t_nodelete = false;
return rv;
}
// ---------------------------------------------------------------------
Flag t_nodelete;
// ---------------------------------------------------------------------
char* Flag::s_true((char*)0x1);
// ---------------------------------------------------------------------
} // namespace impl
And here is an example of a resource class implemented using this solution:
// ---------------------------------------------------------------------
// example.cpp
// ---------------------------------------------------------------------
#include "Resource.hpp"
#include <cstdlib>
#include <string>
#include <stdexcept>
#include <iostream>
// uncomment to test failed resource allocation, usage, and deallocation
//#define TEST_CREAT_FAILURE
//#define TEST_USAGE_FAILURE
//#define TEST_CLOSE_FAILURE
// ---------------------------------------------------------------------
/// The low-level resource type.
struct foo { char c; };
// ---------------------------------------------------------------------
/// The low-level function to allocate the resource.
foo* foo_open()
{
#ifdef TEST_CREAT_FAILURE
return 0;
#else
return (foo*) std::malloc(sizeof(foo));
#endif
}
// ---------------------------------------------------------------------
/// Some low-level function using the resource.
int foo_use(foo*)
{
#ifdef TEST_USAGE_FAILURE
return -1;
#else
return 0;
#endif
}
// ---------------------------------------------------------------------
/// The low-level function to free the resource.
int foo_close(foo* foo)
{
std::free(foo);
#ifdef TEST_CLOSE_FAILURE
return -1;
#else
return 0;
#endif
}
// ---------------------------------------------------------------------
/// The C++ wrapper around the low-level resource.
class Foo
{
public:
void use()
{
if (foo_use(m_foo) < 0)
{
throw std::runtime_error("foo_use");
}
}
protected:
Foo()
: m_foo(foo_open())
{
if (m_foo == 0)
{
throw std::runtime_error("foo_open");
}
}
void close()
{
if (foo_close(m_foo) < 0)
{
throw std::runtime_error("foo_close");
}
}
private:
foo* m_foo;
friend struct ResourceFactory<Foo>;
};
// ---------------------------------------------------------------------
typedef ResourceFactory<Foo> FooFactory;
// ---------------------------------------------------------------------
/// Main function.
int main()
{
try
{
boost::shared_ptr<Foo> resource = FooFactory::create();
resource->use();
FooFactory::destroy(resource);
}
catch (const std::exception& e)
{
std::cerr << e.what() << std::endl;
}
return 0;
}
Finally, here is a small Makefile to build all that:
# Makefile
CXXFLAGS = -g -Wall
example: example.cpp Resource.hpp Resource.o
$(CXX) $(CXXFLAGS) -o example example.cpp Resource.o -lboost_thread-mt
Resource.o: Resource.cpp Resource.hpp
$(CXX) $(CXXFLAGS) -c Resource.cpp -o Resource.o
clean:
rm -f Resource.o example
Well, first off, I don't see a question here. Second off, I have to say that this is a bad idea. What will you gain in all this? When the last shared pointer to a resource is destroyed and your throwing deleter is called you will find yourself with a resource leak. You will have lost all handles to the resource that failed to release. You will never be able to try again.
Your desire to use an RAII object is a good one but a smart pointer is simply insufficient to the task. What you need needs to be even smarter. You need something that can rebuild itself on failure to completely collapse. The destructor is insufficient for such an interface.
You do introduce yourself to the misuse where someone could cause a resource to have a handle but be invalid. The type of resource you're dealing with here simply lends itself to this issue. There are many ways in which you may approach this. One method may be to use the handle/body idiom along with the state pattern. The implementation of the interface can be in one of two states: connected or unconnected. The handle simply passes requests to the internal body/state. Connected works like normal, unconnected throws exceptions/asserts in all applicable requests.
This thing would need a function other than ~ to destroy a handle to it. You could consider a destroy() function that can throw. If you catch an error when you call it you don't delete the handle but instead deal with the problem in whatever application specific way you need to. If you don't catch an error from destroy() you let the handle go out of scope, reset it, or whatever. The function destroy() then decriments the resource count and attempts to release the internal resource if that count is 0. Upon success the handle in switched to the unconnected state, upon failure it generates a catchable error that the client can attempt to handle but leaves the handle in a connected state.
It's not an entirely trivial thing to write but what you are wanting to do, introduce exceptions into destruction, simply will not work.
Generally speaking, if a resource's C-style closure fails, then it's a problem with the API rather than a problem in your code. However, what I would be tempted to do is, if destruction is failed, add it to a list of resources that need destruction/cleanup re-attempted later, say, when app exits, periodically, or when other similar resources are destroyed, and then try to re-destroy. If any are left over at arbitrary time, give user error and exit.

Detecting when an object is passed to a new thread in C++?

I have an object for which I'd like to track the number of threads that reference it. In general, when any method on the object is called I can check a thread local boolean value to determine whether the count has been updated for the current thread. But this doesn't help me if the user say, uses boost::bind to bind my object to a boost::function and uses that to start a boost::thread. The new thread will have a reference to my object, and may hold on to it for an indefinite period of time before calling any of its methods, thus leading to a stale count. I could write my own wrapper around boost::thread to handle this, but that doesn't help if the user boost::bind's an object that contains my object (I can't specialize based on the presence of a member type -- at least I don't know of any way to do that) and uses that to start a boost::thread.
Is there any way to do this? The only means I can think of requires too much work from users -- I provide a wrapper around boost::thread that calls a special hook method on the object being passed in provided it exists, and users add the special hook method to any class that contains my object.
Edit: For the sake of this question we can assume I control the means to make new threads. So I can wrap boost::thread for example and expect that users will use my wrapped version, and not have to worry about users simultaneously using pthreads, etc.
Edit2: One can also assume that I have some means of thread local storage available, through __thread or boost::thread_specific_ptr. It's not in the current standard, but hopefully will be soon.
In general, this is hard. The question of "who has a reference to me?" is not generally solvable in C++. It may be worth looking at the bigger picture of the specific problem(s) you are trying to solve, and seeing if there is a better way.
There are a few things I can come up with that can get you partway there, but none of them are quite what you want.
You can establish the concept of "the owning thread" for an object, and REJECT operations from any other thread, a la Qt GUI elements. (Note that trying to do things thread-safely from threads other than the owner won't actually give you thread-safety, since if the owner isn't checked it can collide with other threads.) This at least gives your users fail-fast behavior.
You can encourage reference counting by having the user-visible objects being lightweight references to the implementation object itself [and by documenting this!]. But determined users can work around this.
And you can combine these two-- i.e. you can have the notion of thread ownership for each reference, and then have the object become aware of who owns the references. This could be very powerful, but not really idiot-proof.
You can start restricting what users can and cannot do with the object, but I don't think covering more than the obvious sources of unintentional error is worthwhile. Should you be declaring operator& private, so people can't take pointers to your objects? Should you be preventing people from dynamically allocating your object? It depends on your users to some degree, but keep in mind you can't prevent references to objects, so eventually playing whack-a-mole will drive you insane.
So, back to my original suggestion: re-analyze the big picture if possible.
Short of a pimpl style implementation that does a threadid check before every dereference I don't see how you could do this:
class MyClass;
class MyClassImpl {
friend class MyClass;
threadid_t owning_thread;
public:
void doSomethingThreadSafe();
void doSomethingNoSafetyCheck();
};
class MyClass {
MyClassImpl* impl;
public:
void doSomethine() {
if (__threadid() != impl->owning_thread) {
impl->doSomethingThreadSafe();
} else {
impl->doSomethingNoSafetyCheck();
}
}
};
Note: I know the OP wants to list threads with active pointers, I don't think that's feasible. The above implementation at least lets the object know when there might be contention. When to change the owning_thread depends heavily on what doSomething does.
Usually you cannot do this programmatically.
Unfortuately, the way to go is to design your program in such a way that you can prove (i.e. convince yourself) that certain objects are shared, and others are thread private.
The current C++ standard does not even have the notion of a thread, so there is no standard portable notion of thread local storage, in particular.
If I understood your problem correctly I believe this could be done in Windows using Win32 function GetCurrentThreadId().
Below is a quick and dirty example of how it could be used. Thread synchronisation should rather be done with a lock object.
If you create an object of CMyThreadTracker at the top of every member function of your object to be tracked for threads, the _handle_vector should contain the thread ids that use your object.
#include <process.h>
#include <windows.h>
#include <vector>
#include <algorithm>
#include <functional>
using namespace std;
class CMyThreadTracker
{
vector<DWORD> & _handle_vector;
DWORD _h;
CRITICAL_SECTION &_CriticalSection;
public:
CMyThreadTracker(vector<DWORD> & handle_vector,CRITICAL_SECTION &crit):_handle_vector(handle_vector),_CriticalSection(crit)
{
EnterCriticalSection(&_CriticalSection);
_h = GetCurrentThreadId();
_handle_vector.push_back(_h);
printf("thread id %08x\n",_h);
LeaveCriticalSection(&_CriticalSection);
}
~CMyThreadTracker()
{
EnterCriticalSection(&_CriticalSection);
vector<DWORD>::iterator ee = remove_if(_handle_vector.begin(),_handle_vector.end(),bind2nd(equal_to<DWORD>(), _h));
_handle_vector.erase(ee,_handle_vector.end());
LeaveCriticalSection(&_CriticalSection);
}
};
class CMyObject
{
vector<DWORD> _handle_vector;
public:
void method1(CRITICAL_SECTION & CriticalSection)
{
CMyThreadTracker tt(_handle_vector,CriticalSection);
printf("method 1\n");
EnterCriticalSection(&CriticalSection);
for(int i=0;i<_handle_vector.size();++i)
{
printf(" this object is currently used by thread %08x\n",_handle_vector[i]);
}
LeaveCriticalSection(&CriticalSection);
}
};
CMyObject mo;
CRITICAL_SECTION CriticalSection;
unsigned __stdcall ThreadFunc( void* arg )
{
unsigned int sleep_time = *(unsigned int*)arg;
while ( true)
{
Sleep(sleep_time);
mo.method1(CriticalSection);
}
_endthreadex( 0 );
return 0;
}
int _tmain(int argc, _TCHAR* argv[])
{
HANDLE hThread;
unsigned int threadID;
if (!InitializeCriticalSectionAndSpinCount(&CriticalSection, 0x80000400) )
return -1;
for(int i=0;i<5;++i)
{
unsigned int sleep_time = 1000 *(i+1);
hThread = (HANDLE)_beginthreadex( NULL, 0, &ThreadFunc, &sleep_time, 0, &threadID );
printf("creating thread %08x\n",threadID);
}
WaitForSingleObject( hThread, INFINITE );
return 0;
}
EDIT1:
As mentioned in the comment, reference dispensing could be implemented as below. A vector could hold the unique thread ids referring to your object. You may also need to implement a custom assignment operator to deal with the object references being copied by a different thread.
class MyClass
{
public:
static MyClass & Create()
{
static MyClass * p = new MyClass();
return *p;
}
static void Destroy(MyClass * p)
{
delete p;
}
private:
MyClass(){}
~MyClass(){};
};
class MyCreatorClass
{
MyClass & _my_obj;
public:
MyCreatorClass():_my_obj(MyClass::Create())
{
}
MyClass & GetObject()
{
//TODO:
// use GetCurrentThreadId to get thread id
// check if the id is already in the vector
// add this to a vector
return _my_obj;
}
~MyCreatorClass()
{
MyClass::Destroy(&_my_obj);
}
};
int _tmain(int argc, _TCHAR* argv[])
{
MyCreatorClass mcc;
MyClass &o1 = mcc.GetObject();
MyClass &o2 = mcc.GetObject();
return 0;
}
The solution I'm familiar with is to state "if you don't use the correct API to interact with this object, then all bets are off."
You may be able to turn your requirements around and make it possible for any threads that reference the object subscribe to signals from the object. This won't help with race conditions, but allows threads to know when the object has unloaded itself (for instance).
To solve the problem "I have an object and want to know how many threads access it" and you also can enumerate your threads, you can solve this problem with thread local storage.
Allocate a TLS index for your object. Make a private method called "registerThread" which simply sets the thread TLS to point to your object.
The key extension to the poster's original idea is that during every method call, call this registerThread(). Then you don't need to detect when or who created the thread, it's just set (often redundantly) during every actual access.
To see which threads have accessed the object, just examine their TLS values.
Upside: simple and pretty efficient.
Downside: solves the posted question but doesn't extend smoothly to multiple objects or dynamic threads that aren't enumerable.