diff --git a/lib/modules/Thread.pmod b/lib/modules/Thread.pmod
new file mode 100644
index 0000000000000000000000000000000000000000..433efa434fb69b0af386af965ac1e0eef35e2c74
--- /dev/null
+++ b/lib/modules/Thread.pmod
@@ -0,0 +1,73 @@
+constant Mutex=_static_modules.Builtin.Mutex;
+constant Condition=_static_modules.Builtin.Condition;
+
+class Fifo {
+  inherit Builtin.condition : r_cond;
+  inherit Builtin.condition: w_cond;
+  inherit Builtin.mutex: lock;
+  
+  mixed *buffer;
+  int r_ptr, w_ptr;
+  
+  int size() {  return (w_ptr+sizeof(buffer) - r_ptr) % sizeof(buffer);  }
+  
+  mixed read()
+    {
+      mixed tmp;
+      object key=lock::lock();
+      while(!size()) r_cond::wait(key);
+      tmp=buffer[r_ptr];
+      if(++r_ptr >= sizeof(buffer)) r_ptr=0;
+      w_cond::signal();
+      return tmp;
+    }
+  
+  void write(mixed v)
+    {
+      object key=lock::lock();
+      while(size() == sizeof(buffer)) w_cond::wait(key);
+      buffer[w_ptr]=v;
+      if(++w_ptr >= sizeof(buffer)) r_ptr=0;
+      r_cond::signal();
+    }
+  
+  varargs void create(int size)
+    {
+      buffer=allocate(size || 128);
+    }
+};
+
+class Queue {
+  inherit Builtin.condition: r_cond;
+  inherit Builtin.mutex: lock;
+  
+  mixed *buffer=allocate(16);
+  int r_ptr, w_ptr;
+  
+  int size() {  return w_ptr - r_ptr;  }
+  
+  mixed read()
+    {
+      mixed tmp;
+      object key=lock::lock();
+      while(!size()) r_cond::wait(key);
+      tmp=buffer[r_ptr++];
+      return tmp;
+    }
+  
+  void write(mixed v)
+    {
+      object key=lock::lock();
+      if(w_ptr >= sizeof(buffer))
+      {
+	buffer=buffer[r_ptr..];
+	buffer+=allocate(sizeof(buffer)+1);
+	w_ptr-=r_ptr;
+	r_ptr=0;
+      }
+      buffer[w_ptr]=v;
+      w_ptr++;
+      r_cond::signal();
+    }
+};
+