strange behavior of Glib.Io.read_chars ?
Pierre Letouzey <[email protected]> Mon, 12 Nov 2012 17:36:18 +0100 (CET)
| Newsgroups | gmane.comp.lang.ocaml.lib.gtk |
|---|---|
| Message-ID | <[email protected]> |
Hi all I'm currently playing with lablgtk, and especially trying its asynchronous I/O abilities. All seem to work quite well when I use Glib.Io.read inside a callback launched by Glib.Io.add_watch. But while writing this code, I noticed in the gtk documentation that g_io_channel_read is considered deprecated. So I tried to use instead Glib.Io.read_chars, but to no avail : the whole gtk app freezes forever when calling this function, even if there's something to read on the channel. Am I missing something ? Of course, I'm tempted to call that a bug, but my (labl)gtk kungfu is still really weak, I may have goofed something. Attached is a toy program demonstrating what I've tried and the freeze I get. Compile with: ocamlopt -o testgtkio -I +lablgtk2 unix.cmxa lablgtk.cmxa testgtkio.ml then run it in a terminal, normally the button toggles every seconds. Now type a newline in the terminal, and here everything freeze. If read_chars is replaced by read, we get instead a pop-up telling what have been read, and the button keeps on toggling. I'm using debian stable (squeeze), hence ocaml 3.11.2, lablgtk2 2.14.0, libgtk2 2.20, libglib 2.24.2, etc etc. If that's indeed a bug, please let me know, I'll submit to the bug tracker (with low priority since I'm quite happy with the "use read instead of read_chars" pragmatic solution). Greetings, Pierre Letouzey _______________________________________________ Lablgtk-list mailing list [email protected] https://lists.ocamlcore.org/cgi-bin/listinfo/lablgtk-list
testgtkio.ml
(text/x-ocaml, 1.3 KB)
(* to compile with :
ocamlopt -o testgtkio -I +lablgtk2 unix.cmxa lablgtk.cmxa testgtkio.ml *)
let all_conds = [ `ERR; `HUP; `IN; `NVAL; `PRI ] (* all but `OUT *)
let cond2string = function
| `ERR -> "ERR"
| `HUP -> "HUP"
| `IN -> "IN"
| `NVAL -> "NVAL"
| `OUT -> "OUT"
| `PRI -> "PRI"
let buf = String.make 1000 ' '
let inch = Glib.Io.channel_of_descr Unix.stdin
let stdin_reader conds =
let condstr = String.concat ";" (List.map cond2string conds) in
let msg =
if List.mem `IN conds || List.mem `PRI conds then
(* /!\ apparently, read_chars below is blocking, while read is ok *)
let len = Glib.Io.read_chars inch buf 0 1000 in
String.sub buf 0 len
else ""
in
GToolbox.message_box ~title:"IN" (condstr ^ ":\n" ^ msg);
true
let main () =
let _ = GtkMain.Main.init () in
let w = GWindow.window ~border_width:10 () in
let b = GButton.toggle_button ~label:"Hello World" ~packing:w#add () in
let _ = w#show ()
in
(* To visualize the freeze, we animate the button *)
let r = ref false in
let _ = Glib.Timeout.add ~ms:1000 ~callback:
(fun () -> r := not !r; b#set_active !r; true)
in
(* Install the stdin reader *)
let _ = Glib.Io.add_watch ~cond:all_conds ~callback:stdin_reader inch
in
GMain.Main.main ()
let _ = main ()