This is a question regarding coding design, so please forgive the long code listings: I could not resume these ideas and the potential pitfalls without showing the actual code.
I am writing a ConcurrentReferenceCounted class and would appreciate some feedback on my implementation. Sub-classes from this class will receive "release" instead of a direct delete.
Here is the class:
class ConcurrentReferenceCounted : private NonCopyable {
public:
ConcurrentReferenceCounted() : ref_count_(1) {}
virtual ~ConcurrentReferenceCounted() {}
void retain() {
ScopedLock lock(mutex_);
++ref_count_;
}
void release() {
bool should_die = false;
{
ScopedLock lock(mutex_);
should_die = --ref_count_ == 0;
}
if (should_die) delete this;
}
private:
size_t ref_count_;
Mutex mutex_;
};
And here is a scoped retain:
class ScopedRetain {
public:
ScopedRetain(ConcurrentReferenceCounted *object) : object_(object) {
retain();
}
ScopedRetain() : object_(NULL) {}
~ScopedRetain() {
release();
}
void hold(ConcurrentReferenceCounted *object) {
assert(!object_); // cannot hold more then 1 object
object_ = object;
retain();
}
private:
ConcurrentReferenceCounted *object_;
void release() {
if (object_) object_->release();
}
void retain() {
object_->retain();
}
};
And finally this is a use case:
Object *target;
ScopedRetain sr;
if (objects_.get(key, &target))
sr.hold(target);
else
return;
// use target
// no need to 'release'
Your ConcurrentReferenceCounted seems to use a full mutex, which is not necessary and not very fast. Reference counting can be implemented atomically using architecture-dependent interlocked instructions. Under Windows, the InterlockedXXXfamily of functions simply wraps these instructions.
Related
I faced a problem with C++ memory management and smart pointers.
I have a code to demonstrate you the problem:
#include <memory>
class Closeable
{
public:
virtual void Close() = 0;
};
class DisconnectionHandler
{
public:
virtual void HandleDisconnection() = 0;
};
class EventHandler
{
public:
virtual void HandleEvent() = 0;
};
class Notifier
{
public:
virtual void OnDisconnection() = 0;
};
class RemoteSystem : public Closeable
{
public:
void SetReceiveDataEventHandler(const std::shared_ptr<EventHandler>& receive_data_event_handler) {
this->receive_data_event_handler_ = receive_data_event_handler;
}
void Close() override { this->receive_data_event_handler_ = nullptr; }
// In this example to simplify the code I just call this method from the main function.
void OnDataReceived() { this->receive_data_event_handler_->HandleEvent(); }
private:
std::shared_ptr<EventHandler> receive_data_event_handler_;
};
class ReceiveDataEventHandler : public EventHandler
{
public:
explicit ReceiveDataEventHandler(const std::shared_ptr<DisconnectionHandler>& disconnection_handler)
: disconnection_handler_(disconnection_handler) {}
void HandleEvent() override {
// Some code of receiving data.
// But we can find out that connection was closed and we must call the disconnection handler.
if (this->IsConnectionClosed()) {
this->disconnection_handler_->HandleDisconnection();
return;
}
// Some other stuff..
}
private:
[[nodiscard]] bool IsConnectionClosed() const {
// In the example code I just return true.
return true;
}
private:
const std::shared_ptr<DisconnectionHandler> disconnection_handler_;
};
class RemoteSystemDisconnectionHandler : public DisconnectionHandler
{
public:
explicit RemoteSystemDisconnectionHandler(const std::shared_ptr<Closeable>& closeable_remote_system,
Notifier* notifier)
: closeable_remote_system_(closeable_remote_system), notifier_(notifier) {}
~RemoteSystemDisconnectionHandler() { printf("Destructed.\n"); }
void HandleDisconnection() override {
this->closeable_remote_system_->Close();
printf("Closed.\n");
this->notifier_->OnDisconnection();
printf("Notified.\n");
}
private:
const std::shared_ptr<Closeable> closeable_remote_system_;
Notifier* const notifier_;
};
class ClientNotifier : public Notifier
{
public:
void OnDisconnection() override { printf("Disconnected.\n"); }
};
int main() {
ClientNotifier notifier;
auto remote_system = std::make_shared<RemoteSystem>();
{
// Scope for losing references in the main function after SetReceiveDataEventHandler.
auto disconnection_handler = std::make_shared<RemoteSystemDisconnectionHandler>(remote_system, ¬ifier);
auto receive_data_event_handler = std::make_shared<ReceiveDataEventHandler>(disconnection_handler);
remote_system->SetReceiveDataEventHandler(receive_data_event_handler);
}
// Only in the example.
remote_system->OnDataReceived();
return 0;
}
You can also run this code. In this example program crashes on the line this->notifier_->OnDisconnection(). The output of the program:
Destructed.
Closed.
*crash*
This occurs because of losing the last reference to the ReceiveDataEventHandler when calling method RemoteSystem::Close from RemoteSystemDisconnectionHandler::HandleDisconnection, accordingly, losing the reference to the RemoteSystemDisconnectionHandler and deleting this object. After the Close method and deleting both objects of classes RemoteSystemDisconnectionHandler and ReceiveDataEventHandler it returns to the RemoteSystemDisconnectionHandler::HandleDisconnection method and prints 'Closed.' to the output, but since the object has been already deleted, the next line occurs an error, because now this is deleted and any access to it occurs memory exception.
I also tried to rewrite this code on Java and it works fine, unlike C++.
So, I want to ask you guys if there is a solution for this problem in the C++ community?
I thought C++ had no problems with memory management since smart pointers exist, but appearently I was wrong.
Hope for your help!
Thanks in advance!
A simple solution is to make a copy of the shared_ptr before invoking the method on it:
void OnDataReceived()
{
auto temp = this->receive_data_event_handler_;
if (temp)
{
temp->HandleEvent();
}
}
temp will keep the pointer alive until after the method invocation has completed.
However note that if you are using multiple threads in your real code, std::shared_ptr is not thread safe so you need to introduce a mutex to protect access to receive_data_event_handler_:
class RemoteSystem : public Closeable
{
public:
void SetReceiveDataEventHandler(const std::shared_ptr<EventHandler>& receive_data_event_handler) {
this->receive_data_event_handler_ = receive_data_event_handler;
}
void Close() override
{
std::unique_lock lock(mutex);
this->receive_data_event_handler_ = nullptr;
}
// In this example to simplify the code I just call this method from the main function.
void OnDataReceived()
{
std::shared_ptr<EventHandler> temp;
{
std::unique_lock lock(mutex);
temp = this->receive_data_event_handler_;
}
if (temp)
{
temp->HandleEvent();
}
}
private:
std::shared_ptr<EventHandler> receive_data_event_handler_;
std::mutex mutex;
};
I'm setting up a State system for my game.
class State
{
protected:
enum State_
{
STATE_INTRO,
STATE_GAME,
STATE_PAUSE,
STATE_CUTSCENE,
};
public:
State();
virtual void run(State_) = 0;
virtual ~State(); // virtual destructor cus we will be inheriting this class
};
I then have inherited classes which represent each state
class IntroState : public State
{
public:
void run(State_ STATE);
};
I want the run function to have different functionality based off of what state the game is in, is it bad practice to achieve that like this:
void IntroState::run(State_ STATE)
{
if (STATE == STATE_INTRO)
{
// load the intro
}
}
I'm not sure how else to do this, thanks (and keep in my mind I'm JUST learning about states so I might be completely off here)
To expand on my comment, here is a possible approach (improvements are appreciated):
class Game {
//... Initialize all State-derived classes in constructor and put them in states (not shown)
vector<unique_ptr>> states;
State_ currentState {STATE_INTRO};
State_ nextState {STATE_INTRO};
public:
void setNextState(State_ state ) {nextState = state;}
void Play() {
for(;;) { //endless loop
if (!states[currentState]->run()) return;//stopping when run returns false
currentState = nextState;
}
}
};
And run could look like this:
class IntroState : public State {
//...
void run(Game& game) {
// do stuff
game.setNextState(STATE_GAME);
return true;
}
};
Of course, you need to figure out the include order, and you'll need to forward-declare Game in State.hpp (the code shown here only shows the central idea). Also, the implementations of run and Play should of course be in seperate .cpp files (didn't do that here so this example wouldn't get too long)
I think you don't need polymorphism in your case since you will only have one State class in your application (correct me if I'm wrong).
You're run function would look like this:
void run(State_ state)
{
switch (state)
{
case STATE_INTRO:
doIntro();
case STATE_BLAH:
doBlah();
// fill all you states...
}
}
void doIntro()
{
// do something for the intro
}
void doBlah()
{
// do something for blah
}
Now if you really wanna get fancy and remove the switch statement:
class State
{
private:
void doA() {}
void doB() {}
enum State_
{
A = 0,
B,
END_
};
std::function<void(void)> functions[END_];
public:
State()
{
functions[A] = std::bind(&State::doA, this);
functions[B] = std::bind(&State::doB, this);
}
void run(State_ state)
{
functions[state]();
}
};
In Java you can create an object whilst at the same time providing (or overloading) abstract functions within the object, thus:
ActionListener al = new ActionListener() {
public void actionPerformed(ActionEvent e) {
// Whatever in here
}
};
I really like that way of doing it, and was wondering if there was some similar construct in C++.
Basically I want a base class with a couple of PV functions declared in it (amongst other stuff), and the user to create an instance of that class whilst at the same time providing the body of the PV functions.
I know I could create child classes, but that seems a little clunky for what I need, where each child class would be unique and only be used to make one instance each.
I have thought about providing lamdas to the constructor and using those instead of actual member functions, but that really seems messy and hard for a novice user to get their head around - not to mention that it would be too rigid (I'd also like to be able to override some non-pure virtual functions optionally).
So is child classes the only way to go, or is there some lesser-known construct in some newer C++ standard that I don't know about that could do what I want?
To expand a little - the idea is to have a class like:
class Thread {
// other stuff
public:
virtual void setup() = 0;
virtual void loop() = 0;
// other functions, some virtual but not pure
};
Thread threadOne {
void setup() {
// Init code for this thread
}
void loop() {
// Run code for this thread
}
};
Thread threadTwo {
void setup() {
// Init code for this thread
}
void loop() {
// Run code for this thread
}
};
Obviously not that syntax, but it gives you an idea of how I'd like to use the class.
It's intended to be run on an embedded system with a slimmed-down C++ implementation (it's g++ but without the full STL). End users aren't the brightest bunch, so it has to be kept as simple to understand as possible.
Anonymous child classes are the closest to what I'd like (though still not perfect). I can use CPP macros to help abstract some of the class implementation syntactic sugar which would help.
Here's a compilable construct I have come up with. Is there anything "wrong" with this approach given the constraints above?
#define THREAD(NAME, CONTENT) class : public Thread {\
public:\
CONTENT\
} NAME;
class Thread {
private:
uint32_t stack[256]; // 1kB stack
volatile bool _running;
public:
virtual void setup() = 0;
virtual void loop() = 0;
void start();
void stop();
uint8_t state();
static void spawn(Thread *thr);
void threadRunner();
};
void Thread::spawn(Thread *thread) {
thread->threadRunner();
}
void Thread::start() {
Thread::spawn(this);
}
void Thread::threadRunner() {
_running = true;
setup();
while (_running) {
loop();
}
}
void Thread::stop() {
_running = false;
}
uint8_t Thread::state() {
return 0;
}
THREAD(myThread,
void setup() override {
}
void loop() override {
}
)
void setup() {
myThread.start();
}
void loop() {
}
Obviously it doesn't actually do anything yet - the whole of the threading back-end is a separate issue, and will be ported over from some existing code I wrote a few years back. I am mainly interested in simplifying the interface for the end user.
There is multiple possibilities, but I'd stick with something simple and versatile: callbacks and lambdas instead of virtual function and inheritance.
class ActionListener
{
std::function<void(int)> _action_performed;
public:
template<class CB>
ActionListener(CB cb) : _action_performed(cb) {}
void click() { _action_performed(0); }
};
int main()
{
ActionListener al([](int n) { std::cout << "Action Performed #" << n << "\n"; });
al.click(); // prints "Action Performed #0"
}
live demo
I'd also like to be able to override some non-pure virtual functions optionally
Which, semantically speaking, means providing a default behavior. This is possible:
ActionListener(CB cb) : _action_performed(cb) {} // construct an AL with the given callback
ActionListener() : _action_performed(default_action_performed) {} // construct an AL with a default callback
void default_action_performed(int n) { /*...*/ }
well, as you already mentioned, one way would be child classes.
another way would be providing some std::functions (or lambdas), either in the constructor or have some set functions.
store the function as a member and call this once your "virtual" member function is called: If you want it optional:
class MyBase
{
public:
MyBase();
void SetFunc(const std::function<int()>& myFun)
{
m_myFun = myFun;
}
int MyVirtFunc()
{
if(m_myFun)
{
return m_myFun();
}
else
{
return 42;
}
}
private:
std::function<int()> m_myFun;
}
if you want the functions given mandatory, put them in the constructor:
class MyBase
{
public:
MyBase(const std::function<int()>& myFun)
: m_myFun(myFun) {}
int MyVirtFun() { return m_myFun(); }
private:
const std::function<int()> m_myFun;
}
I am currently developing a program that needs to download some images from the socket server,and the downloading work will execute a long time. So, I create a new std::thread to do that.
Once it's downloaded,the std::thread will call a member function of current Class, but this Class is likely to have been released. So, I got a exception.
How to solve this problem?
void xxx::fun1()
{
...
}
void xxx::downloadImg()
{
...a long time
if(downloadComplete)
{
this->fun1();
}
}
void xxx::mainProcees()
{
std::thread* th = new thread(mem_fn(&xxx::downloadImg),this);
th->detach();
//if I use th->join(),the UI will be obstructed
}
Don't detach the thread. Instead, you can have a data member that hold a pointer to the thread, and join the thread in destructor.
class YourClass {
public:
~YourClass() {
if (_thread != nullptr) {
_thread->join();
delete _thread;
}
}
void mainProcees() {
_thread = new thread(&YourClass::downloadImg,this);
}
private:
thread *_thread = nullptr;
};
UPDATE
Just as #milleniumbug pointed out, you don't need dynamic allocation for the thread object, since it is movable. So the other solution is as follows.
class YourClass {
public:
~YourClass() {
if (_thread.joinable())
_thread.join();
}
void mainProcess() {
_thread = std::thread(&YourClass::downloadImg, this);
}
private:
std::thread _thread;
};
I have a class that is shared between several projects, some uses of it are single-threaded and some are multi-threaded. The single-threaded users don't want the overhead of mutex locking, and the multi-threaded users don't want to do their own locking and want to be able to optionally run in "single-threaded mode." So I would like to be able to select between real and "dummy" mutexes at runtime.
Ideally, I would have a shared_ptr<something> and assign either a real or fake mutex object. I would then "lock" this without regard to what's in it.
unique_lock<something> guard(*mutex);
... critical section ...
Now there is a signals2::dummy_mutex but it does not share a common base class with boost::mutex.
So, what's an elegant way to select between a real mutex and a dummy mutex (either the one in signals2 or something else) without making the lock/guard code more complicated than the example above?
And, before you point out the alternatives:
I could select an implementation at compile time, but preprocessor macros are ugly and maintaining project configurations is painful for us.
Users of the class in a multi-threaded environment do not want to take on the responsibility of locking the use of the class rather than having the class do its own locking internally.
There are too many APIs and existing usages involved for a "thread-safe wrapper" to be a practical solution.
How about something like this?
Its untested but should be close to OK.
You might consider making the template class hold a value rather than a pointer
if your mutexes support the right kinds of constructions. Otherwise you could specialise the MyMutex class to get value behaviour.
Also it's not being careful about copying or destruction .. I leave that as an exercise to the reader ;) ( shared_ptr or storing a value rather than a pointer should fix this)
Oh and the code would be nicer using RAII rather than explicit lock/unlock... but that's a different question.I assume thats what the unique_lock in your code does?
struct IMutex
{
virtual ~IMutex(){}
virtual void lock()=0;
virtual bool try_lock()=0;
virtual void unlock()=0;
};
template<typename T>
class MyMutex : public IMutex
{
public:
MyMutex(T t) : t_(t) {}
void lock() { t_->lock(); }
bool try_lock() { return t_->try_lock(); }
void unlock() { t_->unlock(); }
protected:
T* t_;
};
IMutex * createMutex()
{
if( isMultithreaded() )
{
return new MyMutex<boost::mutex>( new boost::mutex );
}
else
{
return new MyMutex<signal2::dummy_mutex>( new signal2::dummy_mutex );
}
}
int main()
{
IMutex * mutex = createMutex();
...
{
unique_lock<IMutex> guard( *mutex );
...
}
}
Since the two mutex classes signals2::dummy_mutex and boost::mutex don't share a common base class you could use something like "external polymorphism" to allow to them to be treated polymorphically. You'd then use them as locking strategies for a common mutex/lock interface. This allows you to avoid using "if" statements in the lock implementation.
NOTE: This is basically what Michael's proposed solution implements. I'd suggest going with his answer.
Have you ever heard about Policy-based Design ?
You can define a Lock Policy interface, and the user may choose which policy she wishes. For ease of use, the "default" policy is precised using a compile-time variable.
#ifndef PROJECT_DEFAULT_LOCK_POLICY
#define PROJECT_DEFAULT_LOCK_POLICY TrueLock
#endif
template <class LP = PROJECT_DEFAULT_LOCK_POLICY>
class MyClass {};
This way, your users can choose their policies with a simple compile-time switch, and may override it one instance at a time ;)
This is my solution:
std::unique_lock<std::mutex> lock = dummy ?
std::unique_lock<std::mutex>(mutex, std::defer_lock) :
std::unique_lock<std::mutex>(mutex);
Is this not sufficient?
class SomeClass
{
public:
SomeClass(void);
~SomeClass(void);
void Work(bool isMultiThreaded = false)
{
if(isMultiThreaded)
{
lock // mutex lock ...
{
DoSomething
}
}
else
{
DoSomething();
}
}
};
In general, a mutex is only needed if the resource is shared between multiple processes. If an instance of the object is unique for a (possibly multi-threaded) process, then a Critical Section is often more appropriate.
In Windows, the single-threaded implementation of a Critical Section is a dummy one. Not sure what platform you are using.
Just FYI, here's the implementation I ended up with.
I did away with the abstract base class, merging it with the no-op "dummy" implementation. Also note the shared_ptr-derived class with an implicit conversion operator. A little too tricky, I think, but it lets me use shared_ptr<IMutex> objects where I previously used boost::mutex objects with zero changes.
header file:
class Foo {
...
private:
struct IMutex {
virtual ~IMutex() { }
virtual void lock() { }
virtual bool try_lock() { return true; }
virtual void unlock() { }
};
template <typename T> struct MutexProxy;
struct MutexPtr : public boost::shared_ptr<IMutex> {
operator IMutex&() { return **this; }
};
typedef boost::unique_lock<IMutex> MutexGuard;
mutable MutexPtr mutex;
};
implementation file:
template <typename T>
struct Foo::MutexProxy : public IMutex {
virtual void lock() { mutex.lock(); }
virtual bool try_lock() { return mutex.try_lock(); }
virtual void unlock() { mutex.unlock(); }
private:
T mutex;
};
Foo::Foo(...) {
mutex.reset(single_thread ? new IMutex : new MutexProxy<boost::mutex>);
}
Foo::Method() {
MutexGuard guard(mutex);
}
Policy based Option:
class SingleThreadedPolicy {
public:
class Mutex {
public:
void Lock() {}
void Unlock() {}
bool TryLock() { return true; }
};
class ScopedGuard {
public:
ScopedGuard(Mutex& mutex) {}
};
};
class MultithreadingPolicy {
public:
class ScopedGuard;
class Mutex {
friend class ScopedGuard;
private:
std::mutex mutex_;
public:
void Lock() {
mutex_.lock();
}
void Unlock() {
mutex_.unlock();
}
bool TryLock() {
return mutex_.try_lock();
}
};
class ScopedGuard {
private:
std::lock_guard<std::mutex> lock_;
public:
ScopedGuard(Mutex& mutex) : lock_(mutex.mutex_) {}
};
};
Then it can be used as follows:
template<class ThreadingPolicy = SingleThreadedPolicy>
class MyClass {
private:
typedef typename ThreadingPolicy::Mutex Mutex;
typedef typename ThreadingPolicy::ScopedGuard ScopedGuard;
Mutex mutex_;
public:
void DoSomething(){
ScopedGuard guard(mutex_);
std::cout<<"Hello World"<<std::endl;
}
};