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.

113 lines
2.9 KiB

  1. // Module: Log4CPLUS
  2. // File: pointer.cxx
  3. // Created: 6/2001
  4. // Author: Tad E. Smith
  5. //
  6. //
  7. // Copyright 2001-2010 Tad E. Smith
  8. //
  9. // Licensed under the Apache License, Version 2.0 (the "License");
  10. // you may not use this file except in compliance with the License.
  11. // You may obtain a copy of the License at
  12. //
  13. // http://www.apache.org/licenses/LICENSE-2.0
  14. //
  15. // Unless required by applicable law or agreed to in writing, software
  16. // distributed under the License is distributed on an "AS IS" BASIS,
  17. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  18. // See the License for the specific language governing permissions and
  19. // limitations under the License.
  20. #include <log4cplus/streams.h>
  21. #include <log4cplus/helpers/pointer.h>
  22. #include <log4cplus/thread/threads.h>
  23. #include <log4cplus/thread/impl/syncprims-impl.h>
  24. #include <log4cplus/config/windowsh-inc.h>
  25. #include <cassert>
  26. #if defined (LOG4CPLUS_HAVE_INTRIN_H)
  27. #include <intrin.h>
  28. #endif
  29. namespace log4cplus { namespace helpers {
  30. ///////////////////////////////////////////////////////////////////////////////
  31. // log4cplus::helpers::SharedObject dtor
  32. ///////////////////////////////////////////////////////////////////////////////
  33. SharedObject::~SharedObject()
  34. {
  35. assert(count == 0);
  36. }
  37. ///////////////////////////////////////////////////////////////////////////////
  38. // log4cplus::helpers::SharedObject public methods
  39. ///////////////////////////////////////////////////////////////////////////////
  40. void
  41. SharedObject::addReference() const
  42. {
  43. #if defined (LOG4CPLUS_SINGLE_THREADED)
  44. ++count;
  45. #elif defined (LOG4CPLUS_HAVE_CXX11_ATOMICS)
  46. std::atomic_fetch_add_explicit (&count, 1u,
  47. std::memory_order_relaxed);
  48. #elif defined (LOG4CPLUS_HAVE___SYNC_ADD_AND_FETCH)
  49. __sync_add_and_fetch (&count, 1);
  50. #elif defined (_WIN32) && defined (LOG4CPLUS_HAVE_INTRIN_H)
  51. _InterlockedIncrement (&count);
  52. #elif defined (_WIN32)
  53. InterlockedIncrement (&count);
  54. #else
  55. thread::MutexGuard guard (access_mutex);
  56. ++count;
  57. #endif
  58. }
  59. void
  60. SharedObject::removeReference() const
  61. {
  62. assert (count > 0);
  63. bool destroy;
  64. #if defined (LOG4CPLUS_SINGLE_THREADED)
  65. destroy = --count == 0;
  66. #elif defined (LOG4CPLUS_HAVE_CXX11_ATOMICS)
  67. destroy = std::atomic_fetch_sub_explicit (&count, 1u,
  68. std::memory_order_release) == 1;
  69. if (LOG4CPLUS_UNLIKELY (destroy))
  70. std::atomic_thread_fence (std::memory_order_acquire);
  71. #elif defined (LOG4CPLUS_HAVE___SYNC_SUB_AND_FETCH)
  72. destroy = __sync_sub_and_fetch (&count, 1) == 0;
  73. #elif defined (_WIN32) && defined (LOG4CPLUS_HAVE_INTRIN_H)
  74. destroy = _InterlockedDecrement (&count) == 0;
  75. #elif defined (_WIN32)
  76. destroy = InterlockedDecrement (&count) == 0;
  77. #else
  78. {
  79. thread::MutexGuard guard (access_mutex);
  80. destroy = --count == 0;
  81. }
  82. #endif
  83. if (LOG4CPLUS_UNLIKELY (destroy))
  84. delete this;
  85. }
  86. } } // namespace log4cplus { namespace helpers