View on GitHub

Vistle

Distributed Data-parallel Scientific Visualization in VR

shm_obj_ref_impl.h
Go to the documentation of this file.
1#ifndef VISTLE_SHM_OBJ_REF_IMPL_H
2#define VISTLE_SHM_OBJ_REF_IMPL_H
3
4#include "object.h"
5#include "shm.h"
6#include <cassert>
7
8namespace vistle {
9
10template<class T>
11shm_obj_ref<T>::shm_obj_ref(): m_name(), m_d(nullptr)
12{
13 ref();
14}
15
16template<class T>
17shm_obj_ref<T>::shm_obj_ref(const std::string &name, shm_obj_ref<T>::ObjType *p): m_name(name), m_d(p->d())
18{
19 ref();
20}
21
22template<class T>
23shm_obj_ref<T>::shm_obj_ref(const shm_obj_ref<T> &other): m_name(other.m_name), m_d(other.m_d)
24{
25 ref();
26}
27
28template<class T>
29shm_obj_ref<T>::shm_obj_ref(const shm_name_t name): m_name(name), m_d(shm<T>::find(name))
30{
31 ref();
32}
33
34template<class T>
36{
37 unref();
38}
39
40template<class T>
41template<typename... Args>
43{
44 shm_obj_ref<T> result;
45 result.construct(args...);
46 return result;
47}
48
49template<class T>
51{
52 auto mem = vistle::shm<ObjData>::find(m_name);
53 m_d = mem;
54 ref();
55
56 return valid();
57}
58
59template<class T>
60template<typename... Args>
61void shm_obj_ref<T>::construct(const Args &...args)
62{
63 unref();
64 if (m_name.empty())
65 m_name = Shm::the().createObjectId();
66 m_d = shm<T>::construct(m_name)(args..., Shm::the().allocator());
67 ref();
68}
69
70template<class T>
72{
73 unref();
74 m_name = rhs.m_name;
75 m_d = rhs.m_d;
76 ref();
77 return *this;
78}
79
80template<class T>
82{
83 unref();
84 if (rhs) {
85 m_name = rhs->getName();
86 m_d = rhs->d();
87 } else {
88 m_name.clear();
89 m_d = nullptr;
90 }
91 ref();
92 return *this;
93}
94
95template<class T>
96const shm_obj_ref<T> &shm_obj_ref<T>::operator=(typename shm_obj_ref<T>::ObjType::ptr rhs)
97{
98 // reuse operator fo ObjType::const_ptr
99 *this = std::const_pointer_cast<const ObjType>(rhs);
100 return *this;
101}
102
103template<class T>
105{
106 return m_name.empty() || m_d;
107}
108
109template<class T>
111{
112 if (!valid())
113 return nullptr;
114 typedef typename shm_obj_ref<T>::ObjType ObjType;
115 return typename ObjType::const_ptr(
116 dynamic_cast<ObjType *>(Object::create(const_cast<typename ObjType::Data *>(&*m_d))));
117}
118
119template<class T>
121{
122 if (!valid())
123 return nullptr;
124 return &*m_d;
125}
126
127template<class T>
129{
130 return m_name;
131}
132
133template<class T>
135{
136 if (m_d) {
137 assert(m_name == m_d->name);
138 assert(m_d->refcount() >= 0);
139 m_d->ref();
140 }
141}
142
143template<class T>
144void shm_obj_ref<T>::unref()
145{
146 if (m_d) {
147 assert(m_d->refcount() > 0);
148 m_d->unref();
149 }
150 m_d = nullptr;
151}
152
153template<class T>
155{
156 return valid();
157}
158
159template<class T>
160template<class Archive>
161void shm_obj_ref<T>::save(Archive &ar) const
162{
163 ar &V_NAME(ar, "obj_name", m_name);
164 assert(valid());
165 if (m_d)
166 ar.saveObject(*this);
167}
168
169template<class T>
170template<class Archive>
171void shm_obj_ref<T>::load(Archive &ar)
172{
173 shm_name_t shmname;
174 ar &V_NAME(ar, "obj_name", shmname);
175 std::string arname = shmname;
176
177 std::string name = ar.translateObjectName(arname);
178 //std::cerr << "shm_obj_ref: loading " << arname << ", translates to " << name << std::endl;
179 m_name = name;
180
181 unref();
182 m_d = nullptr;
183
184 if (arname.empty() && m_name.empty())
185 return;
186
187 auto obj = ar.currentObject();
188 auto handler = ar.objectCompletionHandler();
189 auto ref0 = Shm::the().getObjectFromName(name);
190 auto ref1 = T::as(ref0);
191 assert(ref0 || !ref1);
192 if (ref1) {
193 *this = ref1;
194 return;
195 }
196
197 if (obj)
198 obj->unresolvedReference();
199 auto fetcher = ar.fetcher();
200 ref0 = ar.getObject(arname, [this, fetcher, arname, name, obj, handler](Object::const_ptr newobj) -> void {
201 //std::cerr << "object completion handler: " << name << std::endl;
202 assert(newobj);
203 auto ref2 = T::as(newobj);
204 assert(ref2);
205 *this = ref2;
206 m_name = newobj->getName();
207 if (fetcher)
208 fetcher->registerObjectNameTranslation(arname, m_name);
209#if 0
210 auto ref2 = T::as(Shm::the().getObjectFromName(name));
211 assert(ref2);
212 *this = ref2;
213 if (ref2) {
214 m_name = ref2->getName();
215 ar.registerObjectNameTranslation(arname, m_name);
216 }
217#endif
218 if (obj) {
219 obj->referenceResolved(handler);
220 }
221 });
222 ref1 = T::as(ref0);
223 assert(ref0 || !ref1);
224 if (ref1) {
225 m_name = ref1->getName();
226 ar.registerObjectNameTranslation(arname, m_name);
227 // object already present: don't mess with count of outstanding references
228 *this = ref1;
229 }
230}
231
232} // namespace vistle
233#endif
#define V_NAME(ar, name, obj)
Definition: archives_config.h:441
std::shared_ptr< const Object > const_ptr
Definition: object.h:68
static Object * create(Data *)
Definition: object.cpp:132
std::shared_ptr< const Object > getObjectFromName(const std::string &name, bool onlyComplete=true) const
Definition: shm.cpp:608
std::string createObjectId(const std::string &name="")
Definition: shm.cpp:435
const void_allocator & allocator() const
Definition: shm.cpp:310
static Shm & the()
Definition: shm.cpp:315
Definition: shm_obj_ref.h:15
bool find()
Definition: shm_obj_ref_impl.h:50
const ObjType::Data * getData() const
Definition: shm_obj_ref_impl.h:120
static shm_obj_ref create(const Args &...args)
const shm_obj_ref & operator=(const shm_obj_ref &rhs)
Definition: shm_obj_ref_impl.h:71
bool valid() const
Definition: shm_obj_ref_impl.h:104
ObjType::const_ptr getObject() const
Definition: shm_obj_ref_impl.h:110
~shm_obj_ref()
Definition: shm_obj_ref_impl.h:35
const shm_name_t & name() const
Definition: shm_obj_ref_impl.h:128
void construct(const Args &...args)
Definition: shm_obj_ref_impl.h:61
shm_obj_ref()
Definition: shm_obj_ref_impl.h:11
Definition: allobjects.cpp:30
Definition: shmname.h:11
Definition: shm.h:94
static T * find(const std::string &name)
Definition: shm.h:237
static managed_shm::segment_manager::template construct_proxy< T >::type construct(const std::string &name)
Definition: shm_impl.h:87