00001 #ifndef SAFE_LIST_IMPLEMENTATION_FILE
00002 #define SAFE_LIST_IMPLEMENTATION_FILE
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "list.h"
00019 #include "node.h"
00020 #include "safe_list.h"
00021 #include "safe_node.h"
00022
00023 #include <basis/function.h>
00024 #include <basis/mutex.h>
00025 #include <mechanisms/rw_lock.h>
00026
00027 namespace nodes {
00028
00029
00030 const safe_list::iterator_positions safe_list::HEAD = common::HEAD;
00031 const safe_list::iterator_positions safe_list::TAIL = common::TAIL;
00032
00033
00034
00035
00036 class real_safe_node : public node
00037 {
00038 public:
00039 safe_node *_snode;
00040
00041 real_safe_node(safe_node *to_hold) : _snode(to_hold) {}
00042 ~real_safe_node() { WHACK(_snode); }
00043 };
00044
00046
00047
00048
00049 #define CAST_BACK \
00050 list::iterator &iter = *(list::iterator *)_hidden_iterator
00051
00052
00053
00054 #define UPCAST_NODE \
00055 real_safe_node *rsn = dynamic_cast<real_safe_node *>(iter.access())
00056
00058
00059 safe_list_read_iterator::safe_list_read_iterator(const safe_list &mgr,
00060 safe_list::iterator_positions where)
00061 : _manager(mgr), _hidden_iterator(NIL)
00062 {
00063 _hidden_iterator = new list::iterator(_manager._storage, NIL);
00064 CAST_BACK;
00065 if (where == safe_list::HEAD)
00066 iter = _manager._storage->head();
00067 else
00068 iter = _manager._storage->tail();
00069 }
00070
00071 safe_list_read_iterator::~safe_list_read_iterator()
00072 {
00073 CAST_BACK;
00074 delete &iter;
00075 _hidden_iterator = NIL;
00076 }
00077
00078 void safe_list_read_iterator::jump_head()
00079 {
00080 CAST_BACK;
00081 iter.jump_head();
00082 }
00083
00084 void safe_list_read_iterator::jump_tail()
00085 {
00086 CAST_BACK;
00087 iter.jump_tail();
00088 }
00089
00090 void safe_list_read_iterator::next()
00091 {
00092 CAST_BACK;
00093 iter++;
00094 }
00095
00096 void safe_list_read_iterator::previous()
00097 {
00098 CAST_BACK;
00099 iter--;
00100 }
00101
00102 const safe_node *safe_list_read_iterator::observe() const
00103 {
00104 CAST_BACK;
00105 UPCAST_NODE;
00106 return rsn? rsn->_snode : NIL;
00107 }
00108
00109 bool safe_list_read_iterator::is_head()
00110 {
00111 CAST_BACK;
00112 return iter.is_head();
00113 }
00114
00115 bool safe_list_read_iterator::is_tail()
00116 {
00117 CAST_BACK;
00118 return iter.is_tail();
00119 }
00120
00122
00123 safe_list_write_iterator::safe_list_write_iterator(const safe_list &mgr,
00124 safe_list::iterator_positions where)
00125 : _manager(mgr), _hidden_iterator(NIL)
00126 {
00127 _hidden_iterator = new list::iterator(_manager._storage, NIL);
00128 CAST_BACK;
00129 if (where == safe_list::HEAD)
00130 iter = _manager._storage->head();
00131 else
00132 iter = _manager._storage->tail();
00133 }
00134
00135 safe_list_write_iterator::~safe_list_write_iterator()
00136 {
00137 CAST_BACK;
00138 delete &iter;
00139 _hidden_iterator = NIL;
00140 }
00141
00142 void safe_list_write_iterator::jump_head()
00143 {
00144 CAST_BACK;
00145 iter.jump_head();
00146 }
00147
00148 void safe_list_write_iterator::jump_tail()
00149 {
00150 CAST_BACK;
00151 iter.jump_tail();
00152 }
00153
00154 void safe_list_write_iterator::next()
00155 {
00156 CAST_BACK;
00157 iter++;
00158 }
00159
00160 void safe_list_write_iterator::previous()
00161 {
00162 CAST_BACK;
00163 iter--;
00164 }
00165
00166 safe_node *safe_list_write_iterator::access()
00167 {
00168 CAST_BACK;
00169 UPCAST_NODE;
00170 return rsn? rsn->_snode : NIL;
00171 }
00172
00173 bool safe_list_write_iterator::is_head()
00174 {
00175 CAST_BACK;
00176 return iter.is_head();
00177 }
00178
00179 bool safe_list_write_iterator::is_tail()
00180 {
00181 CAST_BACK;
00182 return iter.is_tail();
00183 }
00184
00186
00187 safe_list::safe_list()
00188 : _storage(new list),
00189 _gate_keeper(new reader_writer_lock)
00190 {}
00191
00192 safe_list::~safe_list()
00193 {
00194 WHACK(_storage);
00195 WHACK(_gate_keeper);
00196 }
00197
00198 bool safe_list::empty(safe_list_read_iterator &formal(it))
00199 { return _storage->empty(); }
00200
00201 bool safe_list::empty(safe_list_write_iterator &formal(it))
00202 { return _storage->empty(); }
00203
00204 int safe_list::elements(safe_list_read_iterator &formal(it))
00205 { return _storage->elements(); }
00206
00207 int safe_list::elements(safe_list_write_iterator &formal(it))
00208 { return _storage->elements(); }
00209
00210 safe_list_read_iterator *safe_list::open_reader(iterator_positions where)
00211 {
00212 _gate_keeper->begin_read();
00213 return new safe_list_read_iterator(*this, where);
00214 }
00215
00216 safe_list_write_iterator *safe_list::open_writer(iterator_positions where)
00217 {
00218 _gate_keeper->begin_write();
00219 return new safe_list_write_iterator(*this, where);
00220 }
00221
00222 void safe_list::close_reader(safe_list_read_iterator * &to_close)
00223 {
00224 WHACK(to_close);
00225 _gate_keeper->end_read();
00226 }
00227
00228 void safe_list::close_writer(safe_list_write_iterator * &to_close)
00229 {
00230 WHACK(to_close);
00231 _gate_keeper->end_write();
00232 }
00233
00234 #define CAST_WRITER \
00235 list::iterator &iter = *(list::iterator *)writer._hidden_iterator
00236
00237 safe_node *safe_list::remove(safe_list_write_iterator &writer)
00238 {
00239 CAST_WRITER;
00240 real_safe_node *ogre = dynamic_cast<real_safe_node *>(_storage->remove(iter));
00241 if (!ogre) return NIL;
00242 safe_node *to_return = ogre->_snode;
00243 ogre->_snode = NIL;
00244 delete ogre;
00245 return to_return;
00246 }
00247
00248 void safe_list::zap(safe_list_write_iterator &writer)
00249 {
00250 CAST_WRITER;
00251 _storage->zap(iter);
00252 }
00253
00254 void safe_list::insert(safe_list_write_iterator &writer, safe_node *to_insert)
00255 {
00256 CAST_WRITER;
00257 real_safe_node *to_add = new real_safe_node(to_insert);
00258 _storage->insert(iter, to_add);
00259 }
00260
00261 }
00262
00263 #endif //SAFE_LIST_IMPLEMENTATION_FILE
00264