|
@@ -0,0 +1,95 @@
|
|
|
+// Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC")
|
|
|
+//
|
|
|
+// Permission to use, copy, modify, and/or distribute this software for any
|
|
|
+// purpose with or without fee is hereby granted, provided that the above
|
|
|
+// copyright notice and this permission notice appear in all copies.
|
|
|
+//
|
|
|
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
|
|
|
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
|
+// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
|
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|
|
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
|
|
|
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
|
+// PERFORMANCE OF THIS SOFTWARE.
|
|
|
+
|
|
|
+#ifndef B10_THREAD_H
|
|
|
+#define B10_THREAD_H
|
|
|
+
|
|
|
+#include <exceptions/exceptions.h>
|
|
|
+
|
|
|
+#include <boost/noncopyable.hpp>
|
|
|
+#include <boost/function.hpp>
|
|
|
+
|
|
|
+namespace isc {
|
|
|
+namespace util {
|
|
|
+namespace thread {
|
|
|
+
|
|
|
+/// \brief A separate thread.
|
|
|
+///
|
|
|
+/// A thread of execution. When created, starts running in the background.
|
|
|
+/// You can wait for it then or just forget it ever existed and leave it
|
|
|
+/// live peacefully.
|
|
|
+///
|
|
|
+/// The interface is minimalistic for now. We may need to extend it later.
|
|
|
+class Thread : public boost::noncopyable {
|
|
|
+public:
|
|
|
+ /// \brief There's an uncaught exception in a thread.
|
|
|
+ ///
|
|
|
+ /// When a thread terminates because it the main function of the thread
|
|
|
+ /// throws, this one is re-thrown out of wait() and contains the what
|
|
|
+ /// of the original exception.
|
|
|
+ class UncaughtException : public isc::Exception {
|
|
|
+ public:
|
|
|
+ UncaughtException(const char* file, size_t line, const char* what) :
|
|
|
+ Exception(file, line, what)
|
|
|
+ {}
|
|
|
+ };
|
|
|
+ /// \brief Create and start a thread.
|
|
|
+ ///
|
|
|
+ /// Create a new thread and run body inside it.
|
|
|
+ ///
|
|
|
+ /// If you need to pass parameters to body, or return some result, you
|
|
|
+ /// may just want to use boost::bind or alike to store them within the
|
|
|
+ /// body functor.
|
|
|
+ ///
|
|
|
+ /// The body should terminate by exiting the function. If it throws, it
|
|
|
+ /// is considered an error. You should generally catch any exceptions form
|
|
|
+ /// within there and handle them somehow.
|
|
|
+ ///
|
|
|
+ /// \param body The code to run inside the thread.
|
|
|
+ ///
|
|
|
+ /// \throw std::bad_alloc if allocation of the new thread or other resources
|
|
|
+ /// fails.
|
|
|
+ Thread(boost::function<void()> body);
|
|
|
+ /// \brief Destructor.
|
|
|
+ ///
|
|
|
+ /// It is completely legitimate to destroy the thread without calling
|
|
|
+ /// wait() before. In such case, the thread will just live on until it
|
|
|
+ /// terminates. However, if the thread dies due to exception, for example,
|
|
|
+ /// it's up to you to detect that, no error is reported from this class.
|
|
|
+ ///
|
|
|
+ /// \throw isc::InvalidOperation in the rare case of OS reporting a
|
|
|
+ /// problem. This should not happen unless you messed up with the raw
|
|
|
+ /// thread by the low-level API.
|
|
|
+ ~ Thread();
|
|
|
+ /// \brief Wait for the thread to terminate.
|
|
|
+ ///
|
|
|
+ /// Waits until the thread terminates. Must be called at most once.
|
|
|
+ ///
|
|
|
+ /// \throw isc::InvalidOperation if the OS API returns error. This usually
|
|
|
+ /// mean a programmer error (like two threads trying to wait on each
|
|
|
+ /// other).
|
|
|
+ /// \throw isc::InvalidOperation calling wait a second time.
|
|
|
+ /// \throw UncaughtException if the thread terminated by throwing an
|
|
|
+ /// exception instead of just returning from the function.
|
|
|
+ void wait();
|
|
|
+private:
|
|
|
+ class Impl;
|
|
|
+ Impl* impl_;
|
|
|
+};
|
|
|
+
|
|
|
+}
|
|
|
+}
|
|
|
+}
|
|
|
+
|
|
|
+#endif
|