Date: Tue, 09 Nov 2004 12:26:55 +0100 (CET) Message-Id: <20041109.122655.41646513.andrieu at ijm.jussieu.fr> To: terpstra at gkec.tu-darmstadt.de Cc: lablgtk at kaba.or.jp Subject: Re: Bug in ml_g_io_add_watch From: Olivier Andrieu In-Reply-To: <20041109030536.GA9792 at muffin> References: <20041109030536.GA9792 at muffin> Mime-Version: 1.0 Content-Type: Text/Plain; charset=us-ascii Content-Transfer-Encoding: 7bit Hi, > Wesley W. Terpstra [Tue, 9 Nov 2004]: > Reproducing the bug: > > terpstra@muffin:~$ ocaml -I +lablgtk2 lablgtk.cma unix.cma gtkInit.cmo > Objective Caml version 3.08.1 > > # let ch = GMain.Io.channel_of_descr Unix.stdin ;; > val ch : GMain.Io.channel = > # let id = GMain.Io.add_watch ch ~cond:`IN ~callback:(fun () -> true) ;; > val id : GMain.Io.id = > # GMain.Io.remove id ;; > Exception: > Glib.Critical ("GLib", > "file gmain.c: line 1611 (g_source_remove): assertion `Tag > 0' failed"). > > Why the bug is happening: > > glib is upset because the value passed to g_source_remove is zero. > It is zero b/c GMain.Io.add_watch is broken. > This method is returning Unit in the file src/ml_glib.c: > > CAMLprim value ml_g_io_add_watch(value cond, value clos, value prio, value io) > { > g_io_add_watch_full(GIOChannel_val(io), > Option_val(prio,Int_val,0), > Io_condition_val(cond), > ml_g_io_channel_watch, > ml_global_root_new(clos), > ml_global_root_destroy); > return Val_unit; > return Val_int ( g_io_add_watch_full(GIOChannel_val(io), > Option_val(prio,Int_val,0), > Io_condition_val(cond), > ml_g_io_channel_watch, > ml_global_root_new(clos), > ml_g_destroy_notify) ); > } > > The fix is simply to kill the first two statements. > I have tested this and it appears to work. Thanks for the bug report. It is already corrected in the CVS repository. > Why was this disabled in the first place?? I don't known, looks like somebody forgot to remove the first two statements. > This bug is a problem b/c lablgtk2 provides no way of unhooking a > watch for `HUP and `IN at the same time. This means programs like > giotest.ml (from the examples) cannot be fixed for pipes. Either > they go into an infinite event spawn (consuming 100% CPU) when the > HUP occures, or they bind the `HUP event and then cannot unbind (or > close) the pipe's `IN event. Yeah, actually this function should have type val add_watch : condition list -> (condition list -> bool) -> channel -> id instead of val add_watch : condition -> (unit -> bool) -> channel -> id The problem if you set up two watches (one for `HUP and one for `IN) is that you don't known in what order the callbacks will be called when a `HUP+`IN event occurs. -- Olivier