event_teardown(): retry uv_loop_close() instead of abort. #2903

abort() causes a bad exit; retry uv_loop_close() instead.

Before this change, this ruby script will cause nvim to abort() instead
of exiting cleanly:
```
  require 'open3'
  require 'base64'

  Open3.popen3('nvim --embed -u -NONE') {|stdin, stdout, stderr, wait_thr|
    # base64-encoded msgpack message for the vim_command "qa!".
    stdin.write Base64.decode64('kwKrdmltX2NvbW1hbmSRo3FhIQ==')
    puts wait_thr.value
  }
```

References ##2663
Closes #2466
Closes #2648

Helped-by: Rui Abreu Ferreira <raf-ep@gmx.com>
This commit is contained in:
oni-link 2015-05-13 09:08:35 +01:00 committed by Justin M. Keyes
parent 568d998549
commit 4aa6279a6b

View File

@ -69,24 +69,19 @@ void event_teardown(void)
process_events_from(immediate_events);
process_events_from(deferred_events);
// reset the stop_flag to ensure `uv_run` below won't exit early. This hack
// is required because the `process_events_from` above may call `event_push`
// which will set the stop_flag to 1(uv_stop)
uv_default_loop()->stop_flag = 0;
input_stop();
channel_teardown();
job_teardown();
server_teardown();
signal_teardown();
terminal_teardown();
// this last `uv_run` will return after all handles are stopped, it will
// also take care of finishing any uv_close calls made by other *_teardown
// functions.
uv_run(uv_default_loop(), UV_RUN_DEFAULT);
// abort that if we left unclosed handles
if (uv_loop_close(uv_default_loop())) {
abort();
}
do {
uv_run(uv_default_loop(), UV_RUN_DEFAULT);
} while (uv_loop_close(uv_default_loop()));
}
// Wait for some event