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
21 #include "dcmtk/oflog/streams.h"
22 #include "dcmtk/oflog/helpers/pointer.h"
23 #include "dcmtk/oflog/thread/threads.h"
24 #include "dcmtk/oflog/thread/impl/syncimpl.h"
25 #include "dcmtk/oflog/config/windowsh.h"
26 #include <cassert>
27 #if defined (DCMTK_LOG4CPLUS_HAVE_INTRIN_H)
28 #include <intrin.h>
29 #endif
30
31
32 namespace dcmtk {
33 namespace log4cplus { namespace helpers {
34
35
36 ///////////////////////////////////////////////////////////////////////////////
37 // log4cplus::helpers::SharedObject dtor
38 ///////////////////////////////////////////////////////////////////////////////
39
~SharedObject()40 SharedObject::~SharedObject()
41 {
42 assert(count == 0);
43 }
44
45
46
47 ///////////////////////////////////////////////////////////////////////////////
48 // log4cplus::helpers::SharedObject public methods
49 ///////////////////////////////////////////////////////////////////////////////
50
51 void
addReference() const52 SharedObject::addReference() const
53 {
54 #if defined (DCMTK_LOG4CPLUS_SINGLE_THREADED)
55 ++count;
56
57 #elif defined (DCMTK_LOG4CPLUS_HAVE_CXX11_ATOMICS)
58 STD_NAMESPACE atomic_fetch_add_explicit (&count, 1u,
59 STD_NAMESPACE memory_order_relaxed);
60
61 #elif defined (DCMTK_LOG4CPLUS_HAVE___SYNC_ADD_AND_FETCH)
62 __sync_add_and_fetch (&count, 1);
63
64 #elif defined (_WIN32) && defined (DCMTK_LOG4CPLUS_HAVE_INTRIN_H)
65 _InterlockedIncrement (&count);
66
67 #elif defined (_WIN32)
68 InterlockedIncrement (&count);
69
70 #else
71 thread::MutexGuard guard (access_mutex);
72 ++count;
73
74 #endif
75 }
76
77
78 void
removeReference() const79 SharedObject::removeReference() const
80 {
81 assert (count > 0);
82 bool destroy;
83
84 #if defined (DCMTK_LOG4CPLUS_SINGLE_THREADED)
85 destroy = --count == 0;
86
87 #elif defined (DCMTK_LOG4CPLUS_HAVE_CXX11_ATOMICS)
88 destroy = STD_NAMESPACE atomic_fetch_sub_explicit (&count, 1u,
89 STD_NAMESPACE memory_order_release) == 1;
90 if (DCMTK_LOG4CPLUS_UNLIKELY (destroy))
91 STD_NAMESPACE atomic_thread_fence (STD_NAMESPACE memory_order_acquire);
92
93 #elif defined (DCMTK_LOG4CPLUS_HAVE___SYNC_SUB_AND_FETCH)
94 destroy = __sync_sub_and_fetch (&count, 1) == 0;
95
96 #elif defined (_WIN32) && defined (DCMTK_LOG4CPLUS_HAVE_INTRIN_H)
97 destroy = _InterlockedDecrement (&count) == 0;
98
99 #elif defined (_WIN32)
100 destroy = InterlockedDecrement (&count) == 0;
101
102 #else
103 {
104 thread::MutexGuard guard (access_mutex);
105 destroy = --count == 0;
106 }
107
108 #endif
109 if (DCMTK_LOG4CPLUS_UNLIKELY (destroy))
110 delete this;
111 }
112
113
114 } } // namespace log4cplus { namespace helpers
115 } // end namespace dcmtk
116