PTLib  Version 2.18.8
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
safecoll.h
Go to the documentation of this file.
1 /*
2  * safecoll.h
3  *
4  * Thread safe collection classes.
5  *
6  * Portable Windows Library
7  *
8  * Copyright (c) 2002 Equivalence Pty. Ltd.
9  *
10  * The contents of this file are subject to the Mozilla Public License
11  * Version 1.0 (the "License"); you may not use this file except in
12  * compliance with the License. You may obtain a copy of the License at
13  * http://www.mozilla.org/MPL/
14  *
15  * Software distributed under the License is distributed on an "AS IS"
16  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
17  * the License for the specific language governing rights and limitations
18  * under the License.
19  *
20  * The Original Code is Portable Windows Library.
21  *
22  * The Initial Developer of the Original Code is Equivalence Pty. Ltd.
23  *
24  * Contributor(s): ______________________________________.
25  */
26 
27 #ifndef PTLIB_SAFE_COLLECTION_H
28 #define PTLIB_SAFE_COLLECTION_H
29 
30 #ifdef P_USE_PRAGMA
31 #pragma interface
32 #endif
33 
34 
35 #include <ptlib/syncthrd.h>
36 
37 
38 #if P_TIMERS
39 class PTimer;
40 #endif
41 
42 
123 class PSafeObject : public PObject
124 {
125  PCLASSINFO(PSafeObject, PObject);
126  public:
131  PSafeObject();
132  PSafeObject(
133  const PSafeObject & other
134  );
135  explicit PSafeObject(
136  PSafeObject * indirectLock
137  );
138  explicit PSafeObject(
139  PReadWriteMutex & mutex
140  );
141  ~PSafeObject();
143 
165 
177 
195  __inline bool LockReadOnly() const { return InternalLockReadOnly(NULL); }
196  __inline bool LockReadOnly(const PDebugLocation & location) const { return InternalLockReadOnly(&location); }
197 
208  __inline void UnlockReadOnly() const { InternalUnlockReadOnly(NULL); }
209  __inline void UnlockReadOnly(const PDebugLocation & location) const { InternalUnlockReadOnly(&location); }
210 
228  __inline bool LockReadWrite() const { return InternalLockReadWrite(NULL); }
229  __inline bool LockReadWrite(const PDebugLocation & location) const { return InternalLockReadWrite(&location); }
230 
241  __inline void UnlockReadWrite() const { InternalUnlockReadWrite(NULL); }
242  __inline void UnlockReadWrite(const PDebugLocation & location) const { InternalUnlockReadWrite(&location); }
243 
253  void SafeRemove();
254 
259  unsigned IsSafelyBeingRemoved() const { return m_safelyBeingRemoved; }
260 
269 
281  virtual bool GarbageCollection();
282 
287  unsigned GetSafeReferenceCount() const { PWaitAndSignal lock(m_safetyMutex); return m_safeReferenceCount; }
289 
290  private:
291  void operator=(const PSafeObject &) { }
292 
293  bool InternalLockReadOnly(const PDebugLocation * location) const;
294  void InternalUnlockReadOnly(const PDebugLocation * location) const;
295  bool InternalLockReadWrite(const PDebugLocation * location) const;
296  void InternalUnlockReadWrite(const PDebugLocation * location) const;
297  PReadWriteMutex & InternalGetMutex() const;
298 
299  mutable PCriticalSection m_safetyMutex;
300  unsigned m_safeReferenceCount;
301  bool m_safelyBeingRemoved;
302  bool m_safeMutexCreated;
303  PReadWriteMutex * m_safeInUseMutex;
304 
305  friend class PSafeCollection;
306  friend class PSafePtrBase;
307  friend class PSafeLockReadOnly;
308  friend class PSafeLockReadWrite;
311 };
312 
313 
315 {
316  protected:
317  typedef bool (PSafeObject:: * LockFn)(const PDebugLocation * location) const;
318  typedef void (PSafeObject:: * UnlockFn)(const PDebugLocation * location) const;
319 
320  PSafeLockBase(const PSafeObject & object, const PDebugLocation * location, LockFn lock, UnlockFn unlock);
321 
322  public:
323  ~PSafeLockBase();
324 
325  bool Lock();
326  void Unlock();
327 
328  bool IsLocked() const { return m_locked; }
329  bool operator!() const { return !m_locked; }
330 
331  protected:
336  bool m_locked;
337 };
338 
339 
343 {
344  public:
346  : PSafeLockBase(object, NULL, &PSafeObject::InternalLockReadOnly, &PSafeObject::InternalUnlockReadOnly)
347  { }
348 };
349 
350 
354 {
355  public:
357  : PSafeLockBase(object, NULL, &PSafeObject::InternalLockReadWrite, &PSafeObject::InternalUnlockReadWrite)
358  { }
359 };
360 
361 
362 #if PTRACING
363  class PInstrumentedSafeLockReadOnly : public PSafeLockBase
364  {
365  public:
366  PInstrumentedSafeLockReadOnly(const PSafeObject & object, const PDebugLocation & location)
367  : PSafeLockBase(object, &location, &PSafeObject::InternalLockReadOnly, &PSafeObject::InternalUnlockReadOnly)
368  { }
369  };
370 
371  class PInstrumentedSafeLockReadWrite : public PSafeLockBase
372  {
373  public:
374  PInstrumentedSafeLockReadWrite(const PSafeObject & object, const PDebugLocation & location)
375  : PSafeLockBase(object, &location, &PSafeObject::InternalLockReadWrite, &PSafeObject::InternalUnlockReadWrite)
376  { }
377  };
378 
379  #define P_INSTRUMENTED_LOCK_READ_ONLY2(var, obj) PInstrumentedSafeLockReadOnly var((obj), P_DEBUG_LOCATION)
380  #define P_INSTRUMENTED_LOCK_READ_WRITE2(var, obj) PInstrumentedSafeLockReadWrite var((obj), P_DEBUG_LOCATION)
381 #else // P_TRACING
382  #define P_INSTRUMENTED_LOCK_READ_ONLY2(var, obj) PSafeLockReadOnly var((obj))
383  #define P_INSTRUMENTED_LOCK_READ_WRITE2(var, obj) PSafeLockReadWrite var((obj))
384 #endif // P_TRACING
385 
386 #define P_MAKE_UNIQUE_VAR(base) P_MAKE_UNIQUE_VAR1(base, __LINE__)
387 #define P_MAKE_UNIQUE_VAR1(base, line) P_MAKE_UNIQUE_VAR2(base, line)
388 #define P_MAKE_UNIQUE_VAR2(base, line) base##line
389 
390 #define P_READ_WRITE_RETURN_ARG_0()
391 #define P_READ_WRITE_RETURN_ARG_1(arg) ; if (!P_MAKE_UNIQUE_VAR(lock).IsLocked()) arg
392 #define P_READ_WRITE_RETURN_PART1(narg, args) P_READ_WRITE_RETURN_PART2(narg, args)
393 #define P_READ_WRITE_RETURN_PART2(narg, args) P_READ_WRITE_RETURN_ARG_##narg args
394 
395 #define P_INSTRUMENTED_LOCK_READ_ONLY(...) P_INSTRUMENTED_LOCK_READ_ONLY2(P_MAKE_UNIQUE_VAR(lock),*this) P_READ_WRITE_RETURN_PART1(PARG_COUNT(__VA_ARGS__), (__VA_ARGS__))
396 #define P_INSTRUMENTED_LOCK_READ_WRITE(...) P_INSTRUMENTED_LOCK_READ_WRITE2(P_MAKE_UNIQUE_VAR(lock),*this) P_READ_WRITE_RETURN_PART1(PARG_COUNT(__VA_ARGS__), (__VA_ARGS__))
397 
398 
411 class PSafeCollection : public PObject
412 {
413  PCLASSINFO(PSafeCollection, PObject);
414  public:
421  PCollection * collection
422  );
423 
429 
432  protected:
441  virtual PBoolean SafeRemove(
442  PSafeObject * obj
443  );
444 
453  virtual PBoolean SafeRemoveAt(
454  PINDEX idx
455  );
456 
457  public:
464  virtual void PrintOn(
465  ostream &strm // Stream to print the object into.
466  ) const;
467 
470  virtual void RemoveAll(
471  PBoolean synchronous = false
472  );
473 
479  PBoolean yes = true
480  ) { m_deleteObjects = yes; }
481 
487 
493 
496  virtual void DeleteObject(PObject * object) const;
497 
500  virtual void SetAutoDeleteObjects();
501 
506  PINDEX GetSize() const;
507 
512  PBoolean IsEmpty() const { return GetSize() == 0; }
513 
516  const PMutex & GetMutex() const { return m_collectionMutex; }
519 
520  protected:
521  void CopySafeCollection(PCollection * other);
523  bool SafeAddObject(PSafeObject * obj, PSafeObject * old);
524  void SafeRemoveObject(PSafeObject * obj);
525 
531 
532 #if P_TIMERS
533  PDECLARE_NOTIFIER(PTimer, PSafeCollection, DeleteObjectsTimeout);
534  PTimer * m_deleteObjectsTimer;
535 #endif
536 
537  private:
538  PSafeCollection(const PSafeCollection & other)
539  : PObject(other)
540  , m_collection()
541  , m_deleteObjects()
542  , m_deleteObjectsTimer()
543  { }
544  void operator=(const PSafeCollection &) { }
545 
546  friend class PSafePtrBase;
547 };
548 
549 
554 };
555 
568 class PSafePtrBase : public PObject
569 {
570  PCLASSINFO(PSafePtrBase, PObject);
571 
574  protected:
582  PSafePtrBase(
583  PSafeObject * obj = NULL,
585  );
586 
594  PSafePtrBase(
595  const PSafeCollection & safeCollection,
596  PSafetyMode mode,
597  PINDEX idx
598  );
599 
607  PSafePtrBase(
608  const PSafeCollection & safeCollection,
609  PSafetyMode mode,
610  PSafeObject * obj
611  );
612 
618  PSafePtrBase(
619  const PSafePtrBase & enumerator
620  );
621 
622  public:
625  ~PSafePtrBase();
627 
634  virtual Comparison Compare(
635  const PObject & obj
636  ) const;
637 
644  virtual void PrintOn(
645  ostream &strm // Stream to print the object into.
646  ) const;
648 
653  virtual void SetNULL();
654 
657  bool operator!() const { return m_currentObject == NULL; }
658 
661  PSafeObject * GetObject() const { return m_currentObject; }
662 
665  template <class T>
666  T * GetObjectAs() const { return dynamic_cast<T *>(m_currentObject); }
667 
671 
678  virtual PBoolean SetSafetyMode(
679  PSafetyMode mode
680  );
682 
683  virtual void Assign(const PSafePtrBase & ptr);
684  virtual void Assign(const PSafeCollection & safeCollection);
685  virtual void Assign(PSafeObject * obj);
686  virtual void Assign(PINDEX idx);
687 
688  protected:
689  virtual void Next();
690  virtual void Previous();
691  virtual void DeleteObject(PSafeObject * obj);
692 
696  };
698 
702  };
704 
705  virtual void LockPtr() { }
706  virtual void UnlockPtr() { }
707 
708  protected:
712 };
713 
714 
728 {
729  PCLASSINFO(PSafePtrMultiThreaded, PSafePtrBase);
730 
733  protected:
742  PSafeObject * obj = NULL,
744  );
745 
754  const PSafeCollection & safeCollection,
755  PSafetyMode mode,
756  PINDEX idx
757  );
758 
767  const PSafeCollection & safeCollection,
768  PSafetyMode mode,
769  PSafeObject * obj
770  );
771 
778  const PSafePtrMultiThreaded & enumerator
779  );
780 
781  public:
786 
793  virtual Comparison Compare(
794  const PObject & obj
795  ) const;
797 
802  virtual void SetNULL();
803 
810  virtual PBoolean SetSafetyMode(
811  PSafetyMode mode
812  );
814 
815  virtual void Assign(const PSafePtrMultiThreaded & ptr);
816  virtual void Assign(const PSafePtrBase & ptr);
817  virtual void Assign(const PSafeCollection & safeCollection);
818  virtual void Assign(PSafeObject * obj);
819  virtual void Assign(PINDEX idx);
820 
821  protected:
822  virtual void Next();
823  virtual void Previous();
824  virtual void DeleteObject(PSafeObject * obj);
825 
826  virtual void LockPtr() { m_mutex.Wait(); }
827  virtual void UnlockPtr();
828 
829  protected:
830  mutable PMutex m_mutex;
832 };
833 
834 
855 template <class T, class BaseClass = PSafePtrBase> class PSafePtr : public BaseClass
856 {
857  public:
868  T * obj = NULL,
870  ) : BaseClass(obj, mode) { }
871 
880  const PSafeCollection & safeCollection,
881  PSafetyMode mode = PSafeReadWrite,
882  PINDEX idx = 0
883  ) : BaseClass(safeCollection, mode, idx) { }
884 
893  const PSafeCollection & safeCollection,
894  PSafetyMode mode,
895  PSafeObject * obj
896  ) : BaseClass(safeCollection, mode, obj) { }
897 
904  const PSafePtr & ptr
905  ) : BaseClass(ptr) { }
906 
912  PSafePtr & operator=(const PSafePtr & ptr)
913  {
914  this->Assign(ptr);
915  return *this;
916  }
917 
922  PSafePtr & operator=(const PSafeCollection & safeCollection)
923  {
924  this->Assign(safeCollection);
925  return *this;
926  }
927 
943  PSafePtr & operator=(T * obj)
944  {
945  this->Assign(obj);
946  return *this;
947  }
948 
958  PSafePtr & operator=(PINDEX idx)
959  {
960  this->Assign(idx);
961  return *this;
962  }
963 
968  PSafePtr Set(T * obj)
969  {
970  this->LockPtr();
971  PSafePtr oldPtr = *this;
972  this->Assign(obj);
973  this->UnlockPtr();
974  return oldPtr;
975  }
977 
982  operator T*() const { return dynamic_cast<T *>(this->m_currentObject); }
983 
986  T & operator*() const { return *dynamic_cast<T *>(PAssertNULL(this->m_currentObject)); }
987 
990  T * operator->() const { return dynamic_cast<T *>(PAssertNULL(this->m_currentObject)); }
991 
996  T * operator++(int)
997  {
998  T * previous = dynamic_cast<T *>(this->m_currentObject);
999  this->Next();
1000  return previous;
1001  }
1002 
1008  {
1009  this->Next();
1010  return dynamic_cast<T *>(this->m_currentObject);
1011  }
1012 
1017  T * operator--(int)
1018  {
1019  T * previous = dynamic_cast<T *>(this->m_currentObject);
1020  this->Previous();
1021  return previous;
1022  }
1023 
1029  {
1030  this->Previous();
1031  return dynamic_cast<T *>(this->m_currentObject);
1032  }
1034 };
1035 
1036 
1040 template <class Base, class Derived>
1042 {
1043  PSafePtr<Derived> newPtr;
1044  if (dynamic_cast<Derived *>(oldPtr.GetObject()) != NULL)
1045  newPtr.Assign(oldPtr);
1046  return newPtr;
1047 }
1048 
1049 
1060 template <class Coll, class Base> class PSafeColl : public PSafeCollection
1061 {
1062  PCLASSINFO_WITH_CLONE(PSafeColl, PSafeCollection);
1063  public:
1069  : PSafeCollection(new Coll)
1070  { }
1071 
1075  PSafeColl(const PSafeColl & other)
1076  : PSafeCollection(new Coll)
1077  {
1078  PWaitAndSignal lock2(other.m_collectionMutex);
1079  this->CopySafeCollection(dynamic_cast<Coll *>(other.m_collection));
1080  }
1081 
1085  PSafeColl & operator=(const PSafeColl & other)
1086  {
1087  if (&other != this) {
1088  RemoveAll(true);
1089  PWaitAndSignal lock1(this->m_collectionMutex);
1090  PWaitAndSignal lock2(other.m_collectionMutex);
1091  CopySafeCollection(dynamic_cast<Coll *>(other.m_collection));
1092  }
1093  return *this;
1094  }
1096 
1104  Base * obj,
1105  PSafetyMode mode = PSafeReference
1106  ) {
1107  PWaitAndSignal mutex(this->m_collectionMutex);
1108  if (SafeAddObject(obj, NULL))
1109  return PSafePtr<Base>(*this, mode, this->m_collection->Append(obj));
1110  return NULL;
1111  }
1112 
1121  virtual PBoolean Remove(
1122  Base * obj
1123  ) {
1124  return SafeRemove(obj);
1125  }
1126 
1136  PINDEX idx
1137  ) {
1138  return SafeRemoveAt(idx);
1139  }
1140 
1147  PINDEX idx,
1149  ) {
1150  return PSafePtr<Base>(*this, mode, idx);
1151  }
1152 
1159  const Base & value,
1161  ) {
1162  this->m_collectionMutex.Wait();
1163  PSafePtr<Base> ptr(*this, PSafeReference, this->m_collection->GetValuesIndex(value));
1164  this->m_collectionMutex.Signal();
1165  ptr.SetSafetyMode(mode);
1166  return ptr;
1167  }
1169 };
1170 
1171 
1176 template <class Base> class PSafeArray : public PSafeColl<PArray<Base>, Base>
1177 {
1178  public:
1180 };
1181 
1182 
1187 template <class Base> class PSafeList : public PSafeColl<PList<Base>, Base>
1188 {
1189  public:
1191 };
1192 
1193 
1198 template <class Base> class PSafeSortedList : public PSafeColl<PSortedList<Base>, Base>
1199 {
1200  public:
1202 };
1203 
1204 
1215 template <class Coll, class Key, class Base> class PSafeDictionaryBase : public PSafeCollection
1216 {
1217  PCLASSINFO_WITH_CLONE(PSafeDictionaryBase, PSafeCollection);
1218  public:
1224  : PSafeCollection(new Coll) { }
1225 
1230  : PSafeCollection(new Coll)
1231  {
1232  PWaitAndSignal lock2(other.m_collectionMutex);
1233  CopySafeDictionary(dynamic_cast<Coll *>(other.m_collection));
1234  }
1235 
1240  {
1241  if (&other != this) {
1242  RemoveAll(true);
1244  PWaitAndSignal lock2(other.m_collectionMutex);
1245  CopySafeDictionary(dynamic_cast<Coll *>(other.m_collection));
1246  }
1247  return *this;
1248  }
1250 
1257  virtual void SetAt(const Key & key, Base * obj)
1258  {
1259  this->m_collectionMutex.Wait();
1260  if (SafeAddObject(obj, dynamic_cast<Coll &>(*this->m_collection).GetAt(key)))
1261  dynamic_cast<Coll &>(*this->m_collection).SetAt(key, obj);
1262  this->m_collectionMutex.Signal();
1263  }
1264 
1274  const Key & key
1275  ) {
1276  PWaitAndSignal mutex(this->m_collectionMutex);
1277  return SafeRemove(dynamic_cast<Coll &>(*this->m_collection).GetAt(key));
1278  }
1279 
1283  const Key & key
1284  ) {
1285  PWaitAndSignal lock(this->m_collectionMutex);
1286  return dynamic_cast<Coll &>(*this->m_collection).Contains(key);
1287  }
1288 
1295  PINDEX idx,
1297  ) {
1298  return PSafePtr<Base>(*this, mode, idx);
1299  }
1300 
1307  const Key & key,
1309  ) const {
1310  this->m_collectionMutex.Wait();
1311  PSafePtr<Base> ptr(dynamic_cast<Coll &>(*this->m_collection).GetAt(key), PSafeReference);
1312  this->m_collectionMutex.Signal();
1313  ptr.SetSafetyMode(mode);
1314  return ptr;
1315  }
1316 
1322  const Key & key,
1324  ) const {
1325  this->m_collectionMutex.Wait();
1326  PSafePtr<Base> ptr(*this, PSafeReference, dynamic_cast<Coll &>(*this->m_collection).GetAt(key));
1327  this->m_collectionMutex.Signal();
1328  ptr.SetSafetyMode(mode);
1329  return ptr;
1330  }
1331 
1333  const Key & key,
1335  ) const { return FindIterator(key, mode); }
1336 
1339  virtual bool Move(
1340  const Key & from,
1341  const Key & to
1342  ) {
1343  PWaitAndSignal mutex(this->m_collectionMutex);
1344  if (dynamic_cast<Coll &>(*this->m_collection).GetAt(to) != NULL)
1345  return false;
1346  dynamic_cast<Coll &>(*this->m_collection).SetAt(to, dynamic_cast<Coll &>(*this->m_collection).GetAt(from));
1347  return true;
1348  }
1349 
1355  {
1356  if (this == &other)
1357  return;
1358 
1359  *this = other;
1360  this->AllowDeleteObjects(); // We now own the objects, need to put this back on
1361 
1362  // Remove from other without deleting them
1363  bool del = other.m_deleteObjects;
1364  other.DisallowDeleteObjects();
1365  other.RemoveAll();
1366  other.AllowDeleteObjects(del);
1367  }
1368 
1372  {
1373  PArray<Key> keys;
1374  this->m_collectionMutex.Wait();
1375  dynamic_cast<Coll &>(*this->m_collection).AbstractGetKeys(keys);
1376  this->m_collectionMutex.Signal();
1377  return keys;
1378  }
1380 };
1381 
1382 
1387 template <class K, class D>
1388  class PSafeDictionary : public PSafeDictionaryBase<PDictionary<K, D>, K, D>
1389 {
1390  public:
1391  typedef K key_type;
1392  typedef D data_type;
1395 
1398  class iterator;
1399  class const_iterator;
1401  protected:
1402  K * m_internal_first; // Must be first two members
1404 
1407  PINDEX m_position;
1408 
1410  : m_internal_first(NULL)
1411  , m_internal_second(NULL)
1412  , m_dictionary(NULL)
1414  {
1415  }
1416 
1417  iterator_base(const dict_type * dict)
1418  : m_dictionary(dict)
1419  , m_keys(dict->GetKeys())
1420  {
1421  this->SetPosition(0);
1422  }
1423 
1424  iterator_base(const dict_type * dict, const K & key)
1425  : m_dictionary(dict)
1426  , m_keys(dict->GetKeys())
1427  {
1428  this->SetPosition(m_keys.GetValuesIndex(key));
1429  }
1430 
1431  bool SetPosition(PINDEX position)
1432  {
1433  if (position >= this->m_keys.GetSize()) {
1434  this->m_position = P_MAX_INDEX;
1435  this->m_internal_first = NULL;
1436  this->m_internal_second.SetNULL();
1437  return false;
1438  }
1439 
1440  this->m_position = position;
1441  this->m_internal_first = &this->m_keys[position];
1443  return this->m_internal_second == NULL;
1444  }
1445 
1446  void Next() { while (this->SetPosition(this->m_position+1)) { } }
1447  void Prev() { while (this->SetPosition(this->m_position > 0 ? this->m_position+1 : P_MAX_INDEX)) { } }
1448 
1449  public:
1450  bool operator==(const iterator_base & it) const { return this->m_position == it.m_position; }
1451  bool operator!=(const iterator_base & it) const { return this->m_position != it.m_position; }
1452  };
1453 
1455  public:
1456  const K & first;
1458 
1459  private:
1460  iterator_pair() : first(reinterpret_cast<const K &>(0)) { }
1461  };
1462 
1463  class iterator : public iterator_base, public std::iterator<std::forward_iterator_tag, iterator_pair> {
1464  protected:
1465  iterator(dict_type * dict) : iterator_base(dict) { }
1466  iterator(dict_type * dict, const K & key) : iterator_base(dict, key) { }
1467 
1468  public:
1469  iterator() { }
1470 
1471  iterator operator++() { this->Next(); return *this; }
1472  iterator operator--() { this->Prev(); return *this; }
1473  iterator operator++(int) { iterator it = *this; this->Next(); return it; }
1474  iterator operator--(int) { iterator it = *this; this->Prev(); return it; }
1475 
1476  const iterator_pair * operator->() const { return reinterpret_cast<const iterator_pair *>(this); }
1477  const iterator_pair & operator* () const { return *reinterpret_cast<const iterator_pair *>(this); }
1478 
1479  friend class PSafeDictionary<K, D>;
1480  };
1481 
1482  iterator begin() { return iterator(this); }
1483  iterator end() { return iterator(); }
1484  iterator find(const K & key) { return iterator(this, key); }
1485 
1486 
1487  class const_iterator : public iterator_base, public std::iterator<std::forward_iterator_tag, iterator_pair> {
1488  protected:
1489  const_iterator(const dict_type * dict) : iterator_base(dict) { }
1490  const_iterator(const dict_type * dict, const K & key) : iterator_base(dict, key) { }
1491 
1492  public:
1494  const_iterator(const typename dict_type::iterator & it) : iterator_base(it) { }
1495 
1496  const_iterator operator++() { this->Next(); return *this; }
1497  const_iterator operator--() { this->Prev(); return *this; }
1498  const_iterator operator++(int) { const_iterator it = *this; this->Next(); return it; }
1499  const_iterator operator--(int) { const_iterator it = *this; this->Prev(); return it; }
1500 
1501  const iterator_pair * operator->() const { return reinterpret_cast<const iterator_pair *>(this); }
1502  const iterator_pair & operator* () const { return *reinterpret_cast<const iterator_pair *>(this); }
1503 
1504  friend class PSafeDictionary<K, D>;
1505  };
1506 
1507  const_iterator begin() const { return const_iterator(this); }
1508  const_iterator end() const { return const_iterator(); }
1509  const_iterator find(const K & key) const { return const_iterator(this, key); }
1510 
1511  void erase(const iterator & it) { this->RemoveAt(it->first); }
1512  void erase(const const_iterator & it) { this->RemoveAt(it->first); }
1514 };
1515 
1516 
1517 #endif // PTLIB_SAFE_COLLECTION_H
1518 
1519 
1520 // End Of File ///////////////////////////////////////////////////////////////
T * operator++(int)
Post-increment the pointer.
Definition: safecoll.h:996
Information about a source file location.
Definition: object.h:333
PSafePtr< Base > value_type
Definition: safecoll.h:1179
PSafeObject * m_currentObject
Definition: safecoll.h:710
This class defines a base class for thread-safe pointer to an object.
Definition: safecoll.h:727
const_iterator operator--()
Definition: safecoll.h:1497
iterator(dict_type *dict, const K &key)
Definition: safecoll.h:1466
PMutex & GetMutex()
Definition: safecoll.h:517
friend class PInstrumentedSafeLockReadWrite
Definition: safecoll.h:310
iterator()
Definition: safecoll.h:1469
This class waits for the semaphore on construction and automatically signals the semaphore on destruc...
Definition: psync.h:115
iterator find(const K &key)
Definition: safecoll.h:1484
virtual PBoolean DeleteObjectsToBeRemoved()
Delete any objects that have been removed.
virtual PSafePtr< Base > Append(Base *obj, PSafetyMode mode=PSafeReference)
Add an object to the collection.
Definition: safecoll.h:1103
value_type m_internal_second
Definition: safecoll.h:1403
const_iterator operator--(int)
Definition: safecoll.h:1499
PSafePtr< D > value_type
Definition: safecoll.h:1393
PMutex m_collectionMutex
Definition: safecoll.h:527
virtual void UnlockPtr()
Definition: safecoll.h:706
PList< PSafeObject > m_toBeRemoved
Definition: safecoll.h:529
virtual PINDEX GetSize() const
Get size of array.
iterator_base(const dict_type *dict)
Definition: safecoll.h:1417
This class defines a base class for thread-safe pointer to an object.
Definition: safecoll.h:568
const dict_type * m_dictionary
Definition: safecoll.h:1405
const K & first
Definition: safecoll.h:1456
EnterSafetyModeOption
Definition: safecoll.h:693
K key_type
Definition: safecoll.h:1391
This class defines a thread-safe enumeration of object in a collection.
Definition: safecoll.h:855
iterator begin()
Definition: safecoll.h:1482
T * operator->() const
Allow access to the physical object the pointer is pointing to.
Definition: safecoll.h:990
PSafeObject * GetObject() const
Return pointer to safe object.
Definition: safecoll.h:661
void Prev()
Definition: safecoll.h:1447
This class defines a thread-safe array of objects.
Definition: safecoll.h:1388
PBoolean SafeReference()
Increment the reference count for object.
LockFn m_lock
Definition: safecoll.h:334
virtual void SetAutoDeleteObjects()
Start a timer to automatically call DeleteObjectsToBeRemoved().
Definition: safecoll.h:551
~PSafePtrBase()
Unlock and dereference the PSafeObject this is pointing to.
PSafeObject * m_objectToDelete
Definition: safecoll.h:831
ExitSafetyModeOption
Definition: safecoll.h:699
PSafePtrMultiThreaded(PSafeObject *obj=NULL, PSafetyMode mode=PSafeReference)
Create a new pointer to a PSafeObject.
virtual bool Move(const Key &from, const Key &to)
Move an object from one key location to another.
Definition: safecoll.h:1339
This class implements critical section mutexes using the most efficient mechanism available on the ho...
Definition: mutex.h:270
PSafePtr Set(T *obj)
Set the safe pointer to the specified object.
Definition: safecoll.h:968
__inline void UnlockReadOnly(const PDebugLocation &location) const
Definition: safecoll.h:209
PSafeColl(const PSafeColl &other)
Copy constructor for safe collection.
Definition: safecoll.h:1075
PSafePtrBase(PSafeObject *obj=NULL, PSafetyMode mode=PSafeReference)
Create a new pointer to a PSafeObject.
iterator end()
Definition: safecoll.h:1483
PCollection * m_collection
Definition: safecoll.h:526
PSafePtr(const PSafeCollection &safeCollection, PSafetyMode mode=PSafeReadWrite, PINDEX idx=0)
Create a new pointer to a PSafeObject.
Definition: safecoll.h:879
This class defines a thread-safe array of objects.
Definition: safecoll.h:1176
virtual PINDEX Append(PObject *obj)=0
Append a new object to the collection.
This class defines a thread-safe list of objects.
Definition: safecoll.h:1187
virtual void PrintOn(ostream &strm) const
Output the contents of the object to the stream.
virtual void DeleteObject(PSafeObject *obj)
unsigned IsSafelyBeingRemoved() const
Indicate the object is being safely removed.
Definition: safecoll.h:259
virtual void UnlockPtr()
Comparison
Result of the comparison operation performed by the Compare() function.
Definition: object.h:2251
void ExitSafetyMode(ExitSafetyModeOption ref)
virtual void SetAt(const Key &key, Base *obj)
Add an object to the collection.
Definition: safecoll.h:1257
A set of ordinal integers.
Definition: dict.h:762
PSafeDictionary< K, D > dict_type
Definition: safecoll.h:1394
D data_type
Definition: safecoll.h:1392
PSafeDictionaryBase()
Create a safe dictionary wrapper around the real collection.
Definition: safecoll.h:1223
const iterator_pair * operator->() const
Definition: safecoll.h:1476
virtual Comparison Compare(const PObject &obj) const
Compare the pointers.
iterator_base()
Definition: safecoll.h:1409
const_iterator find(const K &key) const
Definition: safecoll.h:1509
__inline bool LockReadOnly(const PDebugLocation &location) const
Definition: safecoll.h:196
const_iterator operator++()
Definition: safecoll.h:1496
virtual void Next()
value_type second
Definition: safecoll.h:1457
K * m_internal_first
Definition: safecoll.h:1402
iterator operator++(int)
Definition: safecoll.h:1473
void SafeRemove()
Set the removed flag.
virtual void RemoveAll(PBoolean synchronous=false)
Remove all objects in collection.
This class defines a thread-safe collection of objects.
Definition: safecoll.h:411
virtual Comparison Compare(const PObject &obj) const
Compare the pointers.
virtual PBoolean RemoveAt(PINDEX idx)
Remove an object to the collection.
Definition: safecoll.h:1135
virtual PBoolean Remove(Base *obj)
Remove an object to the collection.
Definition: safecoll.h:1121
virtual PBoolean RemoveAt(const Key &key)
Remove an object to the collection.
Definition: safecoll.h:1273
virtual PINDEX GetValuesIndex(const PObject &obj) const =0
Search the collection for the specified value of the object.
PSafeColl & operator=(const PSafeColl &other)
Assign one safe collection to another.
Definition: safecoll.h:1085
virtual void Assign(const PSafePtrBase &ptr)
PBoolean IsEmpty() const
Determine if the collection is empty.
Definition: safecoll.h:512
bool SafeAddObject(PSafeObject *obj, PSafeObject *old)
virtual void Previous()
const_iterator(const typename dict_type::iterator &it)
Definition: safecoll.h:1494
virtual void Previous()
virtual void LockPtr()
Definition: safecoll.h:705
PSafePtr(const PSafePtr &ptr)
Copy the pointer to the PSafeObject.
Definition: safecoll.h:903
virtual void SetNULL()
Set the pointer to NULL, unlocking/dereferencing existing pointer value.
iterator operator--(int)
Definition: safecoll.h:1474
virtual void Next()
This class defines a thread-safe dictionary of objects.
Definition: safecoll.h:1215
PMutex m_removalMutex
Definition: safecoll.h:530
const_iterator(const dict_type *dict, const K &key)
Definition: safecoll.h:1490
Definition: safecoll.h:701
PSafetyMode m_lockMode
Definition: safecoll.h:711
Definition: safecoll.h:1454
T * GetObjectAs() const
Return pointer to safe object.
Definition: safecoll.h:666
iterator_base(const dict_type *dict, const K &key)
Definition: safecoll.h:1424
void(PSafeObject::* UnlockFn)(const PDebugLocation *location) const
Definition: safecoll.h:318
const_iterator operator++(int)
Definition: safecoll.h:1498
virtual PBoolean SetSafetyMode(PSafetyMode mode)
Change the locking mode used by this pointer.
PSafePtr(const PSafeCollection &safeCollection, PSafetyMode mode, PSafeObject *obj)
Create a new pointer to a PSafeObject.
Definition: safecoll.h:892
virtual P_DEPRECATED PSafePtr< Base > FindWithLock(const Key &key, PSafetyMode mode=PSafeReadWrite) const
Definition: safecoll.h:1332
__inline void UnlockReadWrite() const
Release the read/write lock on an object.
Definition: safecoll.h:241
bool operator==(const iterator_base &it) const
Definition: safecoll.h:1450
void SafeRemoveObject(PSafeObject *obj)
PSafeLockBase(const PSafeObject &object, const PDebugLocation *location, LockFn lock, UnlockFn unlock)
virtual PBoolean SetSafetyMode(PSafetyMode mode)
Change the locking mode used by this pointer.
PArray< Key > GetKeys() const
Get an array containing all the keys for the dictionary.
Definition: safecoll.h:1371
PSafeObject & m_safeObject
Definition: safecoll.h:332
virtual PSafePtr< Base > GetAt(PINDEX idx, PSafetyMode mode=PSafeReadWrite)
Get the instance in the collection of the index.
Definition: safecoll.h:1294
#define PAssertNULL(ptr)
This macro is used to assert that a pointer must be non-null.
Definition: object.h:428
void CopySafeCollection(PCollection *other)
This class defines a thread-safe object in a collection.
Definition: safecoll.h:123
PINDEX GetSize() const
Get the current size of the collection.
virtual PBoolean SafeRemoveAt(PINDEX idx)
Remove an object to the collection.
bool PBoolean
Definition: object.h:174
Definition: safecoll.h:553
Definition: safecoll.h:694
const PMutex & GetMutex() const
Get the mutex for the collection.
Definition: safecoll.h:516
virtual void PrintOn(ostream &strm) const
Output the contents of the object to the stream.
const PSafeCollection * m_collection
Definition: safecoll.h:709
bool operator!=(const iterator_base &it) const
Definition: safecoll.h:1451
void erase(const iterator &it)
Definition: safecoll.h:1511
void Next()
Definition: safecoll.h:1446
void CopySafeDictionary(PAbstractDictionary *other)
__inline bool LockReadWrite(const PDebugLocation &location) const
Definition: safecoll.h:229
const iterator_pair & operator*() const
Definition: safecoll.h:1477
#define P_MAX_INDEX
Definition: object.h:80
bool operator!() const
Return true if pointer is NULL.
Definition: safecoll.h:657
PSafePtr & operator=(T *obj)
Set the new pointer to a PSafeObject.
Definition: safecoll.h:943
bool operator!() const
Definition: safecoll.h:329
PSafeCollection(PCollection *collection)
Create a thread safe collection of objects.
void AllowDeleteObjects(PBoolean yes=true)
Disallow the automatic delete any objects that have been removed.
Definition: safecoll.h:478
virtual PSafePtr< Base > FindWithLock(const Base &value, PSafetyMode mode=PSafeReadWrite)
Find the instance in the collection of an object with the same value.
Definition: safecoll.h:1158
const_iterator()
Definition: safecoll.h:1493
Definition: safecoll.h:695
__inline void UnlockReadOnly() const
Release the read only lock on an object.
Definition: safecoll.h:208
virtual PBoolean SafeRemove(PSafeObject *obj)
Remove an object to the collection.
PMutex m_mutex
Definition: safecoll.h:830
virtual void SetNULL()
Set the pointer to NULL, unlocking/dereferencing existing pointer value.
void MoveFrom(PSafeDictionaryBase &other)
Move all objects from other dictionary to this one.
Definition: safecoll.h:1354
T * operator--(int)
Post-decrement the pointer.
Definition: safecoll.h:1017
__inline bool LockReadWrite() const
Lock the object for Read/Write access.
Definition: safecoll.h:228
This class defines a thread mutual exclusion object.
Definition: mutex.h:101
virtual void Signal()
Signal that the synchronisation object is available.
void DisallowDeleteObjects()
Disallow the automatic delete any objects that have been removed.
Definition: safecoll.h:486
Definition: safecoll.h:1487
This class defines a thread-safe collection of objects.
Definition: safecoll.h:1060
virtual bool GarbageCollection()
Do any garbage collection that may be required by the object so that it may be finally deleted...
__inline bool LockReadOnly() const
Lock the object for Read Only access.
Definition: safecoll.h:195
Definition: safecoll.h:700
void erase(const const_iterator &it)
Definition: safecoll.h:1512
__inline void UnlockReadWrite(const PDebugLocation &location) const
Definition: safecoll.h:242
PSafePtr & operator=(PINDEX idx)
Set the new pointer to a collection index.
Definition: safecoll.h:958
~PSafeCollection()
Destroy the thread safe collection.
virtual void DeleteObject(PObject *object) const
Delete an objects that has been removed.
PBoolean SafelyCanBeDeleted() const
Determine if the object can be safely deleted.
unsigned GetSafeReferenceCount() const
Get count of references to this object.
Definition: safecoll.h:287
iterator operator++()
Definition: safecoll.h:1471
This class defines a thread-safe sorted array of objects.
Definition: safecoll.h:1198
PBoolean EnterSafetyMode(EnterSafetyModeOption ref)
PSafetyMode
Definition: safecoll.h:550
bool(PSafeObject::* LockFn)(const PDebugLocation *location) const
Definition: safecoll.h:317
iterator operator--()
Definition: safecoll.h:1472
friend class PInstrumentedSafeLockReadOnly
Definition: safecoll.h:309
virtual void LockPtr()
Definition: safecoll.h:826
Definition: safecoll.h:314
PArray< K > m_keys
Definition: safecoll.h:1406
T * operator++()
Pre-increment the pointer.
Definition: safecoll.h:1007
Definition: safecoll.h:1400
const_iterator(const dict_type *dict)
Definition: safecoll.h:1489
iterator(dict_type *dict)
Definition: safecoll.h:1465
PSafePtr< Derived > PSafePtrCast(const PSafePtr< Base > &oldPtr)
Cast the pointer to a different type.
Definition: safecoll.h:1041
This template class maps the PArrayObjects to a specific object type.
Definition: array.h:925
PDebugLocation m_location
Definition: safecoll.h:333
bool m_locked
Definition: safecoll.h:336
virtual void DeleteObject(PSafeObject *obj)
PSafePtr & operator=(const PSafePtr &ptr)
Copy the pointer to the PSafeObject.
Definition: safecoll.h:912
T & operator*() const
Return the physical pointer to the object.
Definition: safecoll.h:986
const_iterator end() const
Definition: safecoll.h:1508
virtual PSafePtr< Base > GetAt(PINDEX idx, PSafetyMode mode=PSafeReadWrite)
Get the instance in the collection of the index.
Definition: safecoll.h:1146
This class defines a thread synchronisation object.
Definition: syncthrd.h:256
#define P_DEPRECATED
Definition: object.h:141
PSafetyMode GetSafetyMode() const
Get the locking mode used by this pointer.
Definition: safecoll.h:670
PSafePtr< Base > value_type
Definition: safecoll.h:1201
const_iterator begin() const
Definition: safecoll.h:1507
virtual void Assign(const PSafePtrMultiThreaded &ptr)
PBoolean SafeDereference()
Decrement the reference count for object.
T * operator--()
Pre-decrement the pointer.
Definition: safecoll.h:1028
Lock a PSafeObject for read only and automatically unlock it when go out of scope.
Definition: safecoll.h:342
Definition: safecoll.h:552
virtual PSafePtr< Base > Find(const Key &key, PSafetyMode mode=PSafeReadWrite) const
Find the instance in the collection of an object with the same value.
Definition: safecoll.h:1306
#define PDECLARE_NOTIFIER(notifierType, notifiee, func)
Declare PNotifier derived class with P_INT_PTR parameter. Uses PDECLARE_NOTIFIER_EXT macro...
Definition: notifier.h:202
bool SetPosition(PINDEX position)
Definition: safecoll.h:1431
Definition: safecoll.h:1463
PINDEX m_position
Definition: safecoll.h:1407
PSafeDictionaryBase(const PSafeDictionaryBase &other)
Copy constructor for safe collection.
Definition: safecoll.h:1229
Ultimate parent class for all objects in the class library.
Definition: object.h:2204
UnlockFn m_unlock
Definition: safecoll.h:335
A collection is a container that collects together descendents of the PObject class.
Definition: contain.h:392
PSafeObject()
Create a thread safe object.
~PSafePtrMultiThreaded()
Unlock and dereference the PSafeObject this is pointing to.
PSafeLockReadWrite(const PSafeObject &object)
Definition: safecoll.h:356
virtual PSafePtr< Base > FindIterator(const Key &key, PSafetyMode mode=PSafeReadWrite) const
Find instance and use PSafePtr as an iterator.
Definition: safecoll.h:1321
virtual PINDEX GetValuesIndex(const PObject &obj) const
Search the collection for the specified value of the object.
PSafePtr< Base > value_type
Definition: safecoll.h:1190
Lock a PSafeObject for read/write and automatically unlock it when go out of scope.
Definition: safecoll.h:353
PSafeLockReadOnly(const PSafeObject &object)
Definition: safecoll.h:345
PSafeDictionaryBase & operator=(const PSafeDictionaryBase &other)
Assign one safe collection to another.
Definition: safecoll.h:1239
virtual void Wait()
Block until the synchronisation object is available.
PSafeColl()
Create a safe list collection wrapper around the real collection.
Definition: safecoll.h:1068
PSafePtr & operator=(const PSafeCollection &safeCollection)
Start an enumerated PSafeObject.
Definition: safecoll.h:922
virtual PBoolean Contains(const Key &key)
Determine of the dictionary contains an entry for the key.
Definition: safecoll.h:1282
bool m_deleteObjects
Definition: safecoll.h:528
bool IsLocked() const
Definition: safecoll.h:328
PSafePtr(T *obj=NULL, PSafetyMode mode=PSafeReference)
Create a new pointer to a PSafeObject.
Definition: safecoll.h:867
const iterator_pair & operator*() const
Definition: safecoll.h:1502
const iterator_pair * operator->() const
Definition: safecoll.h:1501