summaryrefslogtreecommitdiff
path: root/rwlock.c
diff options
context:
space:
mode:
authorrpj <rpj>2001-07-05 11:57:32 +0000
committerrpj <rpj>2001-07-05 11:57:32 +0000
commit99e8ecc5759668fd3af379eaddd70b4ae50ecd7f (patch)
tree8b824cc1eb8de6fd15a4b5636f5f62fa95541105 /rwlock.c
parent861a8bb5523f257b474f68334c2c5300e52c5371 (diff)
Added new routines from POSIX 1003.1j. This is alpha level code.
* spin.c: New module implementing spin locks. * barrier.c: New module implementing barriers. * pthread.h (_POSIX_SPIN_LOCKS): defined. (_POSIX_BARRIERS): Defined. (pthread_spin_*): Defined. (pthread_barrier*): Defined. (PTHREAD_BARRIER_SERIAL_THREAD): Defined. * implement.h (pthread_spinlock_t_): Defined. (pthread_barrier_t_): Defined. (pthread_barrierattr_t_): Defined. * mutex.c (pthread_mutex_lock): Return with the error if an auto-initialiser initialisation fails. * nonportable.c (pthread_getprocessors_np): New; gets the number of available processors for the current process.
Diffstat (limited to 'rwlock.c')
-rw-r--r--rwlock.c21
1 files changed, 21 insertions, 0 deletions
diff --git a/rwlock.c b/rwlock.c
index cc85b7f..c2d85d8 100644
--- a/rwlock.c
+++ b/rwlock.c
@@ -378,8 +378,24 @@ pthread_rwlock_wrlock(pthread_rwlock_t * rwlock)
if (rwl->nSharedAccessCount > 0)
{
+ /*
+ * pthread_rwlock_wrlock() is not a cancelation point
+ * so temporarily prevent pthread_cond_wait() from being one.
+ */
+ pthread_t self = pthread_self();
+ int cancelType = pthread_getcanceltype(self);
+ int oldCancelState;
+
rwl->nCompletedSharedAccessCount = -rwl->nSharedAccessCount;
+ if (cancelType == PTHREAD_CANCEL_DEFERRED)
+ {
+ oldCancelState =
+ pthread_setcancelstate(self,
+ PTHREAD_CANCEL_DISABLED);
+ }
+
+ /* Could still be PTHREAD_CANCEL_ASYNCHRONOUS. */
pthread_cleanup_push(ptw32_rwlock_cancelwrwait, (void*)rwl);
do
@@ -389,6 +405,11 @@ pthread_rwlock_wrlock(pthread_rwlock_t * rwlock)
}
while (result == 0 && rwl->nCompletedSharedAccessCount < 0);
+ if (cancelType == PTHREAD_CANCEL_DEFERRED)
+ {
+ pthread_setcancelstate(self, oldCancelState);
+ }
+
pthread_cleanup_pop ((result != 0) ? 1 : 0);
if (result == 0)