summaryrefslogtreecommitdiff
path: root/erts/emulator/beam/erl_proc_sig_queue.c
diff options
context:
space:
mode:
authorRickard Green <rickard@erlang.org>2023-01-10 19:22:47 +0100
committerRickard Green <rickard@erlang.org>2023-01-10 19:22:47 +0100
commitc3603bd7c0d5f2928c68157e843955c7bf25a9ef (patch)
treefee1e4c0f8dbf1981d2fd53d20253fb918305927 /erts/emulator/beam/erl_proc_sig_queue.c
parent0863bd30aabd035c83158c78046c5ffda16127e1 (diff)
parent43c3016e8f8d305e83e761a0b0e31d3a8f894f5b (diff)
downloaderlang-c3603bd7c0d5f2928c68157e843955c7bf25a9ef.tar.gz
Merge branch 'rickard/signal-handling-fix/23.3.4/OTP-18388' into rickard/signal-handling-fix/24.3.4/OTP-18388
* rickard/signal-handling-fix/23.3.4/OTP-18388: [erts] Prevent execution of a process while dirty signal handling is done
Diffstat (limited to 'erts/emulator/beam/erl_proc_sig_queue.c')
-rw-r--r--erts/emulator/beam/erl_proc_sig_queue.c36
1 files changed, 18 insertions, 18 deletions
diff --git a/erts/emulator/beam/erl_proc_sig_queue.c b/erts/emulator/beam/erl_proc_sig_queue.c
index 83b6991809..c2068b768c 100644
--- a/erts/emulator/beam/erl_proc_sig_queue.c
+++ b/erts/emulator/beam/erl_proc_sig_queue.c
@@ -220,7 +220,6 @@ typedef struct {
Eterm request_id;
} ErtsCLAData;
-static void wait_handle_signals(Process *c_p);
static void wake_handle_signals(Process *proc);
static int handle_msg_tracing(Process *c_p,
@@ -4968,11 +4967,7 @@ erts_proc_sig_handle_incoming(Process *c_p, erts_aint32_t *statep,
ErtsMessage *sig, ***next_nm_sig;
ErtsSigRecvTracing tracing;
- ASSERT(!(c_p->sig_qs.flags & FS_WAIT_HANDLE_SIGS));
- if (c_p->sig_qs.flags & FS_HANDLING_SIGS)
- wait_handle_signals(c_p);
- else
- c_p->sig_qs.flags |= FS_HANDLING_SIGS;
+ ASSERT(!(c_p->sig_qs.flags & (FS_WAIT_HANDLE_SIGS|FS_HANDLING_SIGS)));
ERTS_HDBG_CHECK_SIGNAL_PRIV_QUEUE(c_p, 0);
ERTS_LC_ASSERT(ERTS_PROC_LOCK_MAIN == erts_proc_lc_my_proc_locks(c_p));
@@ -4986,6 +4981,8 @@ erts_proc_sig_handle_incoming(Process *c_p, erts_aint32_t *statep,
}
}
+ c_p->sig_qs.flags |= FS_HANDLING_SIGS;
+
limit = *redsp;
*redsp = 0;
yield = 0;
@@ -7289,14 +7286,16 @@ erts_proc_sig_cleanup_queues(Process *c_p)
#endif
}
-/* Debug */
-
-static void
-wait_handle_signals(Process *c_p)
+void
+erts_proc_sig_do_wait_dirty_handle_signals__(Process *c_p)
{
/*
- * Process needs to wait on a dirty process signal
- * handler before it can handle signals by itself...
+ * A dirty process signal handler is currently handling
+ * signals for this process, so it is not safe for this
+ * process to continue to execute. This process needs to
+ * wait for the dirty signal handling to complete before
+ * it can continue executing. This since otherwise the
+ * signal queue can be seen in an inconsistent state.
*
* This should be a quite rare event. This only occurs
* when all of the following occurs:
@@ -7311,8 +7310,8 @@ wait_handle_signals(Process *c_p)
* dirty, gets scheduled on a normal scheduler, and
* then tries to handle signals itself.
*
- * If the above happens, the normal sceduler executing
- * the process will wait here until the dirty process
+ * If the above happens, the normal scheduler scheduling
+ * in the process will wait here until the dirty process
* signal handler is done with the process...
*/
erts_tse_t *event;
@@ -7340,18 +7339,17 @@ wait_handle_signals(Process *c_p)
erts_tse_return(event);
c_p->sig_qs.flags &= ~FS_WAIT_HANDLE_SIGS;
- c_p->sig_qs.flags |= FS_HANDLING_SIGS;
}
static void
wake_handle_signals(Process *proc)
{
/*
- * Wake scheduler sleeping in wait_handle_signals()
+ * Wake scheduler waiting in erts_proc_sig_check_wait_dirty_handle_signals()
* (above)...
*
- * This function should only be called by a dirty process
- * signal handler process...
+ * This function should only be called by a dirty process signal handler
+ * process...
*/
#ifdef DEBUG
Process *c_p = erts_get_current_process();
@@ -7369,6 +7367,8 @@ wake_handle_signals(Process *proc)
erts_tse_set(proc->scheduler_data->aux_work_data.ssi->event);
}
+/* Debug */
+
static void
debug_foreach_sig_heap_frags(ErlHeapFragment *hfrag,
void (*oh_func)(ErlOffHeap *, void *),