From 2d3a39b5729a295d4e0ac416ff0280e3edca44c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Thu, 1 May 2014 17:44:18 +0200 Subject: Fix io:columns/0 timeout when invoked via user This patch fixes an issue where io:columns/0 times out when invoked from any application callback (or any supervisor/supervised module since the group leader is inherited). To reproduce the issue, one must simply call io:columns() from any application callback. You will notice the process will block for 2 seconds which then times out and returns {:error, :enotsup}. Note this bug only happens inside the erlang shell (using -noshell or escripts do not trigger the bug). To fix the bug, it is important to understand how io requests flow from application callback processes. Here are the steps followed: 1. Since io:columns/1 is timing out, the first step is to find out who is the group leader for the application callback process. Using process_info/1, we can see the parent process is the application_master and handles io_requests by delegating them to the group_leader. 2. By inspecting the application_master process, we can find the group_leader the message is sent is the registered process named user. The process is running the group module which does handle io:columns/1 requests delegating them to user_drv process. 3. The user_drv process does handle tty_geometry requests, except that a clause above ends up short-circuiting all tty_geometry requests from the user process. This patch moves the user clause below the specific driver messages. OTP-12241 --- lib/kernel/src/user_drv.erl | 5 ----- 1 file changed, 5 deletions(-) (limited to 'lib') diff --git a/lib/kernel/src/user_drv.erl b/lib/kernel/src/user_drv.erl index 79f80f6604..e6ce85c379 100644 --- a/lib/kernel/src/user_drv.erl +++ b/lib/kernel/src/user_drv.erl @@ -173,11 +173,6 @@ server_loop(Iport, Oport, Curr, User, Gr, IOQueue) -> {Iport,eof} -> Curr ! {self(),eof}, server_loop(Iport, Oport, Curr, User, Gr, IOQueue); - {User,Req} when element(1,Req) == tty_geometry; - element(1,Req) == get_unicode_state; - element(1,Req) == set_unicode_state -> - %% We ignore these requests from User, could be a bug? - server_loop(Iport, Oport, Curr, User, Gr, IOQueue); Req when element(1,Req) =:= User orelse element(1,Req) =:= Curr, tuple_size(Req) =:= 2 orelse tuple_size(Req) =:= 3 -> %% We match {User|Curr,_}|{User|Curr,_,_} -- cgit v1.2.3