erlang/otp — pull request #351 by josevalim (2014-05-01 15:52:00+00:00)
Title: Fix io:columns/0 timeout when invoked from application callback

This patch fixes an issue where io:columns/0 times out timing 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 it does handle
io_requests by delegating to the group_leader:

https://github.com/erlang/otp/blob/aca0b6182b039333b4c963938878d9eecc85e5a1/lib/kernel/src/application_master.erl

2. By inspecting the application_master process, we can find the group_leader
the message is sent above is the registered process named user. The process is
running the group module which does handle io:columns/1 requests:

https://github.com/erlang/otp/blob/aca0b6182b039333b4c963938878d9eecc85e5a1/lib/kernel/src/group.erl#L263-L276

3. Those requests are delegated to the underlying driver defined here:

https://github.com/erlang/otp/blob/aca0b6182b039333b4c963938878d9eecc85e5a1/lib/kernel/src/group.erl#L37

4. The driver is the user_drv process. The user_drv process does handle
tty_geometry requests, except that a clause above ends up ignoring the
tty_geometry requests from the user process:

https://github.com/erlang/otp/blob/aca0b6182b039333b4c963938878d9eecc85e5a1/lib/kernel/src/user_drv.erl#L175-L180

This patch moves the user clause below the specific driver messages.