You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

119 lines
3.1 KiB

  1. // -*- C++ -*-
  2. // Copyright (C) 2010, Vaclav Haisman. All rights reserved.
  3. //
  4. // Redistribution and use in source and binary forms, with or without modifica-
  5. // tion, are permitted provided that the following conditions are met:
  6. //
  7. // 1. Redistributions of source code must retain the above copyright notice,
  8. // this list of conditions and the following disclaimer.
  9. //
  10. // 2. Redistributions in binary form must reproduce the above copyright notice,
  11. // this list of conditions and the following disclaimer in the documentation
  12. // and/or other materials provided with the distribution.
  13. //
  14. // THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
  15. // INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
  16. // FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  17. // APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
  18. // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU-
  19. // DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
  20. // OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  21. // ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  22. // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  23. // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  24. //! @file
  25. //! This file contains implementations of reader-writer locking
  26. //! primitive using other primitives, IOW poor man's rwlock.
  27. //! It does not contain any include guards because it is only a fragment
  28. //! to be included by syncprims-{pthreads,win32}.h.
  29. #if ! defined (INSIDE_LOG4CPLUS)
  30. # error "This header must not be be used outside log4cplus' implementation files."
  31. #endif
  32. // This implements algorithm described in "Concurrent Control with "Readers"
  33. // and "Writers"; P.J. Courtois, F. Heymans, and D.L. Parnas;
  34. // MBLE Research Laboratory; Brussels, Belgium"
  35. inline
  36. SharedMutex::SharedMutex ()
  37. : m1 (log4cplus::thread::Mutex::DEFAULT)
  38. , m2 (log4cplus::thread::Mutex::DEFAULT)
  39. , m3 (log4cplus::thread::Mutex::DEFAULT)
  40. , w (1, 1)
  41. , writer_count (0)
  42. , r (1, 1)
  43. , reader_count (0)
  44. { }
  45. inline
  46. SharedMutex::~SharedMutex ()
  47. { }
  48. inline
  49. void
  50. SharedMutex::rdlock () const
  51. {
  52. MutexGuard m3_guard (m3);
  53. SemaphoreGuard r_guard (r);
  54. MutexGuard m1_guard (m1);
  55. if (reader_count + 1 == 1)
  56. w.lock ();
  57. reader_count += 1;
  58. }
  59. inline
  60. void
  61. SharedMutex::rdunlock () const
  62. {
  63. MutexGuard m1_guard (m1);
  64. if (reader_count - 1 == 0)
  65. w.unlock ();
  66. reader_count -= 1;
  67. }
  68. inline
  69. void
  70. SharedMutex::wrlock () const
  71. {
  72. {
  73. MutexGuard m2_guard (m2);
  74. if (writer_count + 1 == 1)
  75. r.lock ();
  76. writer_count += 1;
  77. }
  78. try
  79. {
  80. w.lock ();
  81. }
  82. catch (...)
  83. {
  84. MutexGuard m2_guard (m2);
  85. writer_count -= 1;
  86. throw;
  87. }
  88. }
  89. inline
  90. void
  91. SharedMutex::wrunlock () const
  92. {
  93. w.unlock ();
  94. MutexGuard m2_guard (m2);
  95. if (writer_count - 1 == 0)
  96. r.unlock ();
  97. writer_count -= 1;
  98. }