diff options
author | John Högberg <[email protected]> | 2018-11-13 11:55:48 +0100 |
---|---|---|
committer | John Högberg <[email protected]> | 2018-11-13 16:43:49 +0100 |
commit | d15bd6b9366ff4eef81ec9c4bcc875dfe694fe98 (patch) | |
tree | 01fae71e46df08266e586c2048ecff11bc7e58f8 /erts/emulator/nifs/unix | |
parent | d9682b02b81fa6e23e554b6e017650eb89ecebed (diff) | |
download | otp-d15bd6b9366ff4eef81ec9c4bcc875dfe694fe98.tar.gz otp-d15bd6b9366ff4eef81ec9c4bcc875dfe694fe98.tar.bz2 otp-d15bd6b9366ff4eef81ec9c4bcc875dfe694fe98.zip |
Avoid closing files in gc/monitor callbacks
Closing files in these callbacks could block scheduler progress
and cause major system instability. We now defer these operations
to a dedicated process instead.
This process may in turn block forever and prevent further orphaned
files from being closed, but it will keep the emulator itself from
misbehaving.
Diffstat (limited to 'erts/emulator/nifs/unix')
-rw-r--r-- | erts/emulator/nifs/unix/unix_prim_file.c | 7 |
1 files changed, 5 insertions, 2 deletions
diff --git a/erts/emulator/nifs/unix/unix_prim_file.c b/erts/emulator/nifs/unix/unix_prim_file.c index dea73db18a..169b193993 100644 --- a/erts/emulator/nifs/unix/unix_prim_file.c +++ b/erts/emulator/nifs/unix/unix_prim_file.c @@ -202,21 +202,24 @@ posix_errno_t efile_open(const efile_path_t *path, enum efile_modes_t modes, return errno; } -int efile_close(efile_data_t *d) { +int efile_close(efile_data_t *d, posix_errno_t *error) { efile_unix_t *u = (efile_unix_t*)d; int fd; + ASSERT(enif_thread_type() == ERL_NIF_THR_DIRTY_IO_SCHEDULER); ASSERT(erts_atomic32_read_nob(&d->state) == EFILE_STATE_CLOSED); ASSERT(u->fd != -1); fd = u->fd; u->fd = -1; + enif_release_resource(d); + /* close(2) either always closes (*BSD, Linux) or leaves the fd in an * undefined state (POSIX 2008, Solaris), so we must not retry on EINTR. */ if(close(fd) < 0) { - u->common.posix_errno = errno; + *error = errno; return 0; } |