File: lockable.h

package info (click to toggle)
apt-cacher-ng 0.7.27-1~bpo70+1
  • links: PTS
  • area: main
  • in suites: wheezy-backports
  • size: 1,740 kB
  • sloc: cpp: 13,987; sh: 519; perl: 442; ansic: 414; makefile: 77
file content (166 lines) | stat: -rw-r--r-- 3,555 bytes parent folder | download
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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
#ifndef _LOCKABLE_H
#define _LOCKABLE_H

#include <pthread.h>

class lockguard;

#ifdef DEBUG_never
#include <iostream>
#define __lock_yell(x) MYSTD::cerr <<"### " x "\n";
#else
#define __lock_yell(x)
#endif

class lockable
{
public:
	lockable();
	virtual ~lockable();
	void lock();
	bool tryLock();
	void unlock();
	//pthread_mutex_t * MutexRef() { return &__mutex; }

protected:
	friend class lockguard;
	pthread_mutex_t __mutex;
};

class lockguard
{
public:

	// lock() helper sets the bool flag, no need to pre-initialize here
	inline lockguard(pthread_mutex_t *m) :
		l(m), bLocked(false)
	{
		lock();
	}
	inline lockguard(pthread_mutex_t & m) :
		l(&m), bLocked(false)
	{
		lock();
	}
	inline lockguard(lockable & cl) :
		l(&cl.__mutex), bLocked(false)
	{
		lock();
	}

	inline lockguard(lockable *cl, bool bInitiallyLock=true) :
		l(&cl->__mutex), bLocked(false)
	{
		if (bInitiallyLock)
			lock();
	}
	inline void unLock()
	{
		if (bLocked)
		{
			pthread_mutex_unlock(l);
			bLocked=false;
			__lock_yell ("LOCK RELEASED");
		}
	}
	inline void reLock()
	{
		if (!bLocked)
			lock();
	}
	~lockguard()
	{
		unLock();
	}

private:
	pthread_mutex_t *l;
	bool bLocked;

	inline void lock()
	{
		pthread_mutex_lock(l);
		bLocked=true;
		__lock_yell ("LOCK SET");
	}

	// not to be copied ever
	lockguard(const lockguard&);
	lockguard& operator=(const lockguard&);
};

//#define setLockGuard ldbgvl(DBGSPAM, "Locking @" << __LINE__); lockguard __lockguard(&__mutex);
#define setLockGuard lockguard __lockguard(&__mutex);

// more sophisticated condition class, includes the required mutex
class condition : public lockable {
    public:
        condition();
        ~condition();
        void wait();

#if 0
        /** \brief Waits for the specified period of time or a signal or external notification
         * @return true if awaken by another thread or signal, false if run into timeout.
         * @param secs Seconds to wait
         * @param msecs Extra milliseconds to wait, optional value
         */
        bool wait(time_t secs, long msecs=0);
#endif

        /** \brief Waits until the specified moment is reached or a signal
         * or external notification happened
         *
         * @return true waited to the end, false when awaken prematurely
         * @param secs Seconds to wait
         * @param msecs Extra milliseconds to wait, optional value
        */
        bool wait_until(time_t nUTCsecs, long msec);
        void notifyAll();
        void notify();

    protected:
        pthread_cond_t __cond;
};

/*
// modified version of lockguard, broadcasting potential sleepers

class notifyguard {
    public:
        notifyguard(pthread_mutex_t *m, pthread_cond_t *d):l(m),c(d){pthread_mutex_lock(m);}
        ~notifyguard() {pthread_cond_broadcast(c); pthread_mutex_unlock(l);}
    private:
        pthread_mutex_t *l;
        pthread_cond_t *c;
};

#define setNotifyGuard notifyguard __notifyguard(&__mutex, &__cond);
*/

#if 0 // generalized version of the thread pool which might be used to conns and dlconns
// however, the requirements are slightly different so most likely it would suck

class tRunnable
{
public:
	virtual void WorkLoop() =0;
	virtual ~tRunable() {};
};

class tThreadPool
{
public:
	tThreadPool(size_t nThreadMax, size_t nMaxStandby, size_t nMaxBacklog);
	void AddRunnable(tRunnable *);
	void ResetBacklog();
	bool StartThreadsAsNeeded();
	void StopAll();
private:
	size_t m_nThreadMax, m_nMaxStandby, m_nMaxBacklog;
	MYSTD::vector<pthread_t> m_threads;
	condition m_syncCond;
};
#endif

#endif