MutexVector.h 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. /*
  2. EQ2Emulator: Everquest II Server Emulator
  3. Copyright (C) 2007 EQ2EMulator Development Team (http://www.eq2emulator.net)
  4. This file is part of EQ2Emulator.
  5. EQ2Emulator is free software: you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation, either version 3 of the License, or
  8. (at your option) any later version.
  9. EQ2Emulator is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with EQ2Emulator. If not, see <http://www.gnu.org/licenses/>.
  15. */
  16. #ifndef MUTEXVECTOR_H
  17. #define MUTEXVECTOR_H
  18. #include <vector>
  19. #include "MutexHelper.h"
  20. #define MUTEXVECTOR_PENDING_ADD 1
  21. #define MUTEXVECTOR_PENDING_REMOVE 2
  22. #define MUTEXVECTOR_PENDING_DELETE 3
  23. template <typename T>
  24. class MutexVector{
  25. public:
  26. MutexVector(){
  27. has_pending_data = false;
  28. pending_clear = false;
  29. changing = false;
  30. access_count = 0;
  31. }
  32. ~MutexVector(){
  33. }
  34. class iterator {
  35. private:
  36. typename std::vector<T>::iterator itr; // Current element
  37. MutexVector<T>* vector;
  38. bool first_itr;
  39. public:
  40. iterator(){
  41. }
  42. iterator(MutexVector<T>* vector){
  43. if(vector){
  44. this->vector = vector;
  45. vector->update();
  46. ++this->vector->access_count;
  47. first_itr = true;
  48. itr = vector->current_data.begin();
  49. if(itr != vector->current_data.end())
  50. value = *itr;
  51. }
  52. else
  53. this->vector = 0;
  54. }
  55. ~iterator(){
  56. if(vector)
  57. --vector->access_count;
  58. }
  59. bool HasNext(){
  60. return itr != vector->current_data.end();
  61. }
  62. bool Next(){
  63. if(vector->pending_clear)
  64. return false;
  65. if(first_itr)
  66. first_itr = false;
  67. else
  68. itr++;
  69. if(itr != vector->current_data.end()){
  70. value = *itr;
  71. if(vector->pending_data.count(value) > 0 && vector->pending_data[value] == false) //pending delete
  72. return Next();
  73. return true;
  74. }
  75. return false;
  76. }
  77. iterator* operator->() {
  78. return this;
  79. }
  80. T value;
  81. };
  82. void update(){
  83. //if(access_count > 5)
  84. // cout << "Possible error.\n";
  85. while(changing){
  86. Sleep(1);
  87. }
  88. if(pending_clear && access_count == 0){
  89. changing = true;
  90. while(access_count > 0){
  91. Sleep(1);
  92. }
  93. ++access_count;
  94. current_data.clear();
  95. has_pending_data = (pending_data.size() > 0);
  96. pending_clear = false;
  97. --access_count;
  98. changing = false;
  99. }
  100. if(!pending_clear && has_pending_data && access_count == 0){
  101. changing = true;
  102. while(access_count > 0){
  103. Sleep(1);
  104. }
  105. ++access_count;
  106. typename std::map<T, bool>::iterator pending_itr;
  107. for(pending_itr = pending_data.begin(); pending_itr != pending_data.end(); pending_itr++){
  108. if(pending_itr->second)
  109. current_data.push_back(pending_itr->first);
  110. else{
  111. typename std::vector<T>::iterator data_itr;
  112. for(data_itr = current_data.begin(); data_itr != current_data.end(); data_itr++){
  113. if(*data_itr == pending_itr->first){
  114. current_data.erase(data_itr);
  115. break;
  116. }
  117. }
  118. }
  119. }
  120. pending_data.clear();
  121. has_pending_data = false;
  122. --access_count;
  123. changing = false;
  124. }
  125. handle_deletes.CheckDeletes();
  126. }
  127. unsigned int size(bool include_pending = false){
  128. if(include_pending)
  129. return current_data.size() + pending_data.size();
  130. return current_data.size();
  131. }
  132. iterator begin(){
  133. return iterator(this);
  134. }
  135. void clear(){
  136. pending_clear = true;
  137. update();
  138. }
  139. unsigned int count(T key){
  140. unsigned int ret = 0;
  141. while(changing){
  142. Sleep(1);
  143. }
  144. ++access_count;
  145. typename std::list<T>::iterator iter;
  146. for(iter = current_data.begin(); iter != current_data.end(); iter++){
  147. if(*iter == key)
  148. ret++;
  149. }
  150. --access_count;
  151. return ret;
  152. }
  153. void Remove(T key, bool erase = false, unsigned int erase_time = 0){
  154. while(changing){
  155. Sleep(1);
  156. }
  157. ++access_count;
  158. pending_data[key] = false;
  159. if(erase)
  160. handle_deletes.AddPendingDelete(key, erase_time);
  161. has_pending_data = true;
  162. --access_count;
  163. update();
  164. }
  165. void Add(T key){
  166. while(changing){
  167. Sleep(1);
  168. }
  169. ++access_count;
  170. pending_data[key] = true;
  171. has_pending_data = true;
  172. --access_count;
  173. update();
  174. }
  175. T Get(unsigned int index){
  176. while(changing){
  177. Sleep(1);
  178. }
  179. return current_data[index];
  180. }
  181. private:
  182. volatile int access_count;
  183. std::vector<T> current_data;
  184. std::map<T, bool> pending_data;
  185. HandleDeletes<T> handle_deletes;
  186. volatile bool changing;
  187. volatile bool has_pending_data;
  188. volatile bool pending_clear;
  189. };
  190. #endif