123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104 |
- // 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.
- ///
- /// \note While the objects of this class represent another thread, they
- /// are not thread-safe. You're not supposed to call wait() on the same
- /// object from multiple threads or so. They are reentrant (you can
- /// wait for different threads from different threads).
- 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 main The code to run inside the thread.
- ///
- /// \throw std::bad_alloc if allocation of the new thread or other
- /// resources fails.
- /// \throw isc::InvalidOperation for other errors (should not happen).
- Thread(const boost::function<void()>& main);
- /// \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
|