UCommon
shared.h
Go to the documentation of this file.
1 // Copyright (C) 2015 Cherokees of Idaho.
2 //
3 // This file is part of GNU uCommon C++.
4 //
5 // GNU uCommon C++ is free software: you can redistribute it and/or modify
6 // it under the terms of the GNU Lesser General Public License as published
7 // by the Free Software Foundation, either version 3 of the License, or
8 // (at your option) any later version.
9 //
10 // GNU uCommon C++ is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU Lesser General Public License for more details.
14 //
15 // You should have received a copy of the GNU Lesser General Public License
16 // along with GNU uCommon C++. If not, see <http://www.gnu.org/licenses/>.
17 
24 #ifndef _UCOMMON_SHARED_H_
25 #define _UCOMMON_SHARED_H_
26 
27 #ifndef _UCOMMON_CPR_H_
28 #include <ucommon/cpr.h>
29 #endif
30 
31 #ifndef _UCOMMON_ATOMIC_H_
32 #include <ucommon/atomic.h>
33 #endif
34 
35 #ifndef _UCOMMON_PROTOCOLS_H_
36 #include <ucommon/protocols.h>
37 #endif
38 
39 #ifndef _UCOMMON_OBJECT_H_
40 #include <ucommon/object.h>
41 #endif
42 
43 #ifndef _UCOMMON_TYPEREF_H_
44 #include <ucommon/typeref.h>
45 #endif
46 
47 #ifndef _UCOMMON_THREAD_H_
48 #include <ucommon/thread.h>
49 #endif
50 
51 #ifndef _UCOMMON_SOCKET_H_
52 #include <ucommon/socket.h>
53 #endif
54 
55 namespace ucommon {
56 
57 class __EXPORT SharedRef : protected TypeRef
58 {
59 private:
60  __DELETE_COPY(SharedRef);
61 
62 protected:
63  Mutex lock;
64 
65  SharedRef();
66 
67  TypeRef get();
68 
69  void get(TypeRef& object);
70 
71  void put(TypeRef& object);
72 };
73 
74 template<typename T>
75 class sharedref : private SharedRef
76 {
77 private:
78  __DELETE_COPY(sharedref);
79 
80 public:
81  inline sharedref() : SharedRef() {};
82 
83  inline operator typeref<T>() {
84  lock.acquire();
85  typeref<T> ptr(ref);
86  lock.release();
87  return ptr;
88  }
89 
90  inline typeref<T> operator*() {
91  lock.acquire();
92  typeref<T> ptr(ref);
93  lock.release();
94  return ptr;
95  }
96 
97  inline void put(typeref<T>& ptr) {
98  SharedRef::put(ptr);
99  }
100 
101  inline sharedref& operator=(typeref<T> ptr) {
102  SharedRef::get(ptr);
103  return *this;
104  }
105 
106  inline sharedref& operator=(T obj) {
107  typeref<T> ptr(obj);
108  SharedRef::get(ptr);
109  return *this;
110  }
111 };
112 
113 class __EXPORT MappedPointer
114 {
115 private:
116  __DELETE_COPY(MappedPointer);
117 
118 protected:
119  class __EXPORT Index : public LinkedObject
120  {
121  public:
122  explicit Index(LinkedObject **origin);
123 
124  const void *key;
125  void *value;
126  };
127 
128  condlock_t *lock;
129 
130  LinkedObject *free, **list;
131 
132  memalloc pager;
133 
134  size_t paths;
135 
136  MappedPointer(size_t indexes, condlock_t *locking = NULL, size_t paging = 0);
137  ~MappedPointer();
138 
139  LinkedObject *access(size_t path);
140 
141  LinkedObject *modify(size_t path);
142 
143  void release(void *obj);
144 
145  void insert(const void *key, void *value, size_t path);
146 
147  void replace(Index *ind, void *value);
148 
149  void remove(Index *ind, size_t path);
150 
151 public:
152  static size_t keypath(const uint8_t *addr, size_t size);
153 };
154 
155 template<typename T>
156 inline size_t mapped_keypath(const T *addr)
157 {
158  if(!addr)
159  return 0;
160 
161  return MappedPointer::keypath((const uint8_t *)addr, sizeof(T));
162 }
163 
164 template<typename T>
165 inline bool mapped_keyequal(const T* key1, const T* key2)
166 {
167  if(!key1 || !key2)
168  return false;
169  return !memcmp(key1, key2, sizeof(T));
170 }
171 
172 template<>
173 inline size_t mapped_keypath<char>(const char *addr)
174 {
175  if(!addr)
176  return 0;
177 
178  return MappedPointer::keypath((const uint8_t *)addr, strlen(addr));
179 }
180 
181 template<>
182 inline bool mapped_keyequal<char>(const char *k1, const char *k2)
183 {
184  if(!k1 || !k2)
185  return false;
186 
187  return eq(k1, k2);
188 }
189 
190 template<>
191 inline size_t mapped_keypath<struct sockaddr>(const struct sockaddr *addr)
192 {
193  if(!addr)
194  return 0;
195 
196  return MappedPointer::keypath((const uint8_t *)addr, Socket::len(addr));
197 }
198 
199 template<>
200 inline bool mapped_keyequal<struct sockaddr>(const struct sockaddr *s1, const struct sockaddr *s2)
201 {
202  if(!s1 || !s2)
203  return false;
204  return Socket::equal(s1, s2);
205 }
206 
207 template<typename K, typename V>
208 class mapped_pointer : public MappedPointer
209 {
210 public:
211  inline mapped_pointer(size_t indexes = 37, condlock_t *locking = NULL, size_t paging = 0) : MappedPointer(indexes, locking, paging) {}
212 
213  inline void release(V* object) {
214  MappedPointer::release(object);
215  }
216 
217  void remove(const K* key) {
218  size_t path = mapped_keypath<K>(key);
219  linked_pointer<Index> ip = modify(path);
220  while(is(ip)) {
221  if(mapped_keyequal<K>((const K*)(ip->key), key)) {
222  MappedPointer::remove(*ip, path);
223  return;
224  }
225  ip.next();
226  }
227  lock->commit();
228  }
229 
230  V* get(const K* key) {
231  linked_pointer<Index> ip = access(mapped_keypath<K>(key));
232  while(is(ip)) {
233  if(mapped_keyequal<K>((const K*)(ip->key), key)) {
234  return static_cast<V*>(ip->value);
235  }
236  ip.next();
237  }
238  lock->release();
239  return nullptr;
240  }
241 
242  void set(const K* key, V* ptr) {
243  size_t path = mapped_keypath<K>(key);
244  linked_pointer<Index> ip = modify(path);
245  while(is(ip)) {
246  if(mapped_keyequal<K>((const K*)(ip->key), key)) {
247  replace(*ip, ptr);
248  return;
249  }
250  }
251  insert((const void *)key, (void *)ptr, path);
252  }
253 };
254 
255 } // namespace
256 
257 #endif
static void put(TypeRef &target, Counted *object)
Special weak-public means to copy a container reference.
Definition: typeref.h:259
bool eq(const struct sockaddr *s1, const struct sockaddr *s2)
Compare two socket addresses to see if equal.
Definition: socket.h:2100
A common object base class with auto-pointer support.
bool is(T &object)
Convenience function to validate object assuming it is castable to bool.
Definition: generics.h:292
const struct sockaddr * addr(Socket::address &address)
A convenience function to convert a socket address list into a socket address.
Definition: socket.h:2089
Atomic pointers and locks.
Thread classes and sychronization objects.
ConditionalLock condlock_t
Convenience type for using conditional locks.
Definition: condition.h:725
Common namespace for all ucommon objects.
Definition: access.h:47
Common socket class and address manipulation.
Abstract interfaces and support.
Runtime functions.
static bool equal(const struct sockaddr *address1, const struct sockaddr *address2)
Compare socket addresses.
A thread-safe atomic heap management system.
static socklen_t len(const struct sockaddr *address)
Get the size of a socket address.