[WASAPI] fix stream types and frequencies enumeration
[xbmc.git] / xbmc / threads / test / TestSharedSection.cpp
blobfc2ca08a4c9b8b1ebe7813395d7e2dd170c9cbda
1 /*
2 * Copyright (C) 2005-2018 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
7 */
9 #include "threads/Event.h"
10 #include "threads/IRunnable.h"
11 #include "threads/SharedSection.h"
12 #include "threads/test/TestHelpers.h"
14 #include <mutex>
15 #include <shared_mutex>
16 #include <stdio.h>
18 using namespace std::chrono_literals;
20 //=============================================================================
21 // Helper classes
22 //=============================================================================
24 template<class L>
25 class locker : public IRunnable
27 CSharedSection& sec;
28 CEvent* wait;
30 std::atomic<long>* mutex;
31 public:
32 volatile bool haslock;
33 volatile bool obtainedlock;
35 inline locker(CSharedSection& o, std::atomic<long>* mutex_ = NULL, CEvent* wait_ = NULL) :
36 sec(o), wait(wait_), mutex(mutex_), haslock(false), obtainedlock(false) {}
38 inline locker(CSharedSection& o, CEvent* wait_ = NULL) :
39 sec(o), wait(wait_), mutex(NULL), haslock(false), obtainedlock(false) {}
41 void Run() override
43 AtomicGuard g(mutex);
44 L lock(sec);
45 haslock = true;
46 obtainedlock = true;
47 if (wait)
48 wait->Wait();
49 haslock = false;
53 TEST(TestCritSection, General)
55 CCriticalSection sec;
57 std::unique_lock<CCriticalSection> l1(sec);
58 std::unique_lock<CCriticalSection> l2(sec);
61 TEST(TestSharedSection, General)
63 CSharedSection sec;
65 std::shared_lock<CSharedSection> l1(sec);
66 std::shared_lock<CSharedSection> l2(sec);
69 TEST(TestSharedSection, GetSharedLockWhileTryingExclusiveLock)
71 std::atomic<long> mutex(0L);
72 CEvent event;
74 CSharedSection sec;
76 std::shared_lock<CSharedSection> l1(sec); // get a shared lock
78 locker<std::unique_lock<CSharedSection>> l2(sec, &mutex);
79 thread waitThread1(l2); // try to get an exclusive lock
81 EXPECT_TRUE(waitForThread(mutex, 1, 10000ms));
82 std::this_thread::sleep_for(10ms); // still need to give it a chance to move ahead
84 EXPECT_TRUE(!l2.haslock); // this thread is waiting ...
85 EXPECT_TRUE(!l2.obtainedlock); // this thread is waiting ...
87 // now try and get a SharedLock
88 locker<std::shared_lock<CSharedSection>> l3(sec, &mutex, &event);
89 thread waitThread3(l3); // try to get a shared lock
90 EXPECT_TRUE(waitForThread(mutex, 2, 10000ms));
91 std::this_thread::sleep_for(10ms);
92 EXPECT_TRUE(l3.haslock);
94 event.Set();
95 EXPECT_TRUE(waitThread3.timed_join(10000ms));
97 // l3 should have released.
98 EXPECT_TRUE(!l3.haslock);
100 // but the exclusive lock should still not have happened
101 EXPECT_TRUE(!l2.haslock); // this thread is waiting ...
102 EXPECT_TRUE(!l2.obtainedlock); // this thread is waiting ...
104 // let it go
105 l1.unlock(); // the last shared lock leaves.
107 EXPECT_TRUE(waitThread1.timed_join(10000ms));
109 EXPECT_TRUE(l2.obtainedlock); // the exclusive lock was captured
110 EXPECT_TRUE(!l2.haslock); // ... but it doesn't have it anymore
113 TEST(TestSharedSection, TwoCase)
115 CSharedSection sec;
117 CEvent event;
118 std::atomic<long> mutex(0L);
120 locker<std::shared_lock<CSharedSection>> l1(sec, &mutex, &event);
123 std::shared_lock<CSharedSection> lock(sec);
124 thread waitThread1(l1);
126 EXPECT_TRUE(waitForWaiters(event, 1, 10000ms));
127 EXPECT_TRUE(l1.haslock);
129 event.Set();
131 EXPECT_TRUE(waitThread1.timed_join(10000ms));
134 locker<std::shared_lock<CSharedSection>> l2(sec, &mutex, &event);
136 std::unique_lock<CSharedSection> lock(sec); // get exclusive lock
137 thread waitThread2(l2); // thread should block
139 EXPECT_TRUE(waitForThread(mutex, 1, 10000ms));
140 std::this_thread::sleep_for(10ms);
142 EXPECT_TRUE(!l2.haslock);
144 lock.unlock();
146 EXPECT_TRUE(waitForWaiters(event, 1, 10000ms));
147 std::this_thread::sleep_for(10ms);
148 EXPECT_TRUE(l2.haslock);
150 event.Set();
152 EXPECT_TRUE(waitThread2.timed_join(10000ms));
156 TEST(TestMultipleSharedSection, General)
158 CSharedSection sec;
160 CEvent event;
161 std::atomic<long> mutex(0L);
163 locker<std::shared_lock<CSharedSection>> l1(sec, &mutex, &event);
166 std::shared_lock<CSharedSection> lock(sec);
167 thread waitThread1(l1);
169 EXPECT_TRUE(waitForThread(mutex, 1, 10000ms));
170 std::this_thread::sleep_for(10ms);
172 EXPECT_TRUE(l1.haslock);
174 event.Set();
176 EXPECT_TRUE(waitThread1.timed_join(10000ms));
179 locker<std::shared_lock<CSharedSection>> l2(sec, &mutex, &event);
180 locker<std::shared_lock<CSharedSection>> l3(sec, &mutex, &event);
181 locker<std::shared_lock<CSharedSection>> l4(sec, &mutex, &event);
182 locker<std::shared_lock<CSharedSection>> l5(sec, &mutex, &event);
184 std::unique_lock<CSharedSection> lock(sec);
185 thread waitThread1(l2);
186 thread waitThread2(l3);
187 thread waitThread3(l4);
188 thread waitThread4(l5);
190 EXPECT_TRUE(waitForThread(mutex, 4, 10000ms));
191 std::this_thread::sleep_for(10ms);
193 EXPECT_TRUE(!l2.haslock);
194 EXPECT_TRUE(!l3.haslock);
195 EXPECT_TRUE(!l4.haslock);
196 EXPECT_TRUE(!l5.haslock);
198 lock.unlock();
200 EXPECT_TRUE(waitForWaiters(event, 4, 10000ms));
202 EXPECT_TRUE(l2.haslock);
203 EXPECT_TRUE(l3.haslock);
204 EXPECT_TRUE(l4.haslock);
205 EXPECT_TRUE(l5.haslock);
207 event.Set();
209 EXPECT_TRUE(waitThread1.timed_join(10000ms));
210 EXPECT_TRUE(waitThread2.timed_join(10000ms));
211 EXPECT_TRUE(waitThread3.timed_join(10000ms));
212 EXPECT_TRUE(waitThread4.timed_join(10000ms));