Erlang documentation says about gen_tcp:controlling_process/1:
Assigns a new controlling process Pid to Socket. The controlling process is the process which receives messages from the socket. If called by any other process than the current controlling process, {error, not_owner} is returned.
You created listen socket with option {active, false} and you read the socket synchronously with gen_tcp:recv/2 so your code will work even without calling of gen_tcp:controlling_process/1. However if you want to receive data asynchronously you must create listen socket with option {active, true}. In that case owner of accepted connection will receive messages about incoming data. So if you dont call gen_tcp:controlling_process/1 these messages will be sent to listener process instead of worker.