thread.h 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. // Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC")
  2. //
  3. // Permission to use, copy, modify, and/or distribute this software for any
  4. // purpose with or without fee is hereby granted, provided that the above
  5. // copyright notice and this permission notice appear in all copies.
  6. //
  7. // THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
  8. // REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
  9. // AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
  10. // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  11. // LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
  12. // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  13. // PERFORMANCE OF THIS SOFTWARE.
  14. #ifndef B10_THREAD_H
  15. #define B10_THREAD_H
  16. #include <exceptions/exceptions.h>
  17. #include <boost/noncopyable.hpp>
  18. #include <boost/function.hpp>
  19. namespace isc {
  20. namespace util {
  21. namespace thread {
  22. /// \brief A separate thread.
  23. ///
  24. /// A thread of execution. When created, starts running in the background.
  25. /// You can wait for it then or just forget it ever existed and leave it
  26. /// live peacefully.
  27. ///
  28. /// The interface is minimalistic for now. We may need to extend it later.
  29. ///
  30. /// \note While the objects of this class represent another thread, they
  31. /// are not thread-safe. You're not supposed to call wait() on the same
  32. /// object from multiple threads or so. They are reentrant (you can
  33. /// wait for different threads from different threads).
  34. class Thread : public boost::noncopyable {
  35. public:
  36. /// \brief There's an uncaught exception in a thread.
  37. ///
  38. /// When a thread terminates because it the main function of the thread
  39. /// throws, this one is re-thrown out of wait() and contains the what
  40. /// of the original exception.
  41. class UncaughtException : public isc::Exception {
  42. public:
  43. UncaughtException(const char* file, size_t line, const char* what) :
  44. Exception(file, line, what)
  45. {}
  46. };
  47. /// \brief Create and start a thread.
  48. ///
  49. /// Create a new thread and run body inside it.
  50. ///
  51. /// If you need to pass parameters to body, or return some result, you
  52. /// may just want to use boost::bind or alike to store them within the
  53. /// body functor.
  54. ///
  55. /// The body should terminate by exiting the function. If it throws, it
  56. /// is considered an error. You should generally catch any exceptions form
  57. /// within there and handle them somehow.
  58. ///
  59. /// \param main The code to run inside the thread.
  60. ///
  61. /// \throw std::bad_alloc if allocation of the new thread or other
  62. /// resources fails.
  63. /// \throw isc::InvalidOperation for other errors (should not happen).
  64. Thread(const boost::function<void()>& main);
  65. /// \brief Destructor.
  66. ///
  67. /// It is completely legitimate to destroy the thread without calling
  68. /// wait() before. In such case, the thread will just live on until it
  69. /// terminates. However, if the thread dies due to exception, for example,
  70. /// it's up to you to detect that, no error is reported from this class.
  71. ///
  72. /// \throw isc::InvalidOperation in the rare case of OS reporting a
  73. /// problem. This should not happen unless you messed up with the raw
  74. /// thread by the low-level API.
  75. ~Thread();
  76. /// \brief Wait for the thread to terminate.
  77. ///
  78. /// Waits until the thread terminates. Must be called at most once.
  79. ///
  80. /// \throw isc::InvalidOperation if the OS API returns error. This usually
  81. /// mean a programmer error (like two threads trying to wait on each
  82. /// other).
  83. /// \throw isc::InvalidOperation calling wait a second time.
  84. /// \throw UncaughtException if the thread terminated by throwing an
  85. /// exception instead of just returning from the function.
  86. void wait();
  87. private:
  88. class Impl;
  89. Impl* impl_;
  90. };
  91. }
  92. }
  93. }
  94. #endif