Leaked source code of windows server 2003
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.

162 lines
4.1 KiB

  1. /*++
  2. Copyright (c) Microsoft Corporation. All rights reserved.
  3. Module Name:
  4. INFSCAN
  5. blob.h
  6. Abstract:
  7. Conceptual blob of data (smart pointer variation)
  8. this allows passing of a large object around
  9. like a pointer but with cleanup if stack is unwound (eg, due to an exception)
  10. and can also be passed into the STL constructs
  11. blob<basetype> creates a container object. One container object
  12. can create the blob.
  13. ASSUMPTIONS:
  14. blob<x> val1,val2;
  15. thread1 & thread2 calling "val1.create()" is *not* thread safe
  16. thread1 & thread2 calling "val1=val2" is *not* thread safe
  17. thread1 calling "val1=val2" where val2 owned by thread 2 *is* thread safe
  18. as long as no other threads are trying to assign a value to val1.
  19. ie assignment of an instance of blob<x> is *not* thread safe, however
  20. the referenced 'pointer' of blob<x> *is* thread safe
  21. This requires interlocked ref-counting on the shared data
  22. History:
  23. Created July 2001 - JamieHun
  24. --*/
  25. #ifndef _INFSCAN_BLOB_H_
  26. #define _INFSCAN_BLOB_H_
  27. template <class _Ty> class blob {
  28. private:
  29. typedef blob<_Ty> _Myt;
  30. typedef _Ty value_type;
  31. class _Item {
  32. //
  33. // the allocated structure
  34. //
  35. public:
  36. LONG _Reference;
  37. value_type _Object;
  38. _Item() {
  39. _Reference = 1;
  40. }
  41. void _AddRef() {
  42. if(this) {
  43. //
  44. // needs to be thread-safe as two different threads
  45. // can access the same _Item
  46. // to inc/dec
  47. //
  48. InterlockedIncrement(&_Reference);
  49. }
  50. }
  51. void _Release() {
  52. if(this) {
  53. //
  54. // needs to be thread-safe as two different threads
  55. // can access the same _Item
  56. // to inc/dec
  57. //
  58. // obviously if one is dec'ing to zero, nobody else
  59. // has a reference to it
  60. //
  61. if(InterlockedDecrement(&_Reference) == 0) {
  62. delete this;
  63. }
  64. }
  65. }
  66. };
  67. //
  68. // pointer to this special structure
  69. //
  70. _Item *_pItem;
  71. public:
  72. _Myt & create(void) {
  73. _pItem->_Release();
  74. _pItem = NULL;
  75. _pItem = new _Item; // might throw
  76. return *this;
  77. }
  78. blob(bool f = false) {
  79. _pItem = NULL;
  80. if(f) {
  81. create();
  82. }
  83. }
  84. //
  85. // const implies constness of data
  86. // AddRef doesn't effect true constness of data
  87. // it's a behind the scenes thing
  88. //
  89. blob(const _Myt & other) {
  90. const_cast<_Item*>(other._pItem)->_AddRef();
  91. _pItem = other._pItem;
  92. }
  93. _Myt & operator=(const _Myt & other) {
  94. if(_pItem != other._pItem) {
  95. const_cast<_Item*>(other._pItem)->_AddRef();
  96. _pItem->_Release();
  97. _pItem = other._pItem;
  98. }
  99. return *this;
  100. }
  101. bool operator==(const _Myt & other) const {
  102. return _pItem == other._pItem;
  103. }
  104. bool operator!=(const _Myt & other) const {
  105. return _pItem == other._pItem;
  106. }
  107. operator bool() const {
  108. return _pItem ? true : false;
  109. }
  110. bool operator!() const {
  111. return _pItem ? false : true;
  112. }
  113. operator value_type*() const {
  114. if(_pItem) {
  115. return &_pItem->_Object;
  116. } else {
  117. return NULL;
  118. }
  119. }
  120. operator value_type&() const {
  121. if(_pItem) {
  122. return _pItem->_Object;
  123. } else {
  124. throw bad_pointer();
  125. }
  126. }
  127. value_type& operator*() const {
  128. if(_pItem) {
  129. return _pItem->_Object;
  130. } else {
  131. throw bad_pointer();
  132. }
  133. }
  134. value_type* operator->() const {
  135. if(_pItem) {
  136. return &_pItem->_Object;
  137. } else {
  138. return NULL;
  139. }
  140. }
  141. };
  142. #endif // !_INFSCAN_BLOB_H_