diff libinterp/interp-core/event-queue.h @ 15396:1054ab58cd58

abstract unwind_protect * action-container.h: New file. Provide action_container base class. * event-queue.h: New file. Provide event_queue class. * unwind-prot.h: Derive unwind_protect from action_container.
author John W. Eaton <jwe@octave.org>
date Mon, 17 Sep 2012 19:52:20 -0400
parents
children 1d40c0514053
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libinterp/interp-core/event-queue.h	Mon Sep 17 19:52:20 2012 -0400
@@ -0,0 +1,126 @@
+/*
+
+Copyright (C) 2012 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_event_queue_h)
+#define octave_event_queue_h 1
+
+#include <queue>
+#include <memory>
+
+#include "action-container.h"
+
+class
+OCTINTERP_API
+event_queue : public action_container
+{
+public:
+
+  event_queue (void) : fifo () { }
+
+  // Destructor should not raise an exception, so all actions
+  // registered should be exception-safe (but setting error_state is
+  // allowed). If you're not sure, see event_queue_safe.
+
+  ~event_queue (void) { run (); }
+
+  void add (elem *new_elem)
+  {
+    fifo.push (new_elem);
+  }
+
+  void run_first (void)
+  {
+    if (! empty ())
+      {
+        // No leak on exception!
+        std::auto_ptr<elem> ptr (fifo.front ());
+        fifo.pop ();
+        ptr->run ();
+      }
+  }
+
+  void discard_first (void)
+  {
+    if (! empty ())
+      {
+        elem *ptr = fifo.front ();
+        fifo.pop ();
+        delete ptr;
+      }
+  }
+
+  size_t size (void) const { return fifo.size (); }
+
+protected:
+
+  std::queue<elem *> fifo;
+
+private:
+
+  // No copying!
+
+  event_queue (const event_queue&);
+
+  event_queue& operator = (const event_queue&);
+};
+
+// Like event_queue, but this one will guard against the
+// possibility of seeing an exception (or interrupt) in the cleanup
+// actions. Not that we can do much about it, but at least we won't
+// crash.
+
+class
+event_queue_safe : public event_queue
+{
+private:
+
+  static void gripe_exception (void);
+
+public:
+
+  event_queue_safe (void) : event_queue () { }
+
+  ~event_queue_safe (void)
+    {
+      while (! empty ())
+        {
+          try
+            {
+              run_first ();
+            }
+          catch (...) // Yes, the black hole. Remember we're in a dtor.
+            {
+              gripe_exception ();
+            }
+        }
+    }
+
+private:
+
+  // No copying!
+
+  event_queue_safe (const event_queue_safe&);
+
+  event_queue_safe& operator = (const event_queue_safe&);
+};
+
+#endif