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
55namespace ucommon {
56
57class __EXPORT SharedRef : protected TypeRef
58{
59private:
60 __DELETE_COPY(SharedRef);
61
62protected:
63 Mutex lock;
64
65 SharedRef();
66
67 TypeRef get();
68
69 void get(TypeRef& object);
70
71 void put(TypeRef& object);
72};
73
74template<typename T>
75class sharedref : private SharedRef
76{
77private:
78 __DELETE_COPY(sharedref);
79
80public:
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
113class __EXPORT MappedPointer
114{
115private:
116 __DELETE_COPY(MappedPointer);
117
118protected:
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
151public:
152 static size_t keypath(const uint8_t *addr, size_t size);
153};
154
155template<typename T>
156inline 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
164template<typename T>
165inline 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
172template<>
173inline 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
181template<>
182inline 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
190template<>
191inline 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
199template<>
200inline 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
207template<typename K, typename V>
208class mapped_pointer : public MappedPointer
209{
210public:
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
Runtime functions.
A thread-safe atomic heap management system.
Atomic pointers and locks.
Abstract interfaces and support.
Common namespace for all ucommon objects.
Definition access.h:47
bool eq(const struct sockaddr *s1, const struct sockaddr *s2)
Compare two socket addresses to see if equal.
Definition socket.h:2100
const struct sockaddr * addr(Socket::address &address)
A convenience function to convert a socket address list into a socket address.
Definition socket.h:2089
ConditionalLock condlock_t
Convenience type for using conditional locks.
Definition condition.h:725
bool is(T &object)
Convenience function to validate object assuming it is castable to bool.
Definition generics.h:292
void commit(void)
Commit changes / release a modify lock.
void release(void)
Release a shared lock.
static socklen_t len(const struct sockaddr *address)
Get the size of a socket address.
static bool equal(const struct sockaddr *address1, const struct sockaddr *address2)
Compare socket addresses.
A common object base class with auto-pointer support.
Common socket class and address manipulation.
Thread classes and sychronization objects.