1 /*
2  * Copyright (C) 2018 Codership Oy <info@codership.com>
3  *
4  * This file is part of wsrep-lib.
5  *
6  * Wsrep-lib is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * Wsrep-lib is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with wsrep-lib.  If not, see <https://www.gnu.org/licenses/>.
18  */
19 
20 #ifndef WSREP_MUTEX_HPP
21 #define WSREP_MUTEX_HPP
22 
23 #include "compiler.hpp"
24 #include "exception.hpp"
25 
26 
27 #include <pthread.h>
28 
29 namespace wsrep
30 {
31     /**
32      * Mutex interface.
33      */
34     class mutex
35     {
36     public:
mutex()37         mutex() { }
~mutex()38         virtual ~mutex() { }
39         virtual void lock() = 0;
40         virtual void unlock() = 0;
41         /* Return native handle */
42         virtual void* native() = 0;
43     private:
44         mutex(const mutex& other);
45         mutex& operator=(const mutex& other);
46     };
47 
48     // Default pthread implementation
49     class default_mutex : public wsrep::mutex
50     {
51     public:
default_mutex()52         default_mutex()
53             : wsrep::mutex(),
54               mutex_()
55         {
56             if (pthread_mutex_init(&mutex_, 0))
57             {
58                 throw wsrep::runtime_error("mutex init failed");
59             }
60         }
~default_mutex()61         ~default_mutex()
62         {
63             if (pthread_mutex_destroy(&mutex_)) ::abort();
64         }
65 
lock()66         void lock() WSREP_OVERRIDE
67         {
68             if (pthread_mutex_lock(&mutex_))
69             {
70                 throw wsrep::runtime_error("mutex lock failed");
71             }
72         }
73 
unlock()74         void unlock() WSREP_OVERRIDE
75         {
76             if (pthread_mutex_unlock(&mutex_))
77             {
78                 throw wsrep::runtime_error("mutex unlock failed");
79             }
80         }
81 
native()82         void* native() WSREP_OVERRIDE
83         {
84             return &mutex_;
85         }
86 
87     private:
88         pthread_mutex_t mutex_;
89     };
90 }
91 
92 #endif // WSREP_MUTEX_HPP
93