1 /*
2  *
3  *  Copyright (C) 1996-2018, OFFIS e.V.
4  *  All rights reserved.  See COPYRIGHT file for details.
5  *
6  *  This software and supporting documentation were developed by
7  *
8  *    OFFIS e.V.
9  *    R&D Division Health
10  *    Escherweg 2
11  *    D-26121 Oldenburg, Germany
12  *
13  *
14  *  Module:  dcmimgle
15  *
16  *  Author:  Joerg Riesmeier
17  *
18  *  Purpose: DicomObjectCounter (Header)
19  *
20  */
21 
22 
23 #ifndef DIOBJCOU_H
24 #define DIOBJCOU_H
25 
26 #include "dcmtk/config/osconfig.h"
27 
28 #ifdef WITH_THREADS
29 #include "dcmtk/ofstd/ofthread.h"
30 #endif
31 
32 #include "dcmtk/dcmimgle/didefine.h"
33 
34 
35 /*---------------------*
36  *  class declaration  *
37  *---------------------*/
38 
39 /** Class to count number of instances (objects created from a certain class).
40  *  used to manage more than one reference to an object in a secure way.
41  */
42 class DCMTK_DCMIMGLE_EXPORT DiObjectCounter
43 {
44 
45  public:
46 
47     /** add a reference.
48      *  Increase the internal counter by 1.
49      */
addReference()50     inline void addReference()
51     {
52 #ifdef WITH_THREADS
53         theMutex.lock();
54 #endif
55         ++Counter;
56 #ifdef WITH_THREADS
57         theMutex.unlock();
58 #endif
59     }
60 
61     /** remove a reference.
62      *  Decrease the internal counter by 1 and delete the object only if the counter is zero.
63      */
removeReference()64     inline void removeReference()
65     {
66 #ifdef WITH_THREADS
67         theMutex.lock();
68 #endif
69         if (--Counter == 0)
70         {
71 #ifdef WITH_THREADS
72             theMutex.unlock();
73 #endif
74             delete this;
75 #ifdef WITH_THREADS
76         } else {
77             theMutex.unlock();
78 #endif
79         }
80     }
81 
82 
83  protected:
84 
85     /** constructor.
86      *  Internal counter is initialized with 1.
87      */
DiObjectCounter()88     DiObjectCounter()
89       : Counter(1)
90 #ifdef WITH_THREADS
91        ,theMutex()
92 #endif
93     {
94     }
95 
96     /** destructor
97      */
~DiObjectCounter()98     virtual ~DiObjectCounter()
99     {
100     }
101 
102 
103  private:
104 
105     /// internal counter
106     unsigned long Counter;
107 
108 #ifdef WITH_THREADS
109     /** if compiled for multi-thread operation, the Mutex protecting
110      *  access to the value of this object.
111      *  @remark this member is only available if DCMTK is compiled with thread
112      *  support enabled.
113      */
114     OFMutex theMutex;
115 #endif
116 };
117 
118 
119 #endif
120