* 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);
spin_unlock_irq(¤t->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(¤t->sigmask_lock);
spin_unlock_irq(¤t->sigmask_lock);
}
- MUTEX_ENTER(l);
if (isAFSGlocked) AFS_GLOCK();
+ MUTEX_ENTER(l);
return (sigok && signal_pending(current)) ? EINTR : 0;
}
{
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