aboutsummaryrefslogtreecommitdiff
path: root/pthreads/pthread_mutex_trylock.c
diff options
context:
space:
mode:
authormarha <marha@users.sourceforge.net>2011-07-18 10:51:09 +0200
committermarha <marha@users.sourceforge.net>2011-07-18 10:51:09 +0200
commit3c0d2312573b81e3067bea610a58b1940c075e05 (patch)
tree3f025a27d813374f225957801226aa8ee829a33a /pthreads/pthread_mutex_trylock.c
parentba033884541714680fd7552ab9d6c8817650f7d8 (diff)
parent88101146f2ec7d53ffb793e365f05097ffd35fd3 (diff)
downloadvcxsrv-3c0d2312573b81e3067bea610a58b1940c075e05.tar.gz
vcxsrv-3c0d2312573b81e3067bea610a58b1940c075e05.tar.bz2
vcxsrv-3c0d2312573b81e3067bea610a58b1940c075e05.zip
Merge remote-tracking branch 'origin/released'
Conflicts: X11/Xfuncproto.h.in X11/configure.ac X11/keysymdef.h freetype/include/freetype/internal/pcftypes.h freetype/src/cache/ftcbasic.c freetype/src/cache/ftccmap.c mesalib/src/glsl/ir.h mesalib/src/glsl/link_functions.cpp mesalib/src/mesa/main/dlist.c mesalib/src/mesa/program/prog_optimize.c mesalib/src/mesa/state_tracker/st_program.c pthreads/Makefile
Diffstat (limited to 'pthreads/pthread_mutex_trylock.c')
-rw-r--r--pthreads/pthread_mutex_trylock.c98
1 files changed, 80 insertions, 18 deletions
diff --git a/pthreads/pthread_mutex_trylock.c b/pthreads/pthread_mutex_trylock.c
index 50e8bc65c..d6b68724d 100644
--- a/pthreads/pthread_mutex_trylock.c
+++ b/pthreads/pthread_mutex_trylock.c
@@ -41,8 +41,9 @@
int
pthread_mutex_trylock (pthread_mutex_t * mutex)
{
- int result = 0;
pthread_mutex_t mx;
+ int kind;
+ int result = 0;
/*
* Let the system deal with invalid pointers.
@@ -63,29 +64,90 @@ pthread_mutex_trylock (pthread_mutex_t * mutex)
}
mx = *mutex;
+ kind = mx->kind;
- if (0 == (LONG) PTW32_INTERLOCKED_COMPARE_EXCHANGE (
- (PTW32_INTERLOCKED_LPLONG) &mx->lock_idx,
- (PTW32_INTERLOCKED_LONG) 1,
- (PTW32_INTERLOCKED_LONG) 0))
+ if (kind >= 0)
{
- if (mx->kind != PTHREAD_MUTEX_NORMAL)
- {
- mx->recursive_count = 1;
- mx->ownerThread = pthread_self ();
- }
+ /* Non-robust */
+ if (0 == (PTW32_INTERLOCKED_LONG) PTW32_INTERLOCKED_COMPARE_EXCHANGE_LONG (
+ (PTW32_INTERLOCKED_LONGPTR) &mx->lock_idx,
+ (PTW32_INTERLOCKED_LONG) 1,
+ (PTW32_INTERLOCKED_LONG) 0))
+ {
+ if (kind != PTHREAD_MUTEX_NORMAL)
+ {
+ mx->recursive_count = 1;
+ mx->ownerThread = pthread_self ();
+ }
+ }
+ else
+ {
+ if (kind == PTHREAD_MUTEX_RECURSIVE &&
+ pthread_equal (mx->ownerThread, pthread_self ()))
+ {
+ mx->recursive_count++;
+ }
+ else
+ {
+ result = EBUSY;
+ }
+ }
}
else
{
- if (mx->kind == PTHREAD_MUTEX_RECURSIVE &&
- pthread_equal (mx->ownerThread, pthread_self ()))
- {
- mx->recursive_count++;
- }
+ /*
+ * Robust types
+ * All types record the current owner thread.
+ * The mutex is added to a per thread list when ownership is acquired.
+ */
+ pthread_t self;
+ ptw32_robust_state_t* statePtr = &mx->robustNode->stateInconsistent;
+
+ if ((PTW32_INTERLOCKED_LONG)PTW32_ROBUST_NOTRECOVERABLE ==
+ PTW32_INTERLOCKED_EXCHANGE_ADD_LONG(
+ (PTW32_INTERLOCKED_LONGPTR)statePtr,
+ (PTW32_INTERLOCKED_LONG)0))
+ {
+ return ENOTRECOVERABLE;
+ }
+
+ self = pthread_self();
+ kind = -kind - 1; /* Convert to non-robust range */
+
+ if (0 == (PTW32_INTERLOCKED_LONG) PTW32_INTERLOCKED_COMPARE_EXCHANGE_LONG (
+ (PTW32_INTERLOCKED_LONGPTR) &mx->lock_idx,
+ (PTW32_INTERLOCKED_LONG) 1,
+ (PTW32_INTERLOCKED_LONG) 0))
+ {
+ if (kind != PTHREAD_MUTEX_NORMAL)
+ {
+ mx->recursive_count = 1;
+ }
+ ptw32_robust_mutex_add(mutex, self);
+ }
else
- {
- result = EBUSY;
- }
+ {
+ if (PTHREAD_MUTEX_RECURSIVE == kind &&
+ pthread_equal (mx->ownerThread, pthread_self ()))
+ {
+ mx->recursive_count++;
+ }
+ else
+ {
+ if (EOWNERDEAD == (result = ptw32_robust_mutex_inherit(mutex)))
+ {
+ mx->recursive_count = 1;
+ ptw32_robust_mutex_add(mutex, self);
+ }
+ else
+ {
+ if (0 == result)
+ {
+ result = EBUSY;
+ }
+ }
+ }
+ }
}
return (result);