summaryrefslogtreecommitdiff
path: root/ace/RMCast/RMCast_Copy_On_Write.h
blob: 5efac63e80fb9d19b922436079ccf8a624906e75 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
/* -*- C++ -*- */
// $Id$
//

#ifndef ACE_RMCAST_COPY_ON_WRITE_H
#define ACE_RMCAST_COPY_ON_WRITE_H
#include "ace/pre.h"

#include "RMCast_Worker.h"
#include "ace/Synch.h"

//! A wrapper to implement reference counted collections
template<class COLLECTION, class ITERATOR>
class ACE_RMCast_Copy_On_Write_Collection
{
public:
  //! Constructor
  ACE_RMCast_Copy_On_Write_Collection (void);

  //! Increment the reference count
  void _incr_refcnt (void);

  //! Decrement the reference count
  void _decr_refcnt (void);

  //! The actual collection
  COLLECTION collection;

private:
  //! The reference count
  ACE_UINT32 refcount_;
};

// ****************************************************************

template<class COLLECTION, class ITERATOR>
class ACE_RMCast_Copy_On_Write_Read_Guard;

template<class COLLECTION, class ITERATOR>
class ACE_RMCast_Copy_On_Write_Write_Guard;

//! Base class for the Copy_On_Write collection, used to simplify the
//! declaration of the Write_Guard
template<class COLLECTION, class ITERATOR>
class ACE_RMCast_Copy_On_Write_Container
{
public:
  //! Constructor
  ACE_RMCast_Copy_On_Write_Container (void);

  //! Let the Write_Guard access the internal fields.
  friend class ACE_RMCast_Copy_On_Write_Write_Guard<COLLECTION,ITERATOR>;

  //! Let the Read_Guard access the internal fields.
  friend class ACE_RMCast_Copy_On_Write_Read_Guard<COLLECTION,ITERATOR>;

  //! A shorter name for the actual collection type
  typedef ACE_RMCast_Copy_On_Write_Collection<COLLECTION,ITERATOR> Collection;

protected:
  //! Number of pending writes
  int pending_writes_;

  //! If non-zero then a thread is changing the collection.
  /*!
   * Many threads can use the collection simulatenously, but only one
   * change it.
   */
  int writing_;

  //! A mutex to serialize access to the collection pointer.
  ACE_SYNCH_MUTEX mutex_;

  //! A condition variable to wait to synchronize multiple writers.
  ACE_SYNCH_CONDITION cond_;

  //! The collection, with reference counting added
  Collection *collection_;
};

// ****************************************************************

//! Implement a read guard for a reference counted collection
template<class COLLECTION, class ITERATOR>
class ACE_RMCast_Copy_On_Write_Read_Guard
{
public:
  typedef ACE_RMCast_Copy_On_Write_Collection<COLLECTION,ITERATOR> Collection;
  typedef ACE_RMCast_Copy_On_Write_Container<COLLECTION,ITERATOR> Container;

  //! Constructor
  ACE_RMCast_Copy_On_Write_Read_Guard (Container &container);

  //! Destructor
  ~ACE_RMCast_Copy_On_Write_Read_Guard (void);

  //! A reference to the collection
  Collection *collection;

private:
  //! Synchronization
  ACE_SYNCH_MUTEX &mutex_;
};

// ****************************************************************

//! Implement the write guard for a reference counted collecion
/*!
 * This helper class atomically increments the reference count of a
 * ACE_RMCast_Copy_On_Write_Collection and reads the current
 * collection in the Copy_On_Write class.
 */
template<class COLLECTION, class ITERATOR>
class ACE_RMCast_Copy_On_Write_Write_Guard
{
public:
  typedef ACE_RMCast_Copy_On_Write_Collection<COLLECTION,ITERATOR> Collection;
  typedef ACE_RMCast_Copy_On_Write_Container<COLLECTION,ITERATOR> Container;

  //! Constructor
  ACE_RMCast_Copy_On_Write_Write_Guard (Container &container);

  //! Destructor
  ~ACE_RMCast_Copy_On_Write_Write_Guard (void);

  //! The collection
  Collection *copy;

private:
  //! Keep a reference to the mutex
  ACE_SYNCH_MUTEX &mutex;

  //! Keep a reference to the condition variable
  ACE_SYNCH_CONDITION &cond;

  //! Use a reference to update the pending writes count
  int &pending_writes;

  //! Use a reference to update the writing flag
  int &writing_flag;

  //! Use this reference to update the collection once the
  //! modifications are finished.
  Collection *&collection;
};


// ****************************************************************

//! Implement a copy on write wrapper for a map-like collection
/*
 *
 * <B>WARNING: </B>  This class may be moved away in the future, I'm
 * investigating how it could be converted into a reusable component
 * in ACE.   I won't make promises on when will that happen, but I
 * won't promise that it will stay here either.
 *
 */
template<class KEY, class ITEM, class COLLECTION, class ITERATOR>
class ACE_RMCast_Copy_On_Write : public ACE_RMCast_Copy_On_Write_Container<COLLECTION,ITERATOR>
{
public:
  //! The Read_Guard trait
  typedef ACE_RMCast_Copy_On_Write_Read_Guard<COLLECTION,ITERATOR> Read_Guard;

  //! The Write_Guard trait
  typedef ACE_RMCast_Copy_On_Write_Write_Guard<COLLECTION,ITERATOR> Write_Guard;

  //! The underlying collection type
  typedef ACE_RMCast_Copy_On_Write_Collection<COLLECTION,ITERATOR> Collection;

  //! Constructor
  ACE_RMCast_Copy_On_Write (void);

  //! Destructor
  ~ACE_RMCast_Copy_On_Write (void);

  //! Iterate over all the elements invoking \param worker on each one.
  int for_each (ACE_RMCast_Worker<KEY,ITEM> *worker);

  //! Get the first key
  KEY first_key (void);

  /// Return non-zero if the collection is empty
  int empty (void);

  //! Add a new element
  int bind (KEY const & key, ITEM const & item);

  //! Remove an element
  int unbind (KEY const & key);

  //! Bind assuming the Write_Guard is held
  int bind_i (Write_Guard &guard, KEY const & key, ITEM const & item);

  //! Unbind assuming the Write_Guard is held
  int unbind_i (Write_Guard &guard, KEY const & key);
};

#if defined (__ACE_INLINE__)
#include "RMCast_Copy_On_Write.i"
#endif /* __ACE_INLINE__ */

#if defined (ACE_TEMPLATES_REQUIRE_SOURCE)
#include "RMCast_Copy_On_Write.cpp"
#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */

#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA)
#pragma implementation ("RMCast_Copy_On_Write.cpp")
#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */

#include "ace/post.h"
#endif /* ACE_RMCAST_COPY_ON_WRITE_H */