summaryrefslogtreecommitdiff
path: root/includes/Threads.h
blob: ed629be4209f5c76d03e8c58e5f47f000513b69c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
#pragma once

#include <atomic>
#include <AtStartExit.h>
#include <pthread.h>

namespace Balau {

class QueueBase;

class Lock {
  public:
      Lock();
      ~Lock() { pthread_mutex_destroy(&m_lock); }
    void enter() { pthread_mutex_lock(&m_lock); }
    void leave() { pthread_mutex_unlock(&m_lock); }
  private:
      Lock(const Lock &) = delete;
    Lock & operator=(const Lock &) = delete;
    pthread_mutex_t m_lock;
    friend class QueueBase;
};

class ScopeLock {
  public:
      ScopeLock(Lock & lock) : m_lock(lock) { m_lock.enter(); }
      ~ScopeLock() { m_lock.leave(); }
  private:
      ScopeLock(const ScopeLock &) = delete;
    ScopeLock & operator=(const ScopeLock &) = delete;
    Lock & m_lock;
};

class RWLock {
  public:
      RWLock();
      ~RWLock() { pthread_rwlock_destroy(&m_lock); }
    void enterR() { pthread_rwlock_rdlock(&m_lock); }
    void enterW() { pthread_rwlock_wrlock(&m_lock); }
    void leave() { pthread_rwlock_unlock(&m_lock); }
  private:
      RWLock(const RWLock &) = delete;
    RWLock & operator=(const ScopeLock &) = delete;
    pthread_rwlock_t m_lock;
};

class ScopeLockR {
  public:
      ScopeLockR(RWLock & lock) : m_lock(lock) { m_lock.enterR(); }
      ~ScopeLockR() { m_lock.leave(); }
  private:
      ScopeLockR(const ScopeLockR &) = delete;
    ScopeLockR & operator=(const ScopeLockR &) = delete;
    RWLock & m_lock;
};

class ScopeLockW {
  public:
      ScopeLockW(RWLock & lock) : m_lock(lock) { m_lock.enterW(); }
      ~ScopeLockW() { m_lock.leave(); }
  private:
      ScopeLockW(const ScopeLockW &) = delete;
    ScopeLockW & operator=(const ScopeLockW &) = delete;
    RWLock & m_lock;
};

class ThreadHelper;

class Thread {
  public:
      virtual ~Thread();
    void threadStart();
    void * join();
  protected:
      Thread() : m_joined(false) { }
    virtual void * proc() = 0;
    virtual void threadExit() { };
  private:
      Thread(const Thread &) = delete;
    Thread & operator=(const Thread &) = delete;
    pthread_t m_thread;
    std::atomic<bool> m_joined;

    friend class ThreadHelper;
};

class GlobalThread : public Thread, public AtStart, public AtExit {
  protected:
      GlobalThread(int startOrder = 10) : AtStart(startOrder), AtExit(1) { }
  private:
      GlobalThread(const GlobalThread &) = delete;
    GlobalThread & operator=(const GlobalThread &) = delete;
    virtual void doStart() { threadStart(); }
    virtual void doExit() { join(); }
};

};