linux-cleanup-rx-cv-locking-20020725
authorChas Williams <chas@cmf.nrl.navy.mil>
Fri, 26 Jul 2002 00:29:52 +0000 (00:29 +0000)
committerDerrick Brashear <shadow@dementia.org>
Fri, 26 Jul 2002 00:29:52 +0000 (00:29 +0000)
cleanup wait queue usage
grab glock before mutex (like all other ports)

src/rx/LINUX/rx_kmutex.c

index 3ee6926..1df1810 100644 (file)
@@ -63,11 +63,20 @@ void afs_mutex_exit(afs_kmutex_t *l)
  * CV_WAIT and CV_TIMEDWAIT rely on the fact that the Linux kernel has
  * a global lock. Thus we can safely drop our locks before calling the
  * kernel sleep services.
+ * Or not.
  */
 int afs_cv_wait(afs_kcondvar_t *cv, afs_kmutex_t *l, int sigok)
 {
     int isAFSGlocked = ISAFS_GLOCK();
     sigset_t saved_set;
+#ifdef DECLARE_WAITQUEUE
+    DECLARE_WAITQUEUE(wait, current);
+#else
+    struct wait_queue wait = { current, NULL };
+#endif
+
+    add_wait_queue((wait_queue_head_t *)cv, &wait);
+    set_current_state(TASK_INTERRUPTIBLE);
 
     if (isAFSGlocked) AFS_GUNLOCK();
     MUTEX_EXIT(l);
@@ -80,11 +89,8 @@ int afs_cv_wait(afs_kcondvar_t *cv, afs_kmutex_t *l, int sigok)
        spin_unlock_irq(&current->sigmask_lock);
     }
 
-#if defined(AFS_LINUX24_ENV)
-    interruptible_sleep_on((wait_queue_head_t *)cv);
-#else
-    interruptible_sleep_on((struct wait_queue**)cv);
-#endif
+    schedule();
+    remove_wait_queue(cv, &wait);
 
     if (!sigok) {
        spin_lock_irq(&current->sigmask_lock);
@@ -93,8 +99,8 @@ int afs_cv_wait(afs_kcondvar_t *cv, afs_kmutex_t *l, int sigok)
        spin_unlock_irq(&current->sigmask_lock);
     }
 
-    MUTEX_ENTER(l);
     if (isAFSGlocked) AFS_GLOCK();
+    MUTEX_ENTER(l);
 
     return (sigok && signal_pending(current)) ? EINTR : 0;
 }
@@ -103,18 +109,23 @@ void afs_cv_timedwait(afs_kcondvar_t *cv, afs_kmutex_t *l, int waittime)
 {
     int isAFSGlocked = ISAFS_GLOCK();
     long t = waittime * HZ / 1000;
+#ifdef DECLARE_WAITQUEUE
+    DECLARE_WAITQUEUE(wait, current);
+#else
+    struct wait_queue wait = { current, NULL };
+#endif
+
+    add_wait_queue((wait_queue_head_t *)cv, &wait);
+    set_current_state(TASK_INTERRUPTIBLE);
 
     if (isAFSGlocked) AFS_GUNLOCK();
     MUTEX_EXIT(l);
     
-#if defined(AFS_LINUX24_ENV)
-    t = interruptible_sleep_on_timeout((wait_queue_head_t *)cv, t);
-#else
-    t = interruptible_sleep_on_timeout((struct wait_queue**)cv, t);
-#endif
+    t = schedule_timeout(t);
+    remove_wait_queue(cv, &wait);
     
-    MUTEX_ENTER(l);
     if (isAFSGlocked) AFS_GLOCK();
+    MUTEX_ENTER(l);
 }
 
 #endif