changeset 1707:c05e2e4bdde7

Refactor to avoid dependence on recursive mutexes
author Adam Chlipala <adam@chlipala.net>
date Sun, 08 Apr 2012 16:24:16 -0400
parents 0152f65ced6a
children e263dab7b579
files src/c/urweb.c tests/goodbye.ur tests/goodbye.urp tests/goodbye.urs
diffstat 4 files changed, 41 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- a/src/c/urweb.c	Thu Mar 29 11:23:35 2012 -0400
+++ b/src/c/urweb.c	Sun Apr 08 16:24:16 2012 -0400
@@ -159,13 +159,7 @@
 static client **clients, *clients_free, *clients_used;
 static unsigned n_clients;
 
-static pthread_mutex_t clients_mutex =
-    #ifdef PTHREAD_RECURSIVE_MUTEX_INITIALIZER
-        PTHREAD_RECURSIVE_MUTEX_INITIALIZER
-    #else
-        PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
-    #endif
-    ;
+static pthread_mutex_t clients_mutex = PTHREAD_MUTEX_INITIALIZER;
 size_t uw_messages_max = SIZE_MAX;
 size_t uw_clients_max = SIZE_MAX;
 
@@ -230,20 +224,22 @@
 }
 
 static const char begin_msgs[] = "Content-type: text/plain\r\n\r\n";
+static pthread_t pruning_thread;
+static int pruning_thread_initialized = 0;
 
 static client *find_client(unsigned id) {
   client *c;
 
-  pthread_mutex_lock(&clients_mutex);
+  if (!pruning_thread_initialized || !pthread_equal(pruning_thread, pthread_self())) pthread_mutex_lock(&clients_mutex);
 
   if (id >= n_clients) {
-    pthread_mutex_unlock(&clients_mutex);
+    if (!pruning_thread_initialized || !pthread_equal(pruning_thread, pthread_self())) pthread_mutex_unlock(&clients_mutex);
     return NULL;
   }
 
   c = clients[id];
 
-  pthread_mutex_unlock(&clients_mutex);
+  if (!pruning_thread_initialized || !pthread_equal(pruning_thread, pthread_self())) pthread_mutex_unlock(&clients_mutex);
   return c;
 }
 
@@ -3291,6 +3287,8 @@
   cutoff = time(NULL) - ctx->app->timeout;
 
   pthread_mutex_lock(&clients_mutex);
+  pruning_thread = pthread_self();
+  pruning_thread_initialized = 1;
 
   for (c = clients_used; c; c = next) {
     next = c->next;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/goodbye.ur	Sun Apr 08 16:24:16 2012 -0400
@@ -0,0 +1,26 @@
+table boo : { Client : client, Channel : channel unit }
+
+fun doIt () =
+    me <- self;
+    ch <- channel;
+    dml (INSERT INTO boo (Client, Channel) VALUES ({[me]}, {[ch]}));
+    return <xml><body onload={let
+                                  fun loop () =
+                                      v <- recv ch;
+                                      alert "Someone left";
+                                      loop ()
+                              in
+                                  loop ()
+                              end}/></xml>
+
+task clientLeaves = fn cl =>
+                       debug "Client left";
+                       dml (DELETE FROM boo WHERE Client = {[cl]});
+                       queryI (SELECT (boo.Channel)
+                               FROM boo)
+                       (fn r => send r.1 ());
+                       debug "Done processing"
+
+fun main () = return <xml><body>
+  <form> <submit action={doIt}/> </form>
+</body></xml>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/goodbye.urp	Sun Apr 08 16:24:16 2012 -0400
@@ -0,0 +1,6 @@
+database dbname=goodbye
+sql goodbye.sql
+rewrite all Goodbye/*
+timeout 5
+
+goodbye
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/goodbye.urs	Sun Apr 08 16:24:16 2012 -0400
@@ -0,0 +1,1 @@
+val main : {} -> transaction page