~ubuntu-branches/ubuntu/wily/davix/wily

« back to all changes in this revision

Viewing changes to deps/boost_intern/src/thread/test/test_lock_concept.cpp

  • Committer: Package Import Robot
  • Author(s): Mattias Ellert
  • Date: 2015-07-31 13:17:55 UTC
  • mfrom: (5.1.3 sid)
  • Revision ID: package-import@ubuntu.com-20150731131755-mizprbmn7ogv33te
Tags: 0.4.1-1
* Update to version 0.4.1
* Implement Multi-Arch support

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
// (C) Copyright 2006-8 Anthony Williams
2
 
// Distributed under the Boost Software License, Version 1.0. (See
3
 
// accompanying file LICENSE_1_0.txt or copy at
4
 
// http://www.boost.org/LICENSE_1_0.txt)
5
 
 
6
 
#define BOOST_THREAD_VERSION 2
7
 
 
8
 
#include <boost/test/unit_test.hpp>
9
 
#include <boost/mpl/vector.hpp>
10
 
#include <boost/thread/mutex.hpp>
11
 
#include <boost/thread/lock_types.hpp>
12
 
#include <boost/thread/shared_mutex.hpp>
13
 
#include <boost/thread/thread_only.hpp>
14
 
#include <boost/thread/recursive_mutex.hpp>
15
 
#include <boost/thread/condition_variable.hpp>
16
 
 
17
 
template<typename Mutex,typename Lock>
18
 
struct test_initially_locked
19
 
{
20
 
    void operator()() const
21
 
    {
22
 
        Mutex m;
23
 
        Lock lock(m);
24
 
 
25
 
        BOOST_CHECK(lock);
26
 
        BOOST_CHECK(lock.owns_lock());
27
 
    }
28
 
};
29
 
 
30
 
template<typename Mutex,typename Lock>
31
 
struct test_initially_unlocked_if_other_thread_has_lock
32
 
{
33
 
    Mutex m;
34
 
    boost::mutex done_mutex;
35
 
    bool done;
36
 
    bool locked;
37
 
    boost::condition_variable done_cond;
38
 
 
39
 
    test_initially_unlocked_if_other_thread_has_lock():
40
 
        done(false),locked(false)
41
 
    {}
42
 
 
43
 
    void locking_thread()
44
 
    {
45
 
        Lock lock(m);
46
 
 
47
 
        boost::lock_guard<boost::mutex> lk(done_mutex);
48
 
        locked=lock.owns_lock();
49
 
        done=true;
50
 
        done_cond.notify_one();
51
 
    }
52
 
 
53
 
    bool is_done() const
54
 
    {
55
 
        return done;
56
 
    }
57
 
 
58
 
 
59
 
    void operator()()
60
 
    {
61
 
        Lock lock(m);
62
 
 
63
 
        typedef test_initially_unlocked_if_other_thread_has_lock<Mutex,Lock> this_type;
64
 
 
65
 
        boost::thread t(&this_type::locking_thread,this);
66
 
 
67
 
        try
68
 
        {
69
 
            {
70
 
                boost::unique_lock<boost::mutex> lk(done_mutex);
71
 
                BOOST_CHECK(done_cond.timed_wait(lk,boost::posix_time::seconds(2),
72
 
                                                 boost::bind(&this_type::is_done,this)));
73
 
                BOOST_CHECK(!locked);
74
 
            }
75
 
 
76
 
            lock.unlock();
77
 
            t.join();
78
 
        }
79
 
        catch(...)
80
 
        {
81
 
            lock.unlock();
82
 
            t.join();
83
 
            throw;
84
 
        }
85
 
    }
86
 
};
87
 
 
88
 
template<typename Mutex,typename Lock>
89
 
struct test_initially_unlocked_with_try_lock_if_other_thread_has_unique_lock
90
 
{
91
 
    Mutex m;
92
 
    boost::mutex done_mutex;
93
 
    bool done;
94
 
    bool locked;
95
 
    boost::condition_variable done_cond;
96
 
 
97
 
    test_initially_unlocked_with_try_lock_if_other_thread_has_unique_lock():
98
 
        done(false),locked(false)
99
 
    {}
100
 
 
101
 
    void locking_thread()
102
 
    {
103
 
        Lock lock(m,boost::try_to_lock);
104
 
 
105
 
        boost::lock_guard<boost::mutex> lk(done_mutex);
106
 
        locked=lock.owns_lock();
107
 
        done=true;
108
 
        done_cond.notify_one();
109
 
    }
110
 
 
111
 
    bool is_done() const
112
 
    {
113
 
        return done;
114
 
    }
115
 
 
116
 
 
117
 
    void operator()()
118
 
    {
119
 
        boost::unique_lock<Mutex> lock(m);
120
 
 
121
 
        typedef test_initially_unlocked_with_try_lock_if_other_thread_has_unique_lock<Mutex,Lock> this_type;
122
 
 
123
 
        boost::thread t(&this_type::locking_thread,this);
124
 
 
125
 
        try
126
 
        {
127
 
            {
128
 
                boost::unique_lock<boost::mutex> lk(done_mutex);
129
 
                BOOST_CHECK(done_cond.timed_wait(lk,boost::posix_time::seconds(2),
130
 
                                                 boost::bind(&this_type::is_done,this)));
131
 
                BOOST_CHECK(!locked);
132
 
            }
133
 
 
134
 
            lock.unlock();
135
 
            t.join();
136
 
        }
137
 
        catch(...)
138
 
        {
139
 
            lock.unlock();
140
 
            t.join();
141
 
            throw;
142
 
        }
143
 
    }
144
 
};
145
 
 
146
 
template<typename Mutex,typename Lock>
147
 
struct test_initially_locked_if_other_thread_has_shared_lock
148
 
{
149
 
    Mutex m;
150
 
    boost::mutex done_mutex;
151
 
    bool done;
152
 
    bool locked;
153
 
    boost::condition_variable done_cond;
154
 
 
155
 
    test_initially_locked_if_other_thread_has_shared_lock():
156
 
        done(false),locked(false)
157
 
    {}
158
 
 
159
 
    void locking_thread()
160
 
    {
161
 
        Lock lock(m);
162
 
 
163
 
        boost::lock_guard<boost::mutex> lk(done_mutex);
164
 
        locked=lock.owns_lock();
165
 
        done=true;
166
 
        done_cond.notify_one();
167
 
    }
168
 
 
169
 
    bool is_done() const
170
 
    {
171
 
        return done;
172
 
    }
173
 
 
174
 
 
175
 
    void operator()()
176
 
    {
177
 
        boost::shared_lock<Mutex> lock(m);
178
 
 
179
 
        typedef test_initially_locked_if_other_thread_has_shared_lock<Mutex,Lock> this_type;
180
 
 
181
 
        boost::thread t(&this_type::locking_thread,this);
182
 
 
183
 
        try
184
 
        {
185
 
            {
186
 
                boost::unique_lock<boost::mutex> lk(done_mutex);
187
 
                BOOST_CHECK(done_cond.timed_wait(lk,boost::posix_time::seconds(2),
188
 
                                                 boost::bind(&this_type::is_done,this)));
189
 
                BOOST_CHECK(locked);
190
 
            }
191
 
 
192
 
            lock.unlock();
193
 
            t.join();
194
 
        }
195
 
        catch(...)
196
 
        {
197
 
            lock.unlock();
198
 
            t.join();
199
 
            throw;
200
 
        }
201
 
    }
202
 
};
203
 
 
204
 
template<typename Mutex,typename Lock>
205
 
struct test_initially_unlocked_with_defer_lock_parameter
206
 
{
207
 
    void operator()() const
208
 
    {
209
 
        Mutex m;
210
 
        Lock lock(m,boost::defer_lock);
211
 
 
212
 
        BOOST_CHECK(!lock);
213
 
        BOOST_CHECK(!lock.owns_lock());
214
 
    }
215
 
};
216
 
 
217
 
template<typename Mutex,typename Lock>
218
 
struct test_initially_locked_with_adopt_lock_parameter
219
 
{
220
 
    void operator()() const
221
 
    {
222
 
        Mutex m;
223
 
        m.lock();
224
 
        Lock lock(m,boost::adopt_lock);
225
 
 
226
 
        BOOST_CHECK(lock);
227
 
        BOOST_CHECK(lock.owns_lock());
228
 
    }
229
 
};
230
 
template<typename Mutex,typename Lock>
231
 
struct test_initially_lock_shared_with_adopt_lock_parameter
232
 
{
233
 
    void operator()() const
234
 
    {
235
 
        Mutex m;
236
 
        m.lock_shared();
237
 
        Lock lock(m,boost::adopt_lock);
238
 
 
239
 
        BOOST_CHECK(lock);
240
 
        BOOST_CHECK(lock.owns_lock());
241
 
    }
242
 
};
243
 
 
244
 
 
245
 
template<typename Mutex,typename Lock>
246
 
struct test_unlocked_after_unlock_called
247
 
{
248
 
    void operator()() const
249
 
    {
250
 
        Mutex m;
251
 
        Lock lock(m);
252
 
        lock.unlock();
253
 
        BOOST_CHECK(!lock);
254
 
        BOOST_CHECK(!lock.owns_lock());
255
 
    }
256
 
};
257
 
 
258
 
template<typename Mutex,typename Lock>
259
 
struct test_locked_after_lock_called
260
 
{
261
 
    void operator()() const
262
 
    {
263
 
        Mutex m;
264
 
        Lock lock(m,boost::defer_lock);
265
 
        lock.lock();
266
 
        BOOST_CHECK(lock);
267
 
        BOOST_CHECK(lock.owns_lock());
268
 
    }
269
 
};
270
 
 
271
 
template<typename Mutex,typename Lock>
272
 
struct test_locked_after_try_lock_called
273
 
{
274
 
    void operator()() const
275
 
    {
276
 
        Mutex m;
277
 
        Lock lock(m,boost::defer_lock);
278
 
        lock.try_lock();
279
 
        BOOST_CHECK(lock);
280
 
        BOOST_CHECK(lock.owns_lock());
281
 
    }
282
 
};
283
 
 
284
 
template<typename Mutex,typename Lock>
285
 
struct test_unlocked_after_try_lock_if_other_thread_has_lock
286
 
{
287
 
    Mutex m;
288
 
    boost::mutex done_mutex;
289
 
    bool done;
290
 
    bool locked;
291
 
    boost::condition_variable done_cond;
292
 
 
293
 
    test_unlocked_after_try_lock_if_other_thread_has_lock():
294
 
        done(false),locked(false)
295
 
    {}
296
 
 
297
 
    void locking_thread()
298
 
    {
299
 
        Lock lock(m,boost::defer_lock);
300
 
 
301
 
        boost::lock_guard<boost::mutex> lk(done_mutex);
302
 
        locked=lock.owns_lock();
303
 
        done=true;
304
 
        done_cond.notify_one();
305
 
    }
306
 
 
307
 
    bool is_done() const
308
 
    {
309
 
        return done;
310
 
    }
311
 
 
312
 
 
313
 
    void operator()()
314
 
    {
315
 
        Lock lock(m);
316
 
 
317
 
        typedef test_unlocked_after_try_lock_if_other_thread_has_lock<Mutex,Lock> this_type;
318
 
 
319
 
        boost::thread t(&this_type::locking_thread,this);
320
 
 
321
 
        try
322
 
        {
323
 
            {
324
 
                boost::unique_lock<boost::mutex> lk(done_mutex);
325
 
                BOOST_CHECK(done_cond.timed_wait(lk,boost::posix_time::seconds(2),
326
 
                                                 boost::bind(&this_type::is_done,this)));
327
 
                BOOST_CHECK(!locked);
328
 
            }
329
 
 
330
 
            lock.unlock();
331
 
            t.join();
332
 
        }
333
 
        catch(...)
334
 
        {
335
 
            lock.unlock();
336
 
            t.join();
337
 
            throw;
338
 
        }
339
 
    }
340
 
};
341
 
 
342
 
template<typename Mutex,typename Lock>
343
 
struct test_throws_if_lock_called_when_already_locked
344
 
{
345
 
    void operator()() const
346
 
    {
347
 
        Mutex m;
348
 
        Lock lock(m);
349
 
 
350
 
        BOOST_CHECK_THROW( lock.lock(), boost::lock_error );
351
 
    }
352
 
};
353
 
 
354
 
template<typename Mutex,typename Lock>
355
 
struct test_throws_if_try_lock_called_when_already_locked
356
 
{
357
 
    void operator()() const
358
 
    {
359
 
        Mutex m;
360
 
        Lock lock(m);
361
 
 
362
 
        BOOST_CHECK_THROW( lock.try_lock(), boost::lock_error );
363
 
    }
364
 
};
365
 
 
366
 
template<typename Mutex,typename Lock>
367
 
struct test_throws_if_unlock_called_when_already_unlocked
368
 
{
369
 
    void operator()() const
370
 
    {
371
 
        Mutex m;
372
 
        Lock lock(m);
373
 
        lock.unlock();
374
 
 
375
 
        BOOST_CHECK_THROW( lock.unlock(), boost::lock_error );
376
 
    }
377
 
};
378
 
template<typename Lock>
379
 
struct test_default_constructed_has_no_mutex_and_unlocked
380
 
{
381
 
    void operator()() const
382
 
    {
383
 
        Lock l;
384
 
        BOOST_CHECK(!l.mutex());
385
 
        BOOST_CHECK(!l.owns_lock());
386
 
    }
387
 
};
388
 
 
389
 
 
390
 
template<typename Mutex,typename Lock>
391
 
struct test_locks_can_be_swapped
392
 
{
393
 
    void operator()() const
394
 
    {
395
 
        Mutex m1;
396
 
        Mutex m2;
397
 
        Mutex m3;
398
 
 
399
 
        Lock l1(m1);
400
 
        Lock l2(m2);
401
 
 
402
 
        BOOST_CHECK_EQUAL(l1.mutex(),&m1);
403
 
        BOOST_CHECK_EQUAL(l2.mutex(),&m2);
404
 
 
405
 
        l1.swap(l2);
406
 
 
407
 
        BOOST_CHECK_EQUAL(l1.mutex(),&m2);
408
 
        BOOST_CHECK_EQUAL(l2.mutex(),&m1);
409
 
 
410
 
        swap(l1,l2);
411
 
 
412
 
        BOOST_CHECK_EQUAL(l1.mutex(),&m1);
413
 
        BOOST_CHECK_EQUAL(l2.mutex(),&m2);
414
 
 
415
 
#if 0
416
 
        l1.swap(Lock(m3));
417
 
 
418
 
        BOOST_CHECK_EQUAL(l1.mutex(),&m3);
419
 
#endif
420
 
 
421
 
    }
422
 
};
423
 
 
424
 
template<typename Mutex,typename Lock>
425
 
void test_lock_is_scoped_lock_concept_for_mutex()
426
 
{
427
 
    test_default_constructed_has_no_mutex_and_unlocked<Lock>()();
428
 
    test_initially_locked<Mutex,Lock>()();
429
 
    test_initially_unlocked_with_defer_lock_parameter<Mutex,Lock>()();
430
 
    test_initially_locked_with_adopt_lock_parameter<Mutex,Lock>()();
431
 
    test_unlocked_after_unlock_called<Mutex,Lock>()();
432
 
    test_locked_after_lock_called<Mutex,Lock>()();
433
 
    test_throws_if_lock_called_when_already_locked<Mutex,Lock>()();
434
 
    test_throws_if_unlock_called_when_already_unlocked<Mutex,Lock>()();
435
 
    test_locks_can_be_swapped<Mutex,Lock>()();
436
 
    test_locked_after_try_lock_called<Mutex,Lock>()();
437
 
    test_throws_if_try_lock_called_when_already_locked<Mutex,Lock>()();
438
 
    test_unlocked_after_try_lock_if_other_thread_has_lock<Mutex,Lock>()();
439
 
}
440
 
 
441
 
 
442
 
BOOST_TEST_CASE_TEMPLATE_FUNCTION(test_scoped_lock_concept,Mutex)
443
 
{
444
 
    typedef typename Mutex::scoped_lock Lock;
445
 
 
446
 
    test_lock_is_scoped_lock_concept_for_mutex<Mutex,Lock>();
447
 
}
448
 
 
449
 
BOOST_TEST_CASE_TEMPLATE_FUNCTION(test_unique_lock_is_scoped_lock,Mutex)
450
 
{
451
 
    typedef boost::unique_lock<Mutex> Lock;
452
 
 
453
 
    test_lock_is_scoped_lock_concept_for_mutex<Mutex,Lock>();
454
 
}
455
 
 
456
 
BOOST_TEST_CASE_TEMPLATE_FUNCTION(test_scoped_try_lock_concept,Mutex)
457
 
{
458
 
    typedef typename Mutex::scoped_try_lock Lock;
459
 
 
460
 
    test_default_constructed_has_no_mutex_and_unlocked<Lock>()();
461
 
    test_initially_locked<Mutex,Lock>()();
462
 
    test_initially_unlocked_if_other_thread_has_lock<Mutex,Lock>()();
463
 
    test_initially_unlocked_with_defer_lock_parameter<Mutex,Lock>()();
464
 
    test_initially_locked_with_adopt_lock_parameter<Mutex,Lock>()();
465
 
    test_unlocked_after_unlock_called<Mutex,Lock>()();
466
 
    test_locked_after_lock_called<Mutex,Lock>()();
467
 
    test_locked_after_try_lock_called<Mutex,Lock>()();
468
 
    test_unlocked_after_try_lock_if_other_thread_has_lock<Mutex,Lock>()();
469
 
    test_throws_if_lock_called_when_already_locked<Mutex,Lock>()();
470
 
    test_throws_if_try_lock_called_when_already_locked<Mutex,Lock>()();
471
 
    test_throws_if_unlock_called_when_already_unlocked<Mutex,Lock>()();
472
 
    test_locks_can_be_swapped<Mutex,Lock>()();
473
 
}
474
 
 
475
 
struct dummy_shared_mutex
476
 
{
477
 
    bool locked;
478
 
    bool shared_locked;
479
 
    bool shared_unlocked;
480
 
    bool shared_timed_locked_relative;
481
 
    bool shared_timed_locked_absolute;
482
 
    bool timed_locked_relative;
483
 
    bool timed_locked_absolute;
484
 
 
485
 
    dummy_shared_mutex():
486
 
        locked(false),shared_locked(false),shared_unlocked(false),
487
 
        shared_timed_locked_relative(false),
488
 
        shared_timed_locked_absolute(false),
489
 
        timed_locked_relative(false),
490
 
        timed_locked_absolute(false)
491
 
    {}
492
 
 
493
 
    void lock()
494
 
    {
495
 
        locked=true;
496
 
    }
497
 
 
498
 
    void lock_shared()
499
 
    {
500
 
        shared_locked=true;
501
 
    }
502
 
 
503
 
    void unlock()
504
 
    {}
505
 
 
506
 
    void unlock_shared()
507
 
    {
508
 
        shared_unlocked=true;
509
 
    }
510
 
 
511
 
    bool timed_lock_shared(boost::system_time)
512
 
    {
513
 
        shared_timed_locked_absolute=true;
514
 
        return false;
515
 
    }
516
 
    template<typename Duration>
517
 
    bool timed_lock_shared(Duration)
518
 
    {
519
 
        shared_timed_locked_relative=true;
520
 
        return false;
521
 
    }
522
 
    bool timed_lock(boost::system_time)
523
 
    {
524
 
        timed_locked_absolute=true;
525
 
        return false;
526
 
    }
527
 
    template<typename Duration>
528
 
    bool timed_lock(Duration)
529
 
    {
530
 
        timed_locked_relative=true;
531
 
        return false;
532
 
    }
533
 
 
534
 
};
535
 
 
536
 
 
537
 
void test_shared_lock()
538
 
{
539
 
    typedef boost::shared_mutex Mutex;
540
 
    typedef boost::shared_lock<Mutex> Lock;
541
 
 
542
 
    test_default_constructed_has_no_mutex_and_unlocked<Lock>()();
543
 
    test_initially_locked<Mutex,Lock>()();
544
 
    test_initially_unlocked_with_try_lock_if_other_thread_has_unique_lock<Mutex,Lock>()();
545
 
    test_initially_locked_if_other_thread_has_shared_lock<Mutex,Lock>()();
546
 
    test_initially_unlocked_with_defer_lock_parameter<Mutex,Lock>()();
547
 
    test_initially_lock_shared_with_adopt_lock_parameter<Mutex,Lock>()();
548
 
    test_unlocked_after_unlock_called<Mutex,Lock>()();
549
 
    test_locked_after_lock_called<Mutex,Lock>()();
550
 
    test_locked_after_try_lock_called<Mutex,Lock>()();
551
 
    test_throws_if_lock_called_when_already_locked<Mutex,Lock>()();
552
 
    test_throws_if_try_lock_called_when_already_locked<Mutex,Lock>()();
553
 
    test_throws_if_unlock_called_when_already_unlocked<Mutex,Lock>()();
554
 
    test_locks_can_be_swapped<Mutex,Lock>()();
555
 
 
556
 
    dummy_shared_mutex dummy;
557
 
    boost::shared_lock<dummy_shared_mutex> lk(dummy);
558
 
    BOOST_CHECK(dummy.shared_locked);
559
 
    lk.unlock();
560
 
    BOOST_CHECK(dummy.shared_unlocked);
561
 
    lk.timed_lock(boost::posix_time::milliseconds(5));
562
 
    BOOST_CHECK(dummy.shared_timed_locked_relative);
563
 
    lk.timed_lock(boost::get_system_time());
564
 
    BOOST_CHECK(dummy.shared_timed_locked_absolute);
565
 
}
566
 
 
567
 
boost::unit_test::test_suite* init_unit_test_suite(int, char*[])
568
 
{
569
 
    boost::unit_test::test_suite* test =
570
 
        BOOST_TEST_SUITE("Boost.Threads: lock concept test suite");
571
 
 
572
 
    typedef boost::mpl::vector<boost::mutex,boost::try_mutex,boost::timed_mutex,
573
 
        boost::recursive_mutex,boost::recursive_try_mutex,boost::recursive_timed_mutex> mutex_types_with_scoped_lock;
574
 
 
575
 
    test->add(BOOST_TEST_CASE_TEMPLATE(test_scoped_lock_concept,mutex_types_with_scoped_lock));
576
 
 
577
 
    typedef boost::mpl::vector<boost::try_mutex,boost::timed_mutex,
578
 
        boost::recursive_try_mutex,boost::recursive_timed_mutex> mutex_types_with_scoped_try_lock;
579
 
 
580
 
    test->add(BOOST_TEST_CASE_TEMPLATE(test_scoped_try_lock_concept,mutex_types_with_scoped_try_lock));
581
 
 
582
 
    typedef boost::mpl::vector<boost::mutex,boost::try_mutex,boost::timed_mutex,
583
 
        boost::recursive_mutex,boost::recursive_try_mutex,boost::recursive_timed_mutex,boost::shared_mutex> all_mutex_types;
584
 
 
585
 
    test->add(BOOST_TEST_CASE_TEMPLATE(test_unique_lock_is_scoped_lock,all_mutex_types));
586
 
    test->add(BOOST_TEST_CASE(&test_shared_lock));
587
 
 
588
 
    return test;
589
 
}
590