source: calamares/trunk/fuentes/src/libcalamares/kdsingleapplicationguard/kdlockedsharedmemorypointer.cpp @ 7538

Last change on this file since 7538 was 7538, checked in by kbut, 13 months ago

sync with github

File size: 12.6 KB
Line 
1#include "kdlockedsharedmemorypointer.h"
2
3#if QT_VERSION >= 0x040400 || defined( DOXYGEN_RUN )
4#ifndef QT_NO_SHAREDMEMORY
5
6namespace kdtools
7{
8}
9using namespace kdtools;
10
11KDLockedSharedMemoryPointerBase::KDLockedSharedMemoryPointerBase( QSharedMemory * m )
12    : locker( m ),
13      mem( m )
14{
15
16}
17
18KDLockedSharedMemoryPointerBase::KDLockedSharedMemoryPointerBase( QSharedMemory & m )
19    : locker( &m ),
20      mem( &m )
21{
22
23}
24
25KDLockedSharedMemoryPointerBase::~KDLockedSharedMemoryPointerBase() {}
26
27void * KDLockedSharedMemoryPointerBase::get() {
28    return mem ? mem->data() : 0 ;
29}
30
31const void * KDLockedSharedMemoryPointerBase::get() const {
32    return mem ? mem->data() : 0 ;
33}
34
35size_t KDLockedSharedMemoryPointerBase::byteSize() const {
36    return mem ? mem->size() : 0;
37}
38
39/*!
40  \class KDLockedSharedMemoryPointer
41  \ingroup core raii smartptr
42  \brief Locking pointer for Qt shared memory segments
43  \since_c 2.1
44
45  (The exception safety of this class has not been evaluated yet.)
46
47  KDLockedSharedMemoryPointer is a smart immutable pointer, which gives convenient and safe access to a QSharedMemory data segment.
48  The content of a KDLockedSharedMemoryPointer cannot be changed during it's lifetime.
49
50  You can use this class like a normal pointer to the shared memory segment and be sure it's locked while accessing it.
51  \note You can only put simple types/structs/classes into it. structs and classes shall not contain any other pointers. See the
52  documentation of QSharedMemory for details.
53*/
54
55/*!
56  \fn KDLockedSharedMemoryPointer::KDLockedSharedMemoryPointer( QSharedMemory * mem )
57
58  Constructor. Constructs a KDLockedSharedMemory pointer which points to the data segment of \a mem.
59  The constructor locks \a mem. If the memory segment is already locked by another process, this constructor
60  blocks until the lock is released.
61
62  \post data() == mem->data() and the memory segment has been locked
63*/
64
65/*!
66  \fn KDLockedSharedMemoryPointer::KDLockedSharedMemoryPointer( QSharedMemory & mem )
67
68  \overload
69
70  \post data() == mem.data() and the memory segment has been locked
71*/
72
73/*!
74  \fn KDLockedSharedMemoryPointer::~KDLockedSharedMemoryPointer()
75
76  Destructor. Unlocks the shared memory segment.
77
78  \post The shared memory segment has been unlocked
79*/
80
81/*!
82  \fn T * KDLockedSharedMemoryPointer::get()
83
84  \returns a pointer to the contained object.
85*/
86
87/*!
88  \fn const T * KDLockedSharedMemoryPointer::get() const
89
90  \returns a const pointer to the contained object
91  \overload
92*/
93
94/*!
95  \fn T * KDLockedSharedMemoryPointer::data()
96
97  Equivalent to get(), provided for consistency with Qt naming conventions.
98*/
99
100/*!
101  \fn const T * KDLockedSharedMemoryPointer::data() const
102
103  \overload
104*/
105
106/*!
107  \fn T & KDLockedSharedMemoryPointer::operator*()
108
109  Dereference operator. Returns \link get() *get()\endlink.
110*/
111
112/*!
113  \fn const T & KDLockedSharedMemoryPointer::operator*() const
114
115  Dereference operator. Returns \link get() *get()\endlink.
116  \overload
117*/
118
119/*!
120  \fn T * KDLockedSharedMemoryPointer::operator->()
121
122  Member-by-pointer operator. Returns get().
123*/
124
125/*!
126  \fn const T * KDLockedSharedMemoryPointer::operator->() const
127
128  Member-by-pointer operator. Returns get().
129  \overload
130*/
131
132/*!
133  \class KDLockedSharedMemoryArray
134  \ingroup core raii smartptr
135  \brief Locking array pointer to Qt shared memory segments
136  \since_c 2.1
137
138  (The exception safety of this class has not been evaluated yet.)
139
140  KDLockedSharedMemoryArray is a smart immutable pointer, which gives convenient and safe access to array data stored in a QSharedMemory
141  data segment.
142  The content of a KDLockedSharedMemoryArray cannot be changed during it's lifetime.
143
144  You can use this class like a normal pointer to the shared memory segment and be sure it's locked while accessing it.
145  \note You can only put arrays of simple types/structs/classes into it. structs and classes shall not contain any other pointers. See the
146  documentation of QSharedMemory for details.
147
148  \sa KDLockedSharedMemoryPointer
149*/
150
151/*!
152  \fn KDLockedSharedMemoryArray::KDLockedSharedMemoryArray( QSharedMemory* mem )
153  Constructor. Constructs a KDLockedSharedMemoryArray which points to the data segment of \a mem. The constructor locks \a mem. If the memory
154  segment is already locked by another process, this constructor blocks until the lock is release.
155
156  \post get() == mem->data() and the memory segment has been locked
157*/
158
159/*!
160  \fn KDLockedSharedMemoryArray::KDLockedSharedMemoryArray( QSharedMemory& mem )
161  \overload
162
163  \post get() == mem->data() and the memory segment has been locked
164*/
165
166
167/*!
168  \typedef KDLockedSharedMemoryArray::size_type
169  Typedef for std::size_t. Provided for STL compatibility.
170*/
171
172/*!
173  \typedef KDLockedSharedMemoryArray::difference_type
174  Typedef for std::ptrdiff_t. Provided for STL compatibility.
175*/
176
177/*!
178  \typedef KDLockedSharedMemoryArray::iterator
179  Typedef for T*. Provided for STL compatibility.
180  \since_t 2.2
181*/
182
183/*!
184  \typedef KDLockedSharedMemoryArray::const_iterator
185  Typedef for const T*. Provided for STL compatibility.
186  \since_t 2.2
187*/
188
189/*!
190  \typedef KDLockedSharedMemoryArray::reverse_iterator
191  Typedef for std::reverse_iterator< \link KDLockedSharedMemoryArray::iterator iterator\endlink >. Provided for STL compatibility.
192  \since_t 2.2
193*/
194
195/*!
196  \typedef KDLockedSharedMemoryArray::const_reverse_iterator
197  Typedef for std::reverse_iterator< \link KDLockedSharedMemoryArray::const_iterator const_iterator\endlink >. Provided for STL compatibility.
198  \since_t 2.2
199*/
200
201/*!
202  \fn KDLockedSharedMemoryArray::iterator KDLockedSharedMemoryArray::begin()
203  Returns an \link KDLockedSharedMemoryArray::iterator iterator\endlink pointing to the first item of the array.
204  \since_f 2.2
205*/
206
207/*!
208  \fn KDLockedSharedMemoryArray::const_iterator KDLockedSharedMemoryArray::begin() const
209  \overload
210  \since_f 2.2
211*/
212
213/*!
214  \fn KDLockedSharedMemoryArray::iterator KDLockedSharedMemoryArray::end()
215  Returns an \link KDLockedSharedMemoryArray::iterator iterator\endlink pointing to the item after the last item of the array.
216  \since_f 2.2
217*/
218
219/*!
220  \fn KDLockedSharedMemoryArray::const_iterator KDLockedSharedMemoryArray::end() const
221  \overload
222  \since_f 2.2
223*/
224
225/*!
226  \fn KDLockedSharedMemoryArray::reverse_iterator KDLockedSharedMemoryArray::rbegin()
227  Returns an \link KDLockedSharedMemoryArray::reverse_iterator reverse_iterator\endlink pointing to the item after the last item of the array.
228  \since_f 2.2
229*/
230
231/*!
232  \fn KDLockedSharedMemoryArray::const_reverse_iterator KDLockedSharedMemoryArray::rbegin() const
233  \overload
234  \since_f 2.2
235*/
236
237/*!
238  \fn KDLockedSharedMemoryArray::reverse_iterator KDLockedSharedMemoryArray::rend()
239  Returns an \link KDLockedSharedMemoryArray::reverse_iterator reverse_iterator\endlink pointing to the first item of the array.
240  \since_f 2.2
241*/
242
243/*!
244  \fn KDLockedSharedMemoryArray::const_reverse_iterator KDLockedSharedMemoryArray::rend() const
245  \overload
246  \since_f 2.2
247*/
248
249/*!
250  \fn KDLockedSharedMemoryArray::size_type KDLockedSharedMemoryArray::size() const
251  Returns the size of this array. The size is calculated from the storage size of T and
252  the size of the shared memory segment.
253  \since_f 2.2
254*/
255
256/*!
257  \fn T& KDLockedSharedMemoryArray::operator[]( difference_type n )
258  Array access operator. Returns a reference to the item at index position \a n.
259*/
260
261/*!
262  \fn const T& KDLockedSharedMemoryArray::operator[]( difference_type n ) const
263  \overload
264*/
265
266/*!
267 \fn T& KDLockedSharedMemoryArray::front()
268 Returns a reference to the first item in the array. This is the same as operator[](0).
269*/
270
271/*!
272 \fn const T& KDLockedSharedMemoryArray::front() const
273 \overload
274*/
275
276/*!
277 \fn T& KDLockedSharedMemoryArray::back()
278 Returns a reference to the last item in the array. This is the same as operator[](size()-1).
279 \since_f 2.2
280*/
281
282/*!
283 \fn const T& KDLockedSharedMemoryArray::back() const
284 \overload
285 \since_f 2.2
286*/
287
288
289#ifdef eKDTOOLSCORE_UNITTESTS
290
291#include <KDUnitTest/Test>
292
293#include <QThread>
294#include <QUuid>
295
296namespace
297{
298    struct TestStruct
299    {
300        TestStruct( uint nn = 0 )
301            : n( nn ),
302              f( 0.0 ),
303              c( '\0' ),
304              b( false )
305        {
306        }
307        uint n;
308        double f;
309        char c;
310        bool b;
311    };
312
313    bool operator==( const TestStruct& lhs, const TestStruct& rhs )
314    {
315        return lhs.n == rhs.n && lhs.f == rhs.f && lhs.c == rhs.c && lhs.b == rhs.b;
316    }
317
318    class TestThread : public QThread
319    {
320    public:
321        TestThread( const QString& key )
322            : mem( key )
323        {
324            mem.attach();
325        }
326
327        void run()
328        {
329            while( true )
330            {
331                msleep( 100 );
332                kdtools::KDLockedSharedMemoryPointer< TestStruct > p( &mem );
333                if( !p->b )
334                    continue;
335
336                p->n = 5;
337                p->f = 3.14;
338                p->c = 'A';
339                p->b = false;
340                return;
341            }
342        }
343
344        QSharedMemory mem;
345    };
346
347    bool isConst( TestStruct* )
348    {
349        return false;
350    }
351
352    bool isConst( const TestStruct* )
353    {
354        return true;
355    }
356}
357
358
359KDAB_UNITTEST_SIMPLE( KDLockedSharedMemoryPointer, "kdcoretools" ) {
360
361    const QString key = QUuid::createUuid();
362    QSharedMemory mem( key );
363    const bool created = mem.create( sizeof( TestStruct ) );
364    assertTrue( created );
365    if ( !created )
366        return; // don't execute tests if shm coulnd't be created
367
368    // On Windows, shared mem is only available in increments of page
369    // size (4k), so don't fail if the segment is larger:
370    const unsigned long mem_size = mem.size();
371    assertGreaterOrEqual( mem_size, sizeof( TestStruct ) );
372
373    {
374        kdtools::KDLockedSharedMemoryPointer< TestStruct > p( &mem );
375        assertTrue( p );
376        *p = TestStruct();
377        assertEqual( p->n, 0u );
378        assertEqual( p->f, 0.0 );
379        assertEqual( p->c, '\0' );
380        assertFalse( p->b );
381    }
382
383    {
384        TestThread thread( key );
385        assertEqual( thread.mem.key().toStdString(), key.toStdString() );
386        assertEqual( static_cast< unsigned long >( thread.mem.size() ), mem_size );
387        thread.start();
388
389        assertTrue( thread.isRunning() );
390        thread.wait( 2000 );
391        assertTrue( thread.isRunning() );
392
393        {
394            kdtools::KDLockedSharedMemoryPointer< TestStruct > p( &mem );
395            p->b = true;
396        }
397
398        thread.wait( 2000 );
399        assertFalse( thread.isRunning() );
400    }
401
402    {
403        kdtools::KDLockedSharedMemoryPointer< TestStruct > p( &mem );
404        assertEqual( p->n, 5u );
405        assertEqual( p->f, 3.14 );
406        assertEqual( p->c, 'A' );
407        assertFalse( p->b );
408    }
409
410    {
411        kdtools::KDLockedSharedMemoryPointer< TestStruct > p( mem );
412        assertEqual( mem.data(), p.get() );
413        assertEqual( p.get(), p.operator->() );
414        assertEqual( p.get(), &(*p) );
415        assertEqual( p.get(), p.data() );
416        assertFalse( isConst( p.get() ) );
417    }
418
419    {
420        const kdtools::KDLockedSharedMemoryPointer< TestStruct > p( &mem );
421        assertEqual( mem.data(), p.get() );
422        assertEqual( p.get(), p.operator->() );
423        assertEqual( p.get(), &(*p) );
424        assertEqual( p.get(), p.data() );
425        assertTrue( isConst( p.get() ) );
426    }
427
428    {
429        QSharedMemory mem2( key + key );
430        const bool created2 = mem2.create( 16 * sizeof( TestStruct ) );
431        assertTrue( created2 );
432        if ( !created2 )
433            return; // don't execute tests if shm coulnd't be created
434
435        kdtools::KDLockedSharedMemoryArray<TestStruct> a( mem2 );
436        assertTrue( a );
437        assertEqual( a.get(), mem2.data() );
438        assertEqual( &a[0], a.get() );
439
440        a[1] = a[0];
441        assertTrue( a[0] == a[1] );
442
443        TestStruct ts;
444        ts.n = 5;
445        ts.f = 3.14;
446        a[0] = ts;
447        assertFalse( a[0] == a[1] );
448        assertEqual( a.front().n, ts.n );
449        assertEqual( a[0].f, ts.f );
450        a[0].n = 10;
451        assertEqual( a.front().n, 10u );
452        ts = a[0];
453        assertEqual( ts.n, 10u );
454
455        std::vector< TestStruct > v;
456        for( uint i = 0; i < a.size(); ++i )
457            v.push_back( TestStruct( i ) );
458
459        std::copy( v.begin(), v.end(), a.begin() );
460        for( uint i = 0; i < a.size(); ++i )
461            assertEqual( a[ i ].n, i );
462        assertEqual( a.front().n, 0u );
463        assertEqual( a.back().n, a.size() - 1 );
464
465        std::copy( v.begin(), v.end(), a.rbegin() );
466        for( uint i = 0; i < a.size(); ++i )
467            assertEqual( a[ i ].n, a.size() - 1 - i );
468        assertEqual( a.front().n, a.size() - 1 );
469        assertEqual( a.back().n, 0u );
470     }
471
472}
473#endif // KDTOOLSCORE_UNITTESTS
474#endif // QT_NO_SHAREDMEMORY
475#endif // QT_VERSION >= 0x040400 || defined( DOXYGEN_RUN )
Note: See TracBrowser for help on using the repository browser.