diff options
author | Erlang/OTP <[email protected]> | 2015-01-30 16:56:50 +0100 |
---|---|---|
committer | Erlang/OTP <[email protected]> | 2015-01-30 16:56:50 +0100 |
commit | 30e91c934635836ebe126b3444e73eb50b506ec0 (patch) | |
tree | 96397a5eff1315f259d896f321c41be63c3e4491 /erts/emulator/beam/io.c | |
parent | 7b8af304c9e45540013eefc5b17ae03f8c36bc85 (diff) | |
parent | 86e4d8ead48501f00466d685c157eaa0921d96a8 (diff) | |
download | otp-30e91c934635836ebe126b3444e73eb50b506ec0.tar.gz otp-30e91c934635836ebe126b3444e73eb50b506ec0.tar.bz2 otp-30e91c934635836ebe126b3444e73eb50b506ec0.zip |
Merge branch 'egil/fix-crashdump-epmd/OTP-12447' into maint-17
* egil/fix-crashdump-epmd/OTP-12447:
erts: Check driver version before assigning callback
erts: Don't lookup invalid port for crashdump handling
erts: Reserve a file descriptor for the crashdump file
erts: Use emergency close to close epmd
erts: Extend driver interface with emergency_close
Diffstat (limited to 'erts/emulator/beam/io.c')
-rw-r--r-- | erts/emulator/beam/io.c | 27 |
1 files changed, 26 insertions, 1 deletions
diff --git a/erts/emulator/beam/io.c b/erts/emulator/beam/io.c index 9ae973e108..012a7d1a4b 100644 --- a/erts/emulator/beam/io.c +++ b/erts/emulator/beam/io.c @@ -7349,6 +7349,8 @@ no_stop_select_callback(ErlDrvEvent event, void* private) erts_send_error_to_logger_nogl(dsbufp); } +#define IS_DRIVER_VERSION_GE(DE,MAJOR,MINOR) \ + ((DE)->major_version >= (MAJOR) && (DE)->minor_version >= (MINOR)) static int init_driver(erts_driver_t *drv, ErlDrvEntry *de, DE_Handle *handle) @@ -7396,6 +7398,7 @@ init_driver(erts_driver_t *drv, ErlDrvEntry *de, DE_Handle *handle) drv->timeout = de->timeout ? de->timeout : no_timeout_callback; drv->ready_async = de->ready_async; drv->process_exit = de->process_exit; + drv->emergency_close = IS_DRIVER_VERSION_GE(de,3,2) ? de->emergency_close : NULL; if (de->stop_select) drv->stop_select = de->stop_select; else @@ -7414,6 +7417,8 @@ init_driver(erts_driver_t *drv, ErlDrvEntry *de, DE_Handle *handle) } } +#undef IS_DRIVER_VERSION_GE + void erts_destroy_driver(erts_driver_t *drv) { @@ -7557,7 +7562,7 @@ Port *erts_get_heart_port(void) if (!port) continue; /* only examine undead or alive ports */ - if (erts_atomic32_read_nob(&port->state) & ERTS_PORT_SFLGS_DEAD) + if (erts_atomic32_read_nob(&port->state) & ERTS_PORT_SFLGS_INVALID_DRIVER_LOOKUP) continue; /* immediate atom compare */ reg = port->common.u.alive.reg; @@ -7568,3 +7573,23 @@ Port *erts_get_heart_port(void) return NULL; } + +void erts_emergency_close_ports(void) +{ + int ix, max = erts_ptab_max(&erts_port); + + for (ix = 0; ix < max; ix++) { + Port *port = erts_pix2port(ix); + + if (!port) + continue; + /* only examine undead or alive ports */ + if (erts_atomic32_read_nob(&port->state) & ERTS_PORT_SFLGS_INVALID_DRIVER_LOOKUP) + continue; + + /* emergency close socket */ + if (port->drv_ptr->emergency_close) { + port->drv_ptr->emergency_close((ErlDrvData) port->drv_data); + } + } +} |