aboutsummaryrefslogtreecommitdiffstats
path: root/erts/etc/common/heart.c
diff options
context:
space:
mode:
authorBjörn-Egil Dahlberg <[email protected]>2012-10-11 16:38:04 +0200
committerBjörn-Egil Dahlberg <[email protected]>2012-10-16 16:16:28 +0200
commitd4172bde993275f26b62b53af85a5ac092846dad (patch)
treeb45163905f5d66860be97d7ac76e90d177fa60e9 /erts/etc/common/heart.c
parenta725c75107cea0ba72efdf18c9b135974b6c4339 (diff)
downloadotp-d4172bde993275f26b62b53af85a5ac092846dad.tar.gz
otp-d4172bde993275f26b62b53af85a5ac092846dad.tar.bz2
otp-d4172bde993275f26b62b53af85a5ac092846dad.zip
erts: Change ERL_CRASH_DUMP_SECONDS behaviour
Not setting ERL_CRASH_DUMP_SECONDS will now terminate beam immediately on a crash without writing a crash dump file. Setting ERL_CRASH_DUMP_SECONDS to 0 will also terminate beam immediately on a crash without writing a crash dump file, i.e. same as not setting ERL_CRASH_DUMP_SECONDS environment variable. Setting ERL_CRASH_DUMP_SECONDS to a negative value will let the beam wait indefinitely on the crash dump file being written. Setting ERL_CRASH_DUMP_SECONDS to a positive value will let the beam wait that many seconds on the crash dump file being written. A positive value will set both an alarm in beam AND a heart timeout for restart if heart is running. This is due to the change of 'heart' behavior when 'heart' is listening for a crash.
Diffstat (limited to 'erts/etc/common/heart.c')
-rw-r--r--erts/etc/common/heart.c71
1 files changed, 66 insertions, 5 deletions
diff --git a/erts/etc/common/heart.c b/erts/etc/common/heart.c
index dcb83c33ac..ed75a8f256 100644
--- a/erts/etc/common/heart.c
+++ b/erts/etc/common/heart.c
@@ -137,7 +137,8 @@
# endif
#endif
-#define HEART_COMMAND_ENV "HEART_COMMAND"
+#define HEART_COMMAND_ENV "HEART_COMMAND"
+#define ERL_CRASH_DUMP_SECONDS_ENV "ERL_CRASH_DUMP_SECONDS"
#define MSG_HDR_SIZE 2
#define MSG_HDR_PLUS_OP_SIZE 3
@@ -214,6 +215,7 @@ static void print_error(const char *,...);
static void debugf(const char *,...);
static void init_timestamp(void);
static time_t timestamp(time_t *);
+static int wait_until_close_write_or_env_tmo(int);
#ifdef __WIN32__
static BOOL enable_privilege(void);
@@ -650,15 +652,20 @@ do_terminate(int erlin_fd, int reason) {
(plus heart_beat_report_delay if under VxWorks), so we don't need
to call wd_reset().
*/
- struct msg message;
- int ret = 0;
+ int ret = 0, tmo=0;
+ char *tmo_env;
switch (reason) {
case R_SHUT_DOWN:
break;
case R_CRASHING:
- print_error("Waiting for dump");
- read_message(erlin_fd, &message); /* read until we get something */
+ if (is_env_set(ERL_CRASH_DUMP_SECONDS_ENV)) {
+ tmo_env = get_env(ERL_CRASH_DUMP_SECONDS_ENV);
+ tmo = atoi(tmo_env);
+ print_error("Waiting for dump - timeout set to %d seconds.", tmo);
+ wait_until_close_write_or_env_tmo(tmo);
+ free_env_val(tmo_env);
+ }
/* fall through */
case R_TIMEOUT:
case R_CLOSED:
@@ -709,6 +716,60 @@ do_terminate(int erlin_fd, int reason) {
} /* switch(reason) */
}
+
+/* Waits until something happens on socket or handle
+ *
+ * Uses global variables erlin_fd or hevent_dataready
+ */
+int wait_until_close_write_or_env_tmo(int tmo) {
+ int i = 0;
+
+#ifdef __WIN32__
+ DWORD wresult;
+ DWORD wtmo = INFINITE;
+
+ if (tmo >= 0) {
+ wtmo = tmo*1000 + 2;
+ }
+
+ wresult = WaitForSingleObject(hevent_dataready, wtmo);
+ if (wresult == WAIT_FAILED) {
+ print_last_error();
+ return -1;
+ }
+
+ if (wresult == WAIT_TIMEOUT) {
+ debugf("wait timed out\n");
+ i = 0;
+ } else {
+ debugf("wait ok\n");
+ i = 1;
+ }
+#else
+ fd_set read_fds;
+ int max_fd;
+ struct timeval timeout;
+ struct timeval *tptr = NULL;
+
+ max_fd = erlin_fd; /* global */
+
+ if (tmo >= 0) {
+ timeout.tv_sec = tmo; /* On Linux timeout is modified by select */
+ timeout.tv_usec = 0;
+ tptr = &timeout;
+ }
+
+ FD_ZERO(&read_fds);
+ FD_SET(erlin_fd, &read_fds);
+ if ((i = select(max_fd + 1, &read_fds, NULLFDS, NULLFDS, tptr)) < 0) {
+ print_error("error in select.");
+ return -1;
+ }
+#endif
+ return i;
+}
+
+
/*
* notify_ack
*