1/*
2 * Copyright 2001-2007, Axel Dörfler, axeld@pinc-software.de.
3 * This file may be used under the terms of the MIT License.
4 */
5#ifndef LOCK_H
6#define LOCK_H
7
8
9#include <OS.h>
10
11
12#define USE_BENAPHORE
13	// if defined, benaphores are used for the Semaphore class
14
15class Semaphore {
16	public:
17		Semaphore(const char *name)
18			:
19#ifdef USE_BENAPHORE
20			fSemaphore(create_sem(0, name)),
21			fCount(1)
22#else
23			fSemaphore(create_sem(1, name))
24#endif
25		{
26		}
27
28		~Semaphore()
29		{
30			delete_sem(fSemaphore);
31		}
32
33		status_t InitCheck()
34		{
35			if (fSemaphore < B_OK)
36				return fSemaphore;
37
38			return B_OK;
39		}
40
41		status_t Lock()
42		{
43#ifdef USE_BENAPHORE
44			if (atomic_add(&fCount, -1) <= 0)
45#endif
46				return acquire_sem(fSemaphore);
47#ifdef USE_BENAPHORE
48			return B_OK;
49#endif
50		}
51
52		status_t Unlock()
53		{
54#ifdef USE_BENAPHORE
55			if (atomic_add(&fCount, 1) < 0)
56#endif
57				return release_sem(fSemaphore);
58#ifdef USE_BENAPHORE
59			return B_OK;
60#endif
61		}
62
63	private:
64		sem_id	fSemaphore;
65#ifdef USE_BENAPHORE
66		vint32	fCount;
67#endif
68};
69
70// a convenience class to lock a Semaphore object
71
72class Locker {
73	public:
74		Locker(Semaphore &lock)
75			: fLock(lock)
76		{
77			fStatus = lock.Lock();
78		}
79
80		~Locker()
81		{
82			if (fStatus == B_OK)
83				fLock.Unlock();
84		}
85
86		status_t Status() const
87		{
88			return fStatus;
89		}
90
91	private:
92		Semaphore	&fLock;
93		status_t	fStatus;
94};
95
96#endif	/* LOCK_H */
97