Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Class with all synchronized methods in C++

In Java we can create a class

class Test {
    public synchronized void  fn1() {

    }

    public synchronized void  fn2() {

    }

    public synchronized void  fn3() {
        fn1(); // Calling another method
    }
}

In C++ if I want to mimic the functionality one way is

class Test {
    private:
        mutex obj;
    public:
       void fn1(bool calledFromWithinClass = false) {
            if(calledFromWithinClass) 
                fn1Helper();
            else
                unique_lock<mutex> lock(obj);
                fn1Helper();
        }

       void fn2(bool calledFromWithinClass = false) {
            if(calledFromWithinClass) 
                fn2Helper();
            else
                unique_lock<mutex> lock(obj);
                fn2Helper();
        }

        void fn3(bool calledFromWithinClass = false) {
            if(calledFromWithinClass) 
                fn3Helper();
            else {
                unique_lock<mutex> lock(obj);
                fn3Helper();
            } 
        }
    private:
        void fn1Helper() {
        }

        void fn2Helper() {
        }

        void fn3Helper() {
             fn1(true);
        }
}
int main() {
    Test obj;
    obj.fn1();
    obj.fn2(); 
    // i.e from outside the class the methods are called with calledFromWithinClass as false.
}

In short all I am trying to do is to use RAII for locking as well as allow functions to call each other. In C++ without the calledFromWithinClass flag if the outer function has acquired the lock the inner function can't acquire the lock and the code gets stuck.

As you can see the code is complicated, is there any other way to do this in C++.

I can only use C++98 and you can assume that all methods in the class are synchronized (i.e need the lock)

like image 965
user1918858 Avatar asked Mar 02 '16 02:03

user1918858


1 Answers

I can suggest two options:

  1. Just use boost::recursive_mutex instead (or std::recursive_mutex in C++11).

  2. (better) Always call non-synchronized private implementations from your synchronized code:

    class Test {
    private:
        mutex obj;
    public:
       void fn1() {
            unique_lock<mutex> lock(obj);
            fn1Helper();
        }
    
       void fn2(bool calledFromWithinClass = false) {
            unique_lock<mutex> lock(obj);
            fn2Helper();
        }
    
    private:
        void fn1Helper() {
        }
    
        void fn2Helper() {
            fn1Helper();
        }
    }
    
like image 133
Anton Savin Avatar answered Sep 30 '22 08:09

Anton Savin