1*a90ebd77SClemens Zeidler /* 2*a90ebd77SClemens Zeidler * Copyright 2006, Haiku, Inc. All Rights Reserved. 3*a90ebd77SClemens Zeidler * Distributed under the terms of the MIT License. 4*a90ebd77SClemens Zeidler * 5*a90ebd77SClemens Zeidler * Authors: 6*a90ebd77SClemens Zeidler * Axel Dörfler, axeld@pinc-software.de 7*a90ebd77SClemens Zeidler */ 8*a90ebd77SClemens Zeidler #ifndef LOCK_H 9*a90ebd77SClemens Zeidler #define LOCK_H 10*a90ebd77SClemens Zeidler 11*a90ebd77SClemens Zeidler 12*a90ebd77SClemens Zeidler #include <OS.h> 13*a90ebd77SClemens Zeidler 14*a90ebd77SClemens Zeidler 15*a90ebd77SClemens Zeidler typedef struct lock { 16*a90ebd77SClemens Zeidler sem_id sem; 17*a90ebd77SClemens Zeidler vint32 count; 18*a90ebd77SClemens Zeidler } lock; 19*a90ebd77SClemens Zeidler 20*a90ebd77SClemens Zeidler 21*a90ebd77SClemens Zeidler static inline status_t 22*a90ebd77SClemens Zeidler init_lock(struct lock *lock, const char *name) 23*a90ebd77SClemens Zeidler { 24*a90ebd77SClemens Zeidler lock->sem = create_sem(0, name); 25*a90ebd77SClemens Zeidler lock->count = 0; 26*a90ebd77SClemens Zeidler 27*a90ebd77SClemens Zeidler return lock->sem < B_OK ? lock->sem : B_OK; 28*a90ebd77SClemens Zeidler } 29*a90ebd77SClemens Zeidler 30*a90ebd77SClemens Zeidler 31*a90ebd77SClemens Zeidler static inline void 32*a90ebd77SClemens Zeidler uninit_lock(struct lock *lock) 33*a90ebd77SClemens Zeidler { 34*a90ebd77SClemens Zeidler delete_sem(lock->sem); 35*a90ebd77SClemens Zeidler } 36*a90ebd77SClemens Zeidler 37*a90ebd77SClemens Zeidler 38*a90ebd77SClemens Zeidler static inline status_t 39*a90ebd77SClemens Zeidler acquire_lock(struct lock *lock) 40*a90ebd77SClemens Zeidler { 41*a90ebd77SClemens Zeidler if (atomic_add(&lock->count, 1) > 0) 42*a90ebd77SClemens Zeidler return acquire_sem(lock->sem); 43*a90ebd77SClemens Zeidler 44*a90ebd77SClemens Zeidler return B_OK; 45*a90ebd77SClemens Zeidler } 46*a90ebd77SClemens Zeidler 47*a90ebd77SClemens Zeidler 48*a90ebd77SClemens Zeidler static inline status_t 49*a90ebd77SClemens Zeidler release_lock(struct lock *lock) 50*a90ebd77SClemens Zeidler { 51*a90ebd77SClemens Zeidler if (atomic_add(&lock->count, -1) > 1) 52*a90ebd77SClemens Zeidler return release_sem(lock->sem); 53*a90ebd77SClemens Zeidler 54*a90ebd77SClemens Zeidler return B_OK; 55*a90ebd77SClemens Zeidler } 56*a90ebd77SClemens Zeidler 57*a90ebd77SClemens Zeidler 58*a90ebd77SClemens Zeidler class Autolock { 59*a90ebd77SClemens Zeidler public: 60*a90ebd77SClemens Zeidler Autolock(struct lock &lock) 61*a90ebd77SClemens Zeidler : 62*a90ebd77SClemens Zeidler fLock(&lock) 63*a90ebd77SClemens Zeidler { 64*a90ebd77SClemens Zeidler fStatus = acquire_lock(fLock); 65*a90ebd77SClemens Zeidler } 66*a90ebd77SClemens Zeidler 67*a90ebd77SClemens Zeidler ~Autolock() 68*a90ebd77SClemens Zeidler { 69*a90ebd77SClemens Zeidler if (fStatus == B_OK) 70*a90ebd77SClemens Zeidler release_lock(fLock); 71*a90ebd77SClemens Zeidler } 72*a90ebd77SClemens Zeidler 73*a90ebd77SClemens Zeidler bool 74*a90ebd77SClemens Zeidler IsLocked() const 75*a90ebd77SClemens Zeidler { 76*a90ebd77SClemens Zeidler return fStatus == B_OK; 77*a90ebd77SClemens Zeidler } 78*a90ebd77SClemens Zeidler 79*a90ebd77SClemens Zeidler private: 80*a90ebd77SClemens Zeidler status_t fStatus; 81*a90ebd77SClemens Zeidler struct lock *fLock; 82*a90ebd77SClemens Zeidler }; 83*a90ebd77SClemens Zeidler 84*a90ebd77SClemens Zeidler #endif /* LOCK_H */ 85