1 /*
2  *  Copyright (C) 2005-2018 Team Kodi
3  *  This file is part of Kodi - https://kodi.tv
4  *
5  *  SPDX-License-Identifier: GPL-2.0-or-later
6  *  See LICENSES/README.md for more information.
7  */
8 
9 #pragma once
10 
11 #include "threads/Thread.h"
12 
13 #include <gtest/gtest.h>
14 
15 #define MILLIS(x) x
16 
SleepMillis(unsigned int millis)17 inline static void SleepMillis(unsigned int millis)
18 {
19   std::this_thread::sleep_for(std::chrono::milliseconds(millis));
20 }
21 
waitForWaiters(E & event,int numWaiters,int milliseconds)22 template<class E> inline static bool waitForWaiters(E& event, int numWaiters, int milliseconds)
23 {
24   for( int i = 0; i < milliseconds; i++)
25   {
26     if (event.getNumWaits() == numWaiters)
27       return true;
28     SleepMillis(1);
29   }
30   return false;
31 }
32 
waitForThread(std::atomic<long> & mutex,int numWaiters,int milliseconds)33 inline static bool waitForThread(std::atomic<long>& mutex, int numWaiters, int milliseconds)
34 {
35   CCriticalSection sec;
36   for( int i = 0; i < milliseconds; i++)
37   {
38     if (mutex == (long)numWaiters)
39       return true;
40 
41     {
42       CSingleLock tmplock(sec); // kick any memory syncs
43     }
44     SleepMillis(1);
45   }
46   return false;
47 }
48 
49 class AtomicGuard
50 {
51   std::atomic<long>* val;
52 public:
AtomicGuard(std::atomic<long> * val_)53   inline AtomicGuard(std::atomic<long>* val_) : val(val_) { if (val) ++(*val); }
~AtomicGuard()54   inline ~AtomicGuard() { if (val) --(*val); }
55 };
56 
57 class thread
58 {
59   IRunnable* f;
60   CThread* cthread;
61 
62 //  inline thread(const thread& other) { }
63 public:
thread(IRunnable & runnable)64   inline explicit thread(IRunnable& runnable) :
65     f(&runnable), cthread(new CThread(f, "DumbThread"))
66   {
67     cthread->Create();
68   }
69 
thread()70   inline thread() : f(NULL), cthread(NULL) {}
~thread()71   ~thread()
72   {
73     delete cthread;
74   }
75 
thread(thread & other)76   inline thread(thread& other) : f(other.f), cthread(other.cthread) { other.f = NULL; other.cthread = NULL; }
77   inline thread& operator=(thread& other) { f = other.f; other.f = NULL; cthread = other.cthread; other.cthread = NULL; return *this; }
78 
join()79   void join()
80   {
81     cthread->Join(static_cast<unsigned int>(-1));
82   }
83 
timed_join(unsigned int millis)84   bool timed_join(unsigned int millis)
85   {
86     return cthread->Join(millis);
87   }
88 };
89 
90