linux-cleanup-rx-cv-locking-20020725
[openafs.git] / 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