1212#include < sys/mman.h>
1313#include < sys/stat.h>
1414#include < fcntl.h>
15- #include < pthread.h>
1615#include < time.h>
1716
18- struct header_t {
19- pthread_rwlock_t rwlock;
20- uint lockcounter {0 };
21- };
22-
23-
24- static void rwlock_init (pthread_rwlock_t *rwlock)
25- {
26- pthread_rwlockattr_t attr;
27-
28- int res = pthread_rwlockattr_init (&attr);
29- Q_ASSERT (!res);
30- res = pthread_rwlockattr_setpshared (&attr, PTHREAD_PROCESS_SHARED);
31- Q_ASSERT (!res);
32- res = pthread_rwlock_init (rwlock, &attr);
33- Q_ASSERT (!res);
34- }
35-
3617
3718TSharedMemory::TSharedMemory (const QString &name) :
3819 _name(name)
@@ -52,17 +33,12 @@ TSharedMemory::~TSharedMemory()
5233
5334bool TSharedMemory::create (size_t size)
5435{
55- static const header_t INIT_HEADER = []() {
56- static header_t header;
57- rwlock_init (&header.rwlock );
58- return header;
59- }();
60-
6136 if (_ptr || size == 0 || _name.isEmpty ()) {
6237 return false ;
6338 }
6439
6540 struct stat st;
41+ header_t *header = nullptr ;
6642
6743 // Creates shared memory
6844 _fd = shm_open (qUtf8Printable (_name), O_CREAT | O_RDWR | O_CLOEXEC, S_IRUSR | S_IWUSR);
@@ -90,7 +66,9 @@ bool TSharedMemory::create(size_t size)
9066 goto error;
9167 }
9268
93- std::memcpy (_ptr, &INIT_HEADER, sizeof (INIT_HEADER));
69+ header = new (_ptr) header_t {};
70+ initRwlock (header);
71+
9472 _size = size;
9573 tSystemDebug (" SharedMemory created. name:{} size:{}" , qUtf8Printable (_name), (qulonglong)_size);
9674 return true ;
@@ -202,73 +180,3 @@ size_t TSharedMemory::size() const
202180{
203181 return _size;
204182}
205-
206-
207- bool TSharedMemory::lockForRead ()
208- {
209- #ifdef Q_OS_LINUX
210- struct timespec timeout;
211- header_t *header = (header_t *)_ptr;
212-
213- while (pthread_rwlock_tryrdlock (&header->rwlock ) == EBUSY) {
214- uint cnt = header->lockcounter ;
215- timespec_get (&timeout, TIME_UTC);
216- timeout.tv_sec += 1 ; // 1sec
217-
218- int res = pthread_rwlock_timedrdlock (&header->rwlock , &timeout);
219- if (!res) {
220- // success
221- break ;
222- } else {
223- if (res == ETIMEDOUT && header->lockcounter == cnt) {
224- // resets rwlock object
225- rwlock_init (&header->rwlock );
226- }
227- }
228- }
229- header->lockcounter ++;
230- return true ;
231- #else
232- header_t *header = (header_t *)_ptr;
233- return pthread_rwlock_rdlock (&header->rwlock ) == 0 ;
234- #endif
235- }
236-
237-
238- bool TSharedMemory::lockForWrite ()
239- {
240- #ifdef Q_OS_LINUX
241- struct timespec timeout;
242- header_t *header = (header_t *)_ptr;
243-
244- while (pthread_rwlock_trywrlock (&header->rwlock ) == EBUSY) {
245- uint cnt = header->lockcounter ;
246- timespec_get (&timeout, TIME_UTC);
247- timeout.tv_sec += 1 ; // 1sec
248-
249- int res = pthread_rwlock_timedwrlock (&header->rwlock , &timeout);
250- if (!res) {
251- // success
252- break ;
253- } else {
254- if (res == ETIMEDOUT && header->lockcounter == cnt) {
255- // resets rwlock object
256- rwlock_init (&header->rwlock );
257- }
258- }
259- }
260- header->lockcounter ++;
261- return true ;
262- #else
263- header_t *header = (header_t *)_ptr;
264- return pthread_rwlock_wrlock (&header->rwlock ) == 0 ;
265- #endif
266- }
267-
268-
269- bool TSharedMemory::unlock ()
270- {
271- header_t *header = (header_t *)_ptr;
272- pthread_rwlock_unlock (&header->rwlock );
273- return true ;
274- }
0 commit comments