diff -r bc22395f60fa libinterp/corefcn/interpreter.cc
--- a/libinterp/corefcn/interpreter.cc	Fri Oct 22 12:05:59 2021 -0400
+++ b/libinterp/corefcn/interpreter.cc	Sun Oct 24 20:01:15 2021 +0200
@@ -91,7 +91,7 @@
 bool octave_interpreter_ready = false;
 
 // TRUE means we've processed all the init code and we are good to go.
-bool octave_initialized = false;
+std::atomic<bool> octave_initialized{false};
 
 OCTAVE_NAMESPACE_BEGIN
 
@@ -1909,7 +1909,7 @@
 
     can_interrupt = true;
     octave_interrupt_state = 0;
-    octave_signal_caught = 0;
+    octave_signal_caught = false;
     octave_restore_signal_mask ();
     catch_interrupts ();
   }
diff -r bc22395f60fa libinterp/corefcn/interpreter.h
--- a/libinterp/corefcn/interpreter.h	Fri Oct 22 12:05:59 2021 -0400
+++ b/libinterp/corefcn/interpreter.h	Sun Oct 24 20:01:15 2021 +0200
@@ -28,6 +28,7 @@
 
 #include "octave-config.h"
 
+#include <atomic>
 #include <map>
 #include <set>
 #include <stack>
@@ -66,7 +67,7 @@
 extern OCTINTERP_API bool octave_interpreter_ready;
 
 // TRUE means we've processed all the init code and we are good to go.
-extern OCTINTERP_API bool octave_initialized;
+extern OCTINTERP_API std::atomic<bool> octave_initialized;
 
 #include "oct-time.h"
 
diff -r bc22395f60fa libinterp/corefcn/sighandlers.cc
--- a/libinterp/corefcn/sighandlers.cc	Fri Oct 22 12:05:59 2021 -0400
+++ b/libinterp/corefcn/sighandlers.cc	Sun Oct 24 20:01:15 2021 +0200
@@ -27,6 +27,7 @@
 #  include "config.h"
 #endif
 
+#include <atomic>
 #include <csignal>
 #include <cstdlib>
 
@@ -65,7 +66,7 @@
   int pipe_handler_error_count = 0;
 
   // TRUE means we can be interrupted.
-  bool can_interrupt = false;
+  std::atomic<bool> can_interrupt{false};
 
   // TRUE means we should try to enter the debugger on SIGINT.
   bool Vdebug_on_interrupt = false;
@@ -82,7 +83,7 @@
   static bool Vsigterm_dumps_octave_core = true;
 
   // List of signals we have caught since last call to signal_handler.
-  static bool *signals_caught = nullptr;
+  static std::atomic<bool> *signals_caught = nullptr;
 
   static void
   my_friendly_exit (int sig, bool save_vars = true)
@@ -195,10 +196,10 @@
 
     for (int sig = 0; sig < octave_num_signals (); sig++)
       {
-        if (signals_caught[sig])
+        bool expected = true;
+        
+        if (signals_caught[sig].compare_exchange_strong(expected, false))
           {
-            signals_caught[sig] = false;
-
             if ((have_sigchld && sig == sigchld)
                 || (have_sigcld && sig == sigcld))
               {
@@ -224,9 +225,18 @@
                 // FIXME: is this really needed?  Does it do anything
                 // useful now?
 
-                if (pipe_handler_error_count++ > 100
-                    && octave_interrupt_state >= 0)
-                  octave_interrupt_state++;
+                const int curr_pipe_handler_error_count = pipe_handler_error_count++;
+                
+                if (curr_pipe_handler_error_count > 100)
+                  {
+                    sig_atomic_t curr_interrupt_state = octave_interrupt_state.load();
+                    sig_atomic_t new_interrupt_state;
+
+                    do new_interrupt_state = curr_interrupt_state + 1;
+                    while (curr_interrupt_state >= 0 &&
+                           !octave_interrupt_state.compare_exchange_weak(curr_interrupt_state, new_interrupt_state));
+
+                  }
               }
             else if (have_sighup && sig == sighup)
               my_friendly_exit (sighup, Vsighup_dumps_octave_core);
@@ -277,7 +287,7 @@
     // signal watcher thread so it should probably be more careful about
     // how it accesses global objects.
 
-    octave_signal_caught = 1;
+    octave_signal_caught = true;
 
     signals_caught[sig] = true;
 
@@ -297,7 +307,7 @@
 
         if (can_interrupt)
           {
-            octave_signal_caught = 1;
+            octave_signal_caught = true;
             octave_interrupt_state++;
           }
       }
@@ -366,7 +376,7 @@
   install_signal_handlers (void)
   {
     if (! signals_caught)
-      signals_caught = new bool [octave_num_signals ()];
+      signals_caught = new std::atomic<bool> [octave_num_signals ()];
 
     for (int i = 0; i < octave_num_signals (); i++)
       signals_caught[i] = false;
diff -r bc22395f60fa libinterp/corefcn/sighandlers.h
--- a/libinterp/corefcn/sighandlers.h	Fri Oct 22 12:05:59 2021 -0400
+++ b/libinterp/corefcn/sighandlers.h	Sun Oct 24 20:01:15 2021 +0200
@@ -36,6 +36,7 @@
 #if ! defined (octave_sighandlers_h)
 #define octave_sighandlers_h 1
 
+#include <atomic>
 #include "octave-config.h"
 
 #include "child-list.h"
@@ -56,7 +57,7 @@
   extern int pipe_handler_error_count;
 
   // TRUE means we can be interrupted.
-  extern OCTINTERP_API bool can_interrupt;
+  extern OCTINTERP_API std::atomic<bool> can_interrupt;
 
   extern OCTINTERP_API sig_handler *
   set_signal_handler (int sig, sig_handler *h,
diff -r bc22395f60fa liboctave/util/action-container.h
--- a/liboctave/util/action-container.h	Fri Oct 22 12:05:59 2021 -0400
+++ b/liboctave/util/action-container.h	Sun Oct 24 20:01:15 2021 +0200
@@ -28,6 +28,7 @@
 
 #include "octave-config.h"
 
+#include <atomic>
 #include <functional>
 
 // This class allows registering actions in a list for later
@@ -38,6 +39,21 @@
 
 namespace octave
 {
+  namespace util
+  {
+        template <typename T>
+        struct atomic_traits
+        {
+              typedef T type;
+        };
+
+        template <typename T>
+        struct atomic_traits<std::atomic<T>>
+        {
+              typedef T type;
+        };
+  }
+  
   class
   action_container
   {
@@ -105,7 +121,8 @@
 
     private:
 
-      T *m_ptr, m_val;
+      T *m_ptr;
+      typename util::atomic_traits<T>::type m_val;
     };
 
     // Deletes a class allocated using new.
diff -r bc22395f60fa liboctave/util/cmd-edit.cc
--- a/liboctave/util/cmd-edit.cc	Fri Oct 22 12:05:59 2021 -0400
+++ b/liboctave/util/cmd-edit.cc	Sun Oct 24 20:01:15 2021 +0200
@@ -778,7 +778,7 @@
   void
   gnu_readline::do_handle_interrupt_signal (void)
   {
-    octave_signal_caught = 0;
+    octave_signal_caught = false;
     octave_interrupt_state = 0;
 
     ::octave_rl_recover_from_interrupt ();
diff -r bc22395f60fa liboctave/util/oct-atomic.c
--- a/liboctave/util/oct-atomic.c	Fri Oct 22 12:05:59 2021 -0400
+++ b/liboctave/util/oct-atomic.c	Sun Oct 24 20:01:15 2021 +0200
@@ -29,9 +29,23 @@
 
 #include "oct-atomic.h"
 
+#if defined (__GNUC__)
+
+octave_idx_type
+octave_atomic_increment (octave_idx_type *x)
+{
+  return __sync_add_and_fetch (x,  1);
+}
+
+octave_idx_type
+octave_atomic_decrement (octave_idx_type *x)
+{
+  return __sync_sub_and_fetch (x, 1);
+}
+
 /* Some versions of GCC can't compile stdatomic.h with -fopenmp.  */
 
-#if defined (OCTAVE_STDATOMIC_H_OK)
+#elif defined (OCTAVE_STDATOMIC_H_OK)
 #  include <stdatomic.h>
 
 octave_idx_type
@@ -52,20 +66,6 @@
   return *x;
 }
 
-#elif defined (__GNUC__)
-
-octave_idx_type
-octave_atomic_increment (octave_idx_type *x)
-{
-  return __sync_add_and_fetch (x,  1);
-}
-
-octave_idx_type
-octave_atomic_decrement (octave_idx_type *x)
-{
-  return __sync_sub_and_fetch (x, 1);
-}
-
 #elif defined (_MSC_VER)
 #  include <intrin.h>
 
diff -r bc22395f60fa liboctave/util/quit.cc
--- a/liboctave/util/quit.cc	Fri Oct 22 12:05:59 2021 -0400
+++ b/liboctave/util/quit.cc	Sun Oct 24 20:01:15 2021 +0200
@@ -27,6 +27,7 @@
 #  include "config.h"
 #endif
 
+#include <atomic>
 #include <cstring>
 
 #include <ostream>
@@ -35,16 +36,16 @@
 
 #include "quit.h"
 
-sig_atomic_t octave_interrupt_state = 0;
+std::atomic<sig_atomic_t> octave_interrupt_state{0};
 
 // DEPRECATED in Octave 6.
 // This variable should never have been public.
-sig_atomic_t octave_exception_state = 0;
+std::atomic<sig_atomic_t> octave_exception_state{0};
 // Use this variable internally until the functions that use it can be
 // removed.
-static sig_atomic_t internal_exception_state;
+static std::atomic<sig_atomic_t> internal_exception_state;
 
-volatile sig_atomic_t octave_signal_caught = 0;
+volatile std::atomic<bool> octave_signal_caught{false};
 
 void (*octave_signal_hook) (void) = nullptr;
 void (*octave_interrupt_hook) (void) = nullptr;
@@ -123,10 +124,14 @@
   if (octave_signal_hook)
     octave_signal_hook ();
 
-  if (octave_interrupt_state > 0)
+  sig_atomic_t curr_interrupt_state = octave_interrupt_state.load();
+
+  while (curr_interrupt_state > 0 &&
+         !octave_interrupt_state.compare_exchange_weak(curr_interrupt_state, -1))
+    ;
+    
+  if (curr_interrupt_state > 0)
     {
-      octave_interrupt_state = -1;
-
       throw octave::interrupt_exception ();
     }
 }
@@ -165,10 +170,15 @@
 void
 octave_rethrow_exception (void)
 {
-  if (octave_interrupt_state)
+  sig_atomic_t curr_interrupt_state = octave_interrupt_state.load();
+  
+  // FIXME: Maybe it should be "curr_interrupt_state > 0" ??
+  while (curr_interrupt_state &&
+         !octave_interrupt_state.compare_exchange_weak(curr_interrupt_state, -1))
+    ;
+  
+  if (curr_interrupt_state)
     {
-      octave_interrupt_state = -1;
-
       throw octave::interrupt_exception ();
     }
   else
@@ -188,3 +198,8 @@
         }
     }
 }
+
+void octave_quit_c (void)
+{
+  octave_quit ();
+}
diff -r bc22395f60fa liboctave/util/quit.h
--- a/liboctave/util/quit.h	Fri Oct 22 12:05:59 2021 -0400
+++ b/liboctave/util/quit.h	Sun Oct 24 20:01:15 2021 +0200
@@ -30,6 +30,7 @@
 
 /* The signal header is just needed for the sig_atomic_t type.  */
 #if defined (__cplusplus)
+#  include <atomic>
 #  include <csignal>
 #  include <iosfwd>
 #  include <list>
@@ -222,14 +223,17 @@
     0: no interrupt pending
   < 0: handling interrupt
 */
-extern OCTAVE_API sig_atomic_t octave_interrupt_state;
+
+#if defined (__cplusplus)
+extern OCTAVE_API std::atomic<sig_atomic_t> octave_interrupt_state;
 
 #if defined (OCTAVE_PROVIDE_DEPRECATED_SYMBOLS)
 OCTAVE_DEPRECATED (6, "'octave_exception_state' is an obsolete internal variable; any uses should be removed")
-extern OCTAVE_API sig_atomic_t octave_exception_state;
+extern OCTAVE_API std::atomic<sig_atomic_t> octave_exception_state;
 #endif
 
-extern OCTAVE_API volatile sig_atomic_t octave_signal_caught;
+extern OCTAVE_API volatile std::atomic<bool> octave_signal_caught;
+#endif
 
 extern OCTAVE_API void octave_handle_signal (void);
 
@@ -251,9 +255,10 @@
 
 inline void octave_quit (void)
 {
-  if (octave_signal_caught)
+  bool expected = true;
+  
+  if (octave_signal_caught.compare_exchange_strong(expected, false))
     {
-      octave_signal_caught = 0;
       octave_handle_signal ();
     }
 }
@@ -261,17 +266,8 @@
 #define OCTAVE_QUIT octave_quit ()
 
 #else
-
-#define OCTAVE_QUIT                             \
-  do                                            \
-    {                                           \
-      if (octave_signal_caught)                 \
-        {                                       \
-          octave_signal_caught = 0;             \
-          octave_handle_signal ();              \
-        }                                       \
-    }                                           \
-  while (0)
+extern OCTAVE_API void octave_quit_c (void);
+#define OCTAVE_QUIT octave_quit_c ()
 #endif
 
 /* The following macros are obsolete.  Interrupting immediately by
