From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.1.3 (2006-06-01) on yquem.inria.fr X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=AWL autolearn=disabled version=3.1.3 X-Original-To: caml-list@yquem.inria.fr Delivered-To: caml-list@yquem.inria.fr Received: from discorde.inria.fr (discorde.inria.fr [192.93.2.38]) by yquem.inria.fr (Postfix) with ESMTP id 44AC6BC69 for ; Sat, 25 Aug 2007 15:58:48 +0200 (CEST) Received: from mail15.bluewin.ch (mail15.bluewin.ch [195.186.18.63]) by discorde.inria.fr (8.13.6/8.13.6) with ESMTP id l7PDwljr028020 for ; Sat, 25 Aug 2007 15:58:48 +0200 Received: from [10.0.1.2] (85.2.74.98) by mail15.bluewin.ch (Bluewin 7.3.121) id 46C9BE60001449F0 for caml-list@yquem.inria.fr; Sat, 25 Aug 2007 13:58:47 +0000 Mime-Version: 1.0 (Apple Message framework v752.2) Content-Transfer-Encoding: 7bit Message-Id: <9FA25C33-04DD-46BD-8959-873DDD2FFF82@epfl.ch> Content-Type: text/plain; charset=US-ASCII; delsp=yes; format=flowed To: caml-list@yquem.inria.fr From: =?ISO-8859-1?Q?Daniel_B=FCnzli?= Subject: Has the thread cancellation problem evolved ? Date: Sat, 25 Aug 2007 15:58:47 +0200 X-Mailer: Apple Mail (2.752.2) X-Miltered: at discorde with ID 46D03597.001 by Joe's j-chkmail (http://j-chkmail . ensmp . fr)! X-Spam: no; 0.00; bunzli:01 buenzli:01 type-safe:01 sandbox:01 rewriting:01 gerd:01 stolpmann:01 exn:01 computations:01 bug:01 computations:01 allocates:01 ffb:98 832:98 invoke:01 Hello everybody, I would like to raise again the problem of portable thread cancellation. The potential coming (?) of native dynamic linking brings the stunning perspective of type-safe, native, plugins. However to be able to use this in conjunction with user interfaces (ui) or in a malicious environment it becomes even more acute to be able to monitor/sandbox the execution of functions to avoid application hangs. Thread cancellation allows to invoke an arbitrary function f on a thread and stop its execution before completion, without introducing checks for conditions in f -- rewriting every function to do that goes against separation of concerns and malicious code could just ignore such conditions. Xavier Leroy mentioned many time [1,2,3] that "Thread.kill" is not an option. The argument is that this function is "unsafe" (not in the typical sense) because the victim may be holding ressources and it should be given the opportunity to release them before dying. As such this function is not implemented in the native thread library and will never be (btw. it is still not deprecated in 3.10). Other solutions have been proposed [4,5]. [5] by Gerd Stolpmann is portable. Note however that neither solution will work with uncooperative threads, i.e. those that never perform any system call or trigger the gc [7]. In this [6] message Xavier Leroy acknowledges that having a function "Thread.raise_in : exn -> Thread.t -> unit" to raise an exception in the given thread is a reasonable alternative to "Thread.kill". However the same message points out that this would be difficult to implement for native threads that are blocked on system calls and concludes : "So, the only easily implementable behavior is that the target thread of a "raise_to" operation can delay the processing of the exception until it returns from a system call. But this behavior is nearly useless..." While it wouldn't (or would it ?) solve the problem of uncooperative threads and hence be useless in a malicious environment, the "easy implementation" would be useful to monitor cooperative computations in general -- well those that do not block on system calls, but in a ui there may be many of these. I would appreciate having "Thread.raise_in" implemented, with the system call caveat properly documented, instead of having to resort to [5]. There is no feature request about this in the bug tracker. Before filling a potentially useless one I would like to know what you think about these problems and if there are things I have missed. Best, Daniel P.S. If your computations need to interact with the ui, forking is out of question. [1] http://caml.inria.fr/pub/ml-archives/caml-list/ 2000/05/4cf198c2f8dbf533cde462f2c65cf827.fr.html [2] http://caml.inria.fr/pub/ml-archives/caml-list/ 2002/10/740fa6facb5981e6dc94c4b7d13ea7ed.fr.html [3] http://caml.inria.fr/pub/ml-archives/caml-list/ 2003/05/8d9e6f406983d144111852cb7367ebc7.fr.html [4] http://caml.inria.fr/pub/ml-archives/caml-list/ 2005/12/52715b2ecd818ac61af3ffb34e914ec1.fr.html [5] http://caml.inria.fr/pub/ml-archives/caml-list/ 2005/11/71f680d0defd7ad890587f2b6d339ab5.fr.html [6] http://caml.inria.fr/pub/ml-archives/caml-list/ 2002/09/36902268c9eb832e0042bf74426e14d2.fr.html [7] The difference between cooperative and uncooperative threads can be seen by compiling the following two programs to _native_ code. The first one loops forever while the other doesn't (because it allocates). -- let () = ignore (Thread.create (fun () -> while true do ignore (1 + 2) done) ()); Thread.delay 1. -- let () = ignore (Thread.create (fun () -> while true do ignore (1. +. 2.) done) ()); Thread.delay 1. --