From: Kern Sibbald Date: Sun, 7 Mar 2010 16:09:32 +0000 (+0100) Subject: More devlock work X-Git-Tag: Release-5.2.1~1624 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=4b90dd8f31ba6f7b901951740f03b611a06175d8;p=bacula%2Fbacula More devlock work --- diff --git a/bacula/src/lib/devlock.c b/bacula/src/lib/devlock.c index 2d36c6b86f..c85721f79d 100644 --- a/bacula/src/lib/devlock.c +++ b/bacula/src/lib/devlock.c @@ -240,7 +240,7 @@ int devlock::readunlock() * Lock for write access, wait until locked (or error). * Multiple nested write locking is permitted. */ -int devlock::writelock(int areason, bool acan_steal) +int devlock::writelock(int areason, bool acan_take) { devlock *rwl = this; int stat; @@ -275,7 +275,7 @@ int devlock::writelock(int areason, bool acan_steal) lmgr_post_lock(); } rwl->reason = areason; - rwl->can_steal = acan_steal; + rwl->can_take = acan_take; pthread_mutex_unlock(&rwl->mutex); return stat; } @@ -349,6 +349,47 @@ int devlock::writeunlock() return (stat == 0 ? stat2 : stat); } +int devlock::take_lock(take_lock_t *hold, int areason) +{ + int stat; + + if (valid != DEVLOCK_VALID) { + return EINVAL; + } + if ((stat = pthread_mutex_lock(&mutex)) != 0) { + return stat; + } + hold->reason = reason; + hold->prev_reason = prev_reason; + hold->writer_id = writer_id; + reason = areason; + writer_id = pthread_self(); + stat = pthread_mutex_unlock(&mutex); + return stat; +} + +int devlock::return_lock(take_lock_t *hold) +{ + int stat, stat2; + + if (valid != DEVLOCK_VALID) { + return EINVAL; + } + if ((stat = pthread_mutex_lock(&mutex)) != 0) { + return stat; + } + reason = hold->reason; + prev_reason = hold->prev_reason; + writer_id = hold->writer_id; + writer_id = pthread_self(); + stat2 = pthread_mutex_unlock(&mutex); + if (w_active || w_wait) { + stat = pthread_cond_broadcast(&write); + } + return (stat == 0 ? stat2 : stat); + +} + #ifdef TEST_RWLOCK #define THREADS 300 diff --git a/bacula/src/lib/devlock.h b/bacula/src/lib/devlock.h index b8ad3513c2..bf2e4f6b14 100644 --- a/bacula/src/lib/devlock.h +++ b/bacula/src/lib/devlock.h @@ -39,6 +39,13 @@ #ifndef __DEVLOCK_H #define __DEVLOCK_H 1 +struct take_lock_t { + pthread_t writer_id; /* id of writer */ + int reason; /* save reason */ + int prev_reason; /* previous reason */ +}; + + class devlock { private: pthread_mutex_t mutex; @@ -52,16 +59,21 @@ private: int r_wait; /* readers waiting */ int w_wait; /* writers waiting */ int reason; /* reason for lock */ - bool can_steal; /* can the lock be stolen? */ + int prev_reason; /* previous reason */ + bool can_take; /* can the lock be taken? */ public: - devlock(int reason, bool can_steal=false); + devlock(int reason, bool can_take=false); ~devlock(); int init(int priority); int destroy(); + int take_lock(take_lock_t *hold, int reason); + int return_lock(take_lock_t *hold); + void new_reason(int nreason) { prev_reason = reason; reason = nreason; }; + void restore_reason() { reason = prev_reason; prev_reason = 0; }; - int writelock(int reason, bool can_steal=false); + int writelock(int reason, bool can_take=false); int writetrylock(); int writeunlock(); void write_release();