diff options
| author | rpj <rpj> | 2011-05-06 02:11:50 +0000 | 
|---|---|---|
| committer | rpj <rpj> | 2011-05-06 02:11:50 +0000 | 
| commit | 2fe8aba6a8a4ce09f353f34881c77f93a9c01ca3 (patch) | |
| tree | fd7f179b1abaa525ec55e34bef23b12f8fd89021 /pthread_mutex_unlock.c | |
| parent | 941d7cf87c60b55342b51e0b0fcd748589b76167 (diff) | |
Robust mutexes merged from devel branchpost_merge_with_ROBUST_MUTEXES
Diffstat (limited to 'pthread_mutex_unlock.c')
| -rw-r--r-- | pthread_mutex_unlock.c | 144 | 
1 files changed, 100 insertions, 44 deletions
| diff --git a/pthread_mutex_unlock.c b/pthread_mutex_unlock.c index 9ebe4e3..5cd51af 100644 --- a/pthread_mutex_unlock.c +++ b/pthread_mutex_unlock.c @@ -42,6 +42,7 @@ int  pthread_mutex_unlock (pthread_mutex_t * mutex)  {    int result = 0; +  int kind;    pthread_mutex_t mx;    /* @@ -57,60 +58,115 @@ pthread_mutex_unlock (pthread_mutex_t * mutex)     */    if (mx < PTHREAD_ERRORCHECK_MUTEX_INITIALIZER)      { -      if (mx->kind == PTHREAD_MUTEX_NORMAL) -	{ -	  LONG idx; +      kind = mx->kind; -	  idx = (LONG) PTW32_INTERLOCKED_EXCHANGE ((LPLONG) &mx->lock_idx, -						   (LONG) 0); -	  if (idx != 0) +      if (kind >= 0) +        { +          if (kind == PTHREAD_MUTEX_NORMAL)  	    { -	      if (idx < 0) -		{ -		  /* -		   * Someone may be waiting on that mutex. -		   */ -		  if (SetEvent (mx->event) == 0) -		    { -		      result = EINVAL; -		    } -		} -	    } -	  else -	    { -	      /* -	       * Was not locked (so can't be owned by us). -	       */ -	      result = EPERM; -	    } -	} -      else -	{ -	  if (pthread_equal (mx->ownerThread, pthread_self ())) -	    { -	      if (mx->kind != PTHREAD_MUTEX_RECURSIVE -		  || 0 == --mx->recursive_count) -		{ -		  mx->ownerThread.p = NULL; +	      LONG idx; -		  if ((LONG) PTW32_INTERLOCKED_EXCHANGE ((LPLONG) &mx->lock_idx, -							 (LONG) 0) < 0) +	      idx = (LONG) PTW32_INTERLOCKED_EXCHANGE ((LPLONG) &mx->lock_idx, +						       (LONG) 0); +	      if (idx != 0) +	        { +	          if (idx < 0)  		    { -		      /* Someone may be waiting on that mutex */ +		      /* +		       * Someone may be waiting on that mutex. +		       */  		      if (SetEvent (mx->event) == 0) -			{ -			  result = EINVAL; -			} +		        { +		          result = EINVAL; +		        }  		    } -		} +	        }  	    } -	  else +          else  	    { -	      result = EPERM; +	      if (pthread_equal (mx->ownerThread, pthread_self())) +	        { +	          if (kind != PTHREAD_MUTEX_RECURSIVE +		      || 0 == --mx->recursive_count) +		    { +		      mx->ownerThread.p = NULL; + +		      if ((LONG) PTW32_INTERLOCKED_EXCHANGE ((LPLONG) &mx->lock_idx, +							     (LONG) 0) < 0) +		        { +		          /* Someone may be waiting on that mutex */ +		          if (SetEvent (mx->event) == 0) +			    { +			      result = EINVAL; +			    } +		        } +		    } +	        } +	      else +	        { +	          result = EPERM; +	        }  	    } -	} +        } +      else +        { +          /* Robust types */ +          pthread_t self = pthread_self(); +          kind = -kind - 1; /* Convert to non-robust range */ + +          /* +           * The thread must own the lock regardless of type if the mutex +           * is robust. +           */ +          if (pthread_equal (mx->ownerThread, self)) +            { +              PTW32_INTERLOCKED_COMPARE_EXCHANGE((LPLONG) &mx->robustNode->stateInconsistent, +                                                 (LONG)PTW32_ROBUST_NOTRECOVERABLE, +                                                 (LONG)PTW32_ROBUST_INCONSISTENT); +              if (PTHREAD_MUTEX_NORMAL == kind) +                { +                  ptw32_robust_mutex_remove(mutex, NULL); + +                  if ((LONG) PTW32_INTERLOCKED_EXCHANGE((LPLONG) &mx->lock_idx, +                                                          (LONG) 0) < 0) +                    { +                      /* +                       * Someone may be waiting on that mutex. +                       */ +                      if (SetEvent (mx->event) == 0) +                        { +                          result = EINVAL; +                        } +                    } +                } +              else +                { +                  if (kind != PTHREAD_MUTEX_RECURSIVE +                      || 0 == --mx->recursive_count) +                    { +                      ptw32_robust_mutex_remove(mutex, NULL); + +                      if ((LONG) PTW32_INTERLOCKED_EXCHANGE((LPLONG) &mx->lock_idx, +                                                            (LONG) 0) < 0) +                        { +                          /* +                           * Someone may be waiting on that mutex. +                           */ +                          if (SetEvent (mx->event) == 0) +                            { +                              result = EINVAL; +                            } +                        } +                    } +                } +            } +          else +            { +              result = EPERM; +            } +        }      } -  else +  else if (mx != PTHREAD_MUTEX_INITIALIZER)      {        result = EINVAL;      } | 
