Is is intentional that tummy_task is not initialized?
Ok, it won't crash because the current __run_task_queue() implementation
doesn't call tq->routine if it's NULL, but IMHO it's ugly.

Additionally I don't like the loop in flush_scheduled_tasks(), what
about replacing it with a locked semaphore (same idea as vfork)?

I've attched an untested patch.

--
        Manfred
--- context.c.orig      Sun Jan 28 17:02:35 2001
+++ context.c   Sun Jan 28 17:09:24 2001
@@ -22,7 +22,6 @@
 
 static DECLARE_TASK_QUEUE(tq_context);
 static DECLARE_WAIT_QUEUE_HEAD(context_task_wq);
-static DECLARE_WAIT_QUEUE_HEAD(context_task_done);
 static int keventd_running;
 static struct task_struct *keventd_task;
 
@@ -97,7 +96,6 @@
                schedule();
                remove_wait_queue(&context_task_wq, &wait);
                run_task_queue(&tq_context);
-               wake_up(&context_task_done);
                if (signal_pending(curtask)) {
                        while (waitpid(-1, (unsigned int *)0, __WALL|WNOHANG) > 0)
                                ;
@@ -119,31 +117,24 @@
  * The caller should hold no spinlocks and should hold no semaphores which could
  * cause the scheduled tasks to block.
  */
-static struct tq_struct dummy_task;
 
-void flush_scheduled_tasks(void)
+static void up_semaphore(void* sem)
 {
-       int count;
-       DECLARE_WAITQUEUE(wait, current);
+       up((struct semaphore*)sem);
+}
 
-       /*
-        * Do it twice. It's possible, albeit highly unlikely, that
-        * the caller queued a task immediately before calling us,
-        * and that the eventd thread was already past the run_task_queue()
-        * but not yet into wake_up(), so it woke us up before completing
-        * the caller's queued task or our new dummy task.
-        */
-       add_wait_queue(&context_task_done, &wait);
-       for (count = 0; count < 2; count++) {
-               set_current_state(TASK_UNINTERRUPTIBLE);
+void flush_scheduled_tasks(void)
+{
+       DECLARE_MUTEX_LOCKED(sem);
+       struct tq_struct wakeup_task;
 
-               /* Queue a dummy task to make sure we get kicked */
-               schedule_task(&dummy_task);
+       wakeup_task.routine = up_semaphore;
+       wakeup_task.data = &sem;
+       /* Queue a dummy task to make sure we get kicked */
+       schedule_task(&dummy_task);
 
-               /* Wait for it to complete */
-               schedule();
-       }
-       remove_wait_queue(&context_task_done, &wait);
+       /* Wait for it to complete */
+       down(&sem);
 }
        
 int start_context_thread(void)

Reply via email to