From 4a59c05f1b9804e16c5b56274409037c92839ddc Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Henrik=20Grubbstr=C3=B6m=20=28Grubba=29?=
 <grubba@grubba.org>
Date: Mon, 30 Sep 2002 20:45:22 +0200
Subject: [PATCH] Thread.Condition()->wait() now requires an argument.

Rev: lib/7.2/modules/Thread.pmod:1.1
Rev: src/threads.c:1.186
---
 .gitattributes              |  1 +
 lib/7.2/modules/Thread.pmod | 24 ++++++++++
 src/threads.c               | 89 ++++++++++++++++---------------------
 3 files changed, 63 insertions(+), 51 deletions(-)
 create mode 100644 lib/7.2/modules/Thread.pmod

diff --git a/.gitattributes b/.gitattributes
index 7fc3c44859..cb818003cf 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -45,6 +45,7 @@ testfont binary
 /lib/7.2/modules/LR.pmod/rule.pike foreign_ident
 /lib/7.2/modules/LR.pmod/scanner.pike foreign_ident
 /lib/7.2/modules/Protocols.pmod/LDAP.pmod/client.pike foreign_ident
+/lib/7.2/modules/Thread.pmod foreign_ident
 /lib/7.2/modules/__default.pmod foreign_ident
 /lib/7.2/modules/system.pmod foreign_ident
 /lib/master.pike.in foreign_ident
diff --git a/lib/7.2/modules/Thread.pmod b/lib/7.2/modules/Thread.pmod
new file mode 100644
index 0000000000..448f08c542
--- /dev/null
+++ b/lib/7.2/modules/Thread.pmod
@@ -0,0 +1,24 @@
+#pike 7.3
+
+//
+// $Id: Thread.pmod,v 1.1 2002/09/30 18:45:20 grubba Exp $
+//
+// Pike 7.2 backward compatibility layer.
+//
+
+inherit Thread;
+
+class Condition
+{
+  inherit Thread::Condition;
+
+  // Old-style wait().
+  void wait(void|Mutex m)
+  {
+    if (!m) {
+      m = Mutex();
+      m->lock();
+    }
+    ::wait();
+  }
+}
diff --git a/src/threads.c b/src/threads.c
index 8488f011e6..e6fd8e13e1 100644
--- a/src/threads.c
+++ b/src/threads.c
@@ -1,5 +1,5 @@
 #include "global.h"
-RCSID("$Id: threads.c,v 1.185 2002/09/29 13:52:08 nilsson Exp $");
+RCSID("$Id: threads.c,v 1.186 2002/09/30 18:45:22 grubba Exp $");
 
 PMOD_EXPORT int num_threads = 1;
 PMOD_EXPORT int threads_disabled = 0;
@@ -1247,8 +1247,7 @@ void exit_mutex_key_obj(struct object *o)
  *!   @[Mutex]
  */
 
-/*! @decl void wait()
- *! @decl void wait(Thread.MutexKey mutex_key)
+/*! @decl void wait(Thread.MutexKey mutex_key)
  *!
  *! Wait for contition.
  *!
@@ -1258,72 +1257,60 @@ void exit_mutex_key_obj(struct object *o)
  *! waiting for the condition in one atomic operation. After waiting
  *! for the condition the mutex referenced by mutex_key will be re-locked.
  *!
+ *! @note
+ *!   In Pike 7.2 and earlier it was possible to call @[wait()]
+ *!   without arguments. This possibility was removed in Pike 7.3,
+ *!   since it lead to programs with deadlocks.
+ *!
  *! @seealso
  *!   @[Mutex->lock()]
  */
 void f_cond_wait(INT32 args)
 {
+  struct object *key;
+  struct mutex_storage *mut;
   COND_T *c;
 
   if(threads_disabled)
     Pike_error("Cannot wait for conditions when threads are disabled!\n");
+
+  get_all_args("condition->wait", args, "%o", &key);
       
+  if ((key->prog != mutex_key) ||
+      (!(OB2KEY(key)->initialized)) ||
+      (!(mut = OB2KEY(key)->mut))) {
+    Pike_error("Bad argument 1 to condition->wait()\n");
+  }
+
   if(args > 1) {
     pop_n_elems(args - 1);
     args = 1;
   }
 
-  c=THIS_COND;
-
-  if((args > 0) && !UNSAFE_IS_ZERO(Pike_sp-1))
-  {
-    struct object *key;
-    struct mutex_storage *mut;
-
-    if(Pike_sp[-1].type != T_OBJECT)
-      Pike_error("Bad argument 1 to condition->wait()\n");
-    
-    key=Pike_sp[-1].u.object;
-    
-    if(key->prog != mutex_key)
-      Pike_error("Bad argument 1 to condition->wait()\n");
+  c = THIS_COND;
 
-    if (OB2KEY(key)->initialized) {
-
-      mut = OB2KEY(key)->mut;
-      if(!mut)
-	Pike_error("Bad argument 1 to condition->wait()\n");
-
-      /* Unlock mutex */
-      mut->key=0;
-      OB2KEY(key)->mut=0;
-      co_signal(& mut->condition);
+  /* Unlock mutex */
+  mut->key=0;
+  OB2KEY(key)->mut=0;
+  co_signal(& mut->condition);
     
-      /* Wait and allow mutex operations */
-      SWAP_OUT_CURRENT_THREAD();
-      co_wait_interpreter(c);
-      SWAP_IN_CURRENT_THREAD();
-    
-      /* Lock mutex */
-      while(mut->key) {
-	SWAP_OUT_CURRENT_THREAD();
-	co_wait_interpreter(& mut->condition);
-	SWAP_IN_CURRENT_THREAD();
-	check_threads_etc();
-      }
-      mut->key=key;
-      OB2KEY(key)->mut=mut;
-      
-      pop_n_elems(args);
-      return;
-    }
-  }
-
+  /* Wait and allow mutex operations */
   SWAP_OUT_CURRENT_THREAD();
   co_wait_interpreter(c);
   SWAP_IN_CURRENT_THREAD();
-
-  pop_n_elems(args);
+    
+  /* Lock mutex */
+  while(mut->key) {
+    SWAP_OUT_CURRENT_THREAD();
+    co_wait_interpreter(& mut->condition);
+    SWAP_IN_CURRENT_THREAD();
+    check_threads_etc();
+  }
+  mut->key=key;
+  OB2KEY(key)->mut=mut;
+      
+  pop_stack();
+  return;
 }
 
 /*! @decl void signal()
@@ -1850,9 +1837,9 @@ void th_init(void)
 
   START_NEW_PROGRAM_ID(THREAD_CONDITION);
   ADD_STORAGE(COND_T);
-  /* function(void|object(mutex_key):void) */
+  /* function(object(mutex_key):void) */
   ADD_FUNCTION("wait",f_cond_wait,
-	       tFunc(tOr(tVoid,tObjIs_THREAD_MUTEX_KEY),tVoid),0);
+	       tFunc(tObjIs_THREAD_MUTEX_KEY,tVoid),0);
   /* function(:void) */
   ADD_FUNCTION("signal",f_cond_signal,tFunc(tNone,tVoid),0);
   /* function(:void) */
-- 
GitLab