Project

General

Profile

RE: Exiv2 and VS2017 ยป rwlock.hpp

Robin Mills, 25 Jul 2017 07:36

 
1
// ***************************************************************** -*- C++ -*-
2
/*
3
 * Copyright (C) 2004-2017 Andreas Huggel <ahuggel@gmx.net>
4
 *
5
 * This program is part of the Exiv2 distribution.
6
 *
7
 * This program is free software; you can redistribute it and/or
8
 * modify it under the terms of the GNU General Public License
9
 * as published by the Free Software Foundation; either version 2
10
 * of the License, or (at your option) any later version.
11
 *
12
 * This program is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 * GNU General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU General Public License
18
 * along with this program; if not, write to the Free Software
19
 * Foundation, Inc., 51 Franklin Street, 5th Floor, Boston, MA 02110-1301 USA.
20
 */
21

    
22
#ifndef RW_LOCK_HPP
23
#define RW_LOCK_HPP
24

    
25
#ifdef _MSC_VER
26
#include <windows.h>
27
#else
28
#include <pthread.h>
29
#endif
30

    
31
namespace Exiv2 {
32
#ifdef _MSC_VER
33
        class RWLock
34
        {
35
        public:
36
            RWLock()
37
            {
38
                InitializeCriticalSection(&lock_);
39
            }
40

    
41
            ~RWLock()
42
            {
43
                DeleteCriticalSection(&lock_);
44
            }
45

    
46
            void wrlock() { enter(); }
47

    
48
            bool trywrlock() { return tryenter(); }
49

    
50
            void rdlock() { enter(); }
51

    
52
            bool tryrdlock() { return tryenter(); }
53

    
54
            void rdunlock() { leave(); }
55

    
56
            void wrunlock() { leave(); }
57

    
58
        private:
59
            void enter()
60
            {
61
                EnterCriticalSection(&lock_);
62
            }
63

    
64
            void leave()
65
            {
66
                LeaveCriticalSection(&lock_);
67
            }
68

    
69
            bool tryenter()
70
            {
71
                return 0 != TryEnterCriticalSection(&lock_);
72
            }
73

    
74
        private:
75
            CRITICAL_SECTION lock_;
76
        };
77
#else
78
        /*!
79
         @brief Class to provide a Read-Write Lock
80
        */
81
        // UNIX systems (including MinGW and Cygwin)
82
        class RWLock
83
        {
84
        public:
85
        	//! constructor (acquires the lock)
86
            RWLock(const pthread_rwlockattr_t *attr = 0)
87
            {
88
                pthread_rwlock_init(&rwlock_, attr);
89
            }
90

    
91
        	//! constructor (releases lock)
92
            ~RWLock()
93
            {
94
                pthread_rwlock_destroy(&rwlock_);
95
            }
96

    
97
        	//! acquire rw lock
98
            void wrlock()
99
            {
100
                pthread_rwlock_wrlock(&rwlock_);
101
            }
102

    
103
            //! test to see if the rw lock can be acquired
104
            bool trywrlock()
105
            {
106
                return 0 == pthread_rwlock_trywrlock(&rwlock_);
107
            }
108

    
109
            //! acquire rd lock
110
            void rdlock()
111
            {
112
                pthread_rwlock_rdlock(&rwlock_);
113
            }
114

    
115
            //! test to see if the rd lock can be acquired
116
            bool tryrdlock()
117
            {
118
                return 0 == pthread_rwlock_tryrdlock(&rwlock_);
119
            }
120

    
121
            //! release rw lock
122
            void unlock()
123
            {
124
                pthread_rwlock_unlock(&rwlock_);
125
            }
126

    
127
            //! unlock rd lock
128
            void rdunlock() { unlock(); }
129

    
130
            //! unlock rw lock
131
            void wrunlock() { unlock(); }
132

    
133
        private:
134
        	//! the lock itself
135
            pthread_rwlock_t rwlock_;
136
        };
137
#endif
138

    
139
        /*!
140
         @brief Class to provide a ScopedReadLock.
141
         The lock is applied by the constructor and released by the destructor.
142
        */
143
        class ScopedReadLock
144
        {
145
        public:
146
            //! constructor - locks the object
147
            ScopedReadLock(RWLock &rwlock):
148
                rwlock_(rwlock)
149
            {
150
                rwlock_.rdlock();
151
            }
152

    
153
            //! destructor - unlocks the object used in constructor
154
            ~ScopedReadLock() { rwlock_.rdunlock(); }
155

    
156
        private:
157
        	//! object locked by the constructor (and released by destructor)
158
            RWLock &rwlock_;
159
        };
160

    
161
        /*!
162
         @brief Class to provide a ScopedWriteLock.
163
         The lock is applied by the constructor and released by the destructor.
164
        */
165
        class ScopedWriteLock
166
        {
167
        public:
168
            //! constructor - locks the object
169
            ScopedWriteLock(RWLock &rwlock):
170
                rwlock_(rwlock)
171
            {
172
                rwlock_.wrlock();
173
            }
174

    
175
            //! destructor - unlocks the object used in constructor
176
            ~ScopedWriteLock() { rwlock_.wrunlock(); }
177

    
178
        private:
179
        	//! object locked by the constructor (and released by destructor)
180
            RWLock &rwlock_;
181
        };
182
}
183

    
184
#endif // RW_LOCK_HPP
    (1-1/1)