X-Git-Url: http://matita.cs.unibo.it/gitweb/?a=blobdiff_plain;f=helm%2FDEVEL%2Focaml-http%2Fexamples%2Fthreads.ml;h=01f6dae4c3ea30ed25f0389be13b00915263cc86;hb=4167cea65ca58897d1a3dbb81ff95de5074700cc;hp=9eba49f37bc9b4dc43453bf3588b529621d429d8;hpb=9a072f192471daeca8cb409e991f0073b1d4271f;p=helm.git diff --git a/helm/DEVEL/ocaml-http/examples/threads.ml b/helm/DEVEL/ocaml-http/examples/threads.ml index 9eba49f37..01f6dae4c 100644 --- a/helm/DEVEL/ocaml-http/examples/threads.ml +++ b/helm/DEVEL/ocaml-http/examples/threads.ml @@ -2,7 +2,7 @@ (* OCaml HTTP - do it yourself (fully OCaml) HTTP daemon - Copyright (C) <2002> Stefano Zacchiroli + Copyright (C) <2002-2004> Stefano Zacchiroli This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -19,29 +19,45 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *) -let m = Mutex.create () in -let i = ref 10 in +open Http_types + +let m = Mutex.create () +let m_locked = ref true + +let critical f = + Mutex.lock m; + m_locked := true; + Lazy.force f; + m_locked := false; + Mutex.unlock m + + (** ocaml's Thread.unlock suspend the invoking process if the mutex is already + * unlocked, therefore we unlock it only if we know that it's currently locked + *) +let safe_unlock _ _ = if !m_locked then Mutex.unlock m + +let i = ref 10 let dump_i outchan = Http_daemon.respond ~body:(Printf.sprintf "i = %d\n" !i) outchan -in + let callback req outchan = match req#path with - | "/incr" -> - Mutex.lock m; - incr i; - dump_i outchan; - Unix.sleep 5; - Mutex.unlock m - | "/decr" -> - Mutex.lock m; - decr i; - dump_i outchan; - Unix.sleep 5; - Mutex.unlock m - | "/get" -> - Mutex.lock m; - dump_i outchan; - Mutex.unlock m + | "/incr" -> critical (lazy (incr i; dump_i outchan; Unix.sleep 5)) + | "/decr" -> critical (lazy (decr i; dump_i outchan; Unix.sleep 5)) + | "/get" -> critical (lazy (dump_i outchan)) | bad_request -> Http_daemon.respond_error outchan -in -Http_daemon.start' ~port:9999 ~mode:`Thread callback + +let spec = + { Http_daemon.default_spec with + port = 9999; + mode = `Thread; + callback = callback; + exn_handler = Some safe_unlock; + (** ocaml-http's default exn_handler is Pervasives.ignore. This means + * that threads holding the "m" mutex above may die without unlocking it. + * Using safe_unlock as an exception handler we ensure that "m" mutex is + * unlocked in case of exceptions (e.g. SIGPIPE) *) + } + +let _ = Http_daemon.main spec +