Author: Armin Rigo <[email protected]>
Branch: 
Changeset: r75996:223e8c97aec5
Date: 2015-02-19 12:45 +0100
http://bitbucket.org/pypy/pypy/changeset/223e8c97aec5/

Log:    Group together the two C function calls done during lock.release().

diff --git a/rpython/rlib/rthread.py b/rpython/rlib/rthread.py
--- a/rpython/rlib/rthread.py
+++ b/rpython/rlib/rthread.py
@@ -58,7 +58,8 @@
                                         [TLOCKP, rffi.LONGLONG, rffi.INT],
                                         rffi.INT,
                                         releasegil=True)    # release the GIL
-c_thread_releaselock = llexternal('RPyThreadReleaseLock', [TLOCKP], 
lltype.Void,
+c_thread_releaselock = llexternal('RPyThreadReleaseLock', [TLOCKP],
+                                  lltype.Signed,
                                   _nowrapper=True)   # *don't* release the GIL
 
 # another set of functions, this time in versions that don't cause the
@@ -152,12 +153,8 @@
         return res
 
     def release(self):
-        # Sanity check: the lock must be locked
-        if self.acquire(False):
-            c_thread_releaselock(self._lock)
-            raise error("bad lock")
-        else:
-            c_thread_releaselock(self._lock)
+        if c_thread_releaselock(self._lock) != 0:
+            raise error("the lock was not previously acquired")
 
     def __del__(self):
         if free_ll_lock is None:  # happens when tests are shutting down
diff --git a/rpython/translator/c/src/thread_nt.c 
b/rpython/translator/c/src/thread_nt.c
--- a/rpython/translator/c/src/thread_nt.c
+++ b/rpython/translator/c/src/thread_nt.c
@@ -184,10 +184,12 @@
     return RPyThreadAcquireLockTimed(lock, waitflag ? -1 : 0, /*intr_flag=*/0);
 }
 
-void RPyThreadReleaseLock(struct RPyOpaque_ThreadLock *lock)
+long RPyThreadReleaseLock(struct RPyOpaque_ThreadLock *lock)
 {
-       if (!LeaveNonRecursiveMutex(lock))
-               /* XXX complain? */;
+    if (LeaveNonRecursiveMutex(lock))
+        return 0;   /* success */
+    else
+        return -1;  /* failure: the lock was not previously acquired */
 }
 
 /************************************************************/
diff --git a/rpython/translator/c/src/thread_nt.h 
b/rpython/translator/c/src/thread_nt.h
--- a/rpython/translator/c/src/thread_nt.h
+++ b/rpython/translator/c/src/thread_nt.h
@@ -24,7 +24,7 @@
 RPyLockStatus RPyThreadAcquireLockTimed(struct RPyOpaque_ThreadLock *lock,
                                        RPY_TIMEOUT_T timeout, int intr_flag);
 RPY_EXTERN
-void RPyThreadReleaseLock(struct RPyOpaque_ThreadLock *lock);
+long RPyThreadReleaseLock(struct RPyOpaque_ThreadLock *lock);
 RPY_EXTERN
 long RPyThreadGetStackSize(void);
 RPY_EXTERN
diff --git a/rpython/translator/c/src/thread_pthread.c 
b/rpython/translator/c/src/thread_pthread.c
--- a/rpython/translator/c/src/thread_pthread.c
+++ b/rpython/translator/c/src/thread_pthread.c
@@ -274,13 +274,23 @@
        return success;
 }
 
-void RPyThreadReleaseLock(struct RPyOpaque_ThreadLock *lock)
+long RPyThreadReleaseLock(struct RPyOpaque_ThreadLock *lock)
 {
-       sem_t *thelock = &lock->sem;
-       int status, error = 0;
+    sem_t *thelock = &lock->sem;
+    int status, error = 0;
+    int current_value;
 
-       status = sem_post(thelock);
-       CHECK_STATUS("sem_post");
+    /* If the current value is > 0, then the lock is not acquired so far.
+       Oops. */
+    sem_getvalue(thelock, &current_value);
+    if (current_value > 0) {
+        return -1;
+    }
+
+    status = sem_post(thelock);
+    CHECK_STATUS("sem_post");
+
+    return 0;
 }
 
 /************************************************************/
@@ -425,13 +435,18 @@
        return success;
 }
 
-void RPyThreadReleaseLock(struct RPyOpaque_ThreadLock *lock)
+long RPyThreadReleaseLock(struct RPyOpaque_ThreadLock *lock)
 {
        int status, error = 0;
+        long result;
 
        status = pthread_mutex_lock( &lock->mut );
        CHECK_STATUS("pthread_mutex_lock[3]");
 
+        /* If the lock was non-locked, then oops, we return -1 for failure.
+           Otherwise, we return 0 for success. */
+        result = (lock->locked == 0) ? -1 : 0;
+
        lock->locked = 0;
 
        status = pthread_mutex_unlock( &lock->mut );
@@ -440,6 +455,8 @@
        /* wake up someone (anyone, if any) waiting on the lock */
        status = pthread_cond_signal( &lock->lock_released );
        CHECK_STATUS("pthread_cond_signal");
+
+        return result;
 }
 
 /************************************************************/
diff --git a/rpython/translator/c/src/thread_pthread.h 
b/rpython/translator/c/src/thread_pthread.h
--- a/rpython/translator/c/src/thread_pthread.h
+++ b/rpython/translator/c/src/thread_pthread.h
@@ -71,7 +71,7 @@
 RPyLockStatus RPyThreadAcquireLockTimed(struct RPyOpaque_ThreadLock *lock,
                                        RPY_TIMEOUT_T timeout, int intr_flag);
 RPY_EXTERN
-void RPyThreadReleaseLock(struct RPyOpaque_ThreadLock *lock);
+long RPyThreadReleaseLock(struct RPyOpaque_ThreadLock *lock);
 RPY_EXTERN
 long RPyThreadGetStackSize(void);
 RPY_EXTERN
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to