interprocess_sync.h 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  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 INTERPROCESS_SYNC_H
  15. #define INTERPROCESS_SYNC_H
  16. #include <string>
  17. namespace isc {
  18. namespace util {
  19. class InterprocessSyncLocker; // forward declaration
  20. /// \brief Interprocess Sync Class
  21. ///
  22. /// This class specifies an interface for mutual exclusion among
  23. /// co-operating processes. This is an abstract class and a real
  24. /// implementation such as InterprocessSyncFile should be used
  25. /// in code. Usage is as follows:
  26. ///
  27. /// 1. Client instantiates a sync object of an implementation (such as
  28. /// InterprocessSyncFile).
  29. /// 2. Client then creates an automatic (stack) object of
  30. /// InterprocessSyncLocker around the sync object. Such an object
  31. /// destroys itself and releases any acquired lock when it goes out of extent.
  32. /// 3. Client calls lock() method on the InterprocessSyncLocker.
  33. /// 4. Client performs task that needs mutual exclusion.
  34. /// 5. Client frees lock with unlock(), or simply returns from the basic
  35. /// block which forms the scope for the InterprocessSyncLocker.
  36. ///
  37. /// NOTE: All implementations of InterprocessSync should keep the
  38. /// is_locked_ member variable updated whenever their
  39. /// lock()/tryLock()/unlock() implementations are called.
  40. class InterprocessSync {
  41. // InterprocessSyncLocker is the only code outside this class that
  42. // should be allowed to call the lock(), tryLock() and unlock()
  43. // methods.
  44. friend class InterprocessSyncLocker;
  45. public:
  46. /// \brief Constructor
  47. ///
  48. /// Creates an interprocess synchronization object
  49. ///
  50. /// \param task_name Name of the synchronization task. This has to be
  51. /// identical among the various processes that need to be
  52. /// synchronized for the same task.
  53. InterprocessSync(const std::string& task_name) :
  54. task_name_(task_name), is_locked_(false)
  55. {}
  56. /// \brief Destructor
  57. virtual ~InterprocessSync() {}
  58. protected:
  59. /// \brief Acquire the lock (blocks if something else has acquired a
  60. /// lock on the same task name)
  61. ///
  62. /// \return Returns true if the lock was acquired, false otherwise.
  63. virtual bool lock() = 0;
  64. /// \brief Try to acquire a lock (doesn't block)
  65. ///
  66. /// \return Returns true if the lock was acquired, false otherwise.
  67. virtual bool tryLock() = 0;
  68. /// \brief Release the lock
  69. ///
  70. /// \return Returns true if the lock was released, false otherwise.
  71. virtual bool unlock() = 0;
  72. const std::string task_name_; ///< The task name
  73. bool is_locked_; ///< Is the lock taken?
  74. };
  75. /// \brief Interprocess Sync Locker Class
  76. ///
  77. /// This class is used for making automatic stack objects to manage
  78. /// locks that are released automatically when the block is exited
  79. /// (RAII). It is meant to be used along with InterprocessSync objects. See
  80. /// the description of InterprocessSync.
  81. class InterprocessSyncLocker {
  82. public:
  83. /// \brief Constructor
  84. ///
  85. /// Creates a lock manager around a interprocess synchronization object
  86. ///
  87. /// \param sync The sync object which has to be locked/unlocked by
  88. /// this locker object.
  89. InterprocessSyncLocker(InterprocessSync& sync) :
  90. sync_(sync)
  91. {}
  92. /// \brief Destructor
  93. ~InterprocessSyncLocker() {
  94. if (isLocked())
  95. unlock();
  96. }
  97. /// \brief Acquire the lock (blocks if something else has acquired a
  98. /// lock on the same task name)
  99. ///
  100. /// \return Returns true if the lock was acquired, false otherwise.
  101. bool lock() {
  102. return (sync_.lock());
  103. }
  104. /// \brief Try to acquire a lock (doesn't block)
  105. ///
  106. /// \return Returns true if a new lock could be acquired, false
  107. /// otherwise.
  108. bool tryLock() {
  109. return (sync_.tryLock());
  110. }
  111. /// \brief Check if the lock is taken
  112. ///
  113. /// \return Returns true if a lock is currently acquired, false
  114. /// otherwise.
  115. bool isLocked() const {
  116. return (sync_.is_locked_);
  117. }
  118. /// \brief Release the lock
  119. ///
  120. /// \return Returns true if the lock was released, false otherwise.
  121. bool unlock() {
  122. return (sync_.unlock());
  123. }
  124. protected:
  125. InterprocessSync& sync_; ///< Ref to underlying sync object
  126. };
  127. } // namespace util
  128. } // namespace isc
  129. #endif // INTERPROCESS_SYNC_H