generic_shared_impl.hpp
1 /*
2  * This file is part of CasADi.
3  *
4  * CasADi -- A symbolic framework for dynamic optimization.
5  * Copyright (C) 2010-2023 Joel Andersson, Joris Gillis, Moritz Diehl,
6  * KU Leuven. All rights reserved.
7  * Copyright (C) 2011-2014 Greg Horn
8  *
9  * CasADi is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 3 of the License, or (at your option) any later version.
13  *
14  * CasADi is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with CasADi; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22  *
23  */
24 
25 
26 #ifndef CASADI_GENERIC_SHARED_IMPL_HPP
27 #define CASADI_GENERIC_SHARED_IMPL_HPP
28 
29 namespace casadi {
30 
31  template<typename Shared, typename Internal>
32  void GenericShared<Shared, Internal>::count_up() {
33 #ifdef WITH_EXTRA_CHECKS
34  casadi_assert_dev(Function::call_depth_==0);
35 #endif // WITH_EXTRA_CHECKS
36 
37  if (node) static_cast<Internal*>(node)->count++;
38 
39  }
40 
41  template<typename Shared, typename Internal>
42  void GenericShared<Shared, Internal>::count_down() {
43 #ifdef WITH_EXTRA_CHECKS
44  casadi_assert_dev(Function::call_depth_==0);
45 #endif // WITH_EXTRA_CHECKS
46  if (!node) return;
47  if (node->weak_ref_) {
48 #ifdef CASADI_WITH_THREADSAFE_SYMBOLICS
49  auto mutex = node->weak_ref_->get_mutex();
50  // Avoid triggering a delete while a weak_ref.shared_if_alive is being called
51  std::lock_guard<std::mutex> lock(*mutex);
52  // Could it be that this mutex is destroyed when the lock goes out of scope?
53 #endif // CASADI_WITH_THREADSAFE_SYMBOLICS
54 
55  if (--static_cast<Internal*>(node)->count == 0) {
56  delete node;
57  node = nullptr;
58  }
59  } else {
60  if (--static_cast<Internal*>(node)->count == 0) {
61  delete node;
62  node = nullptr;
63  }
64  }
65  }
66 
67  template<typename Shared, typename Internal>
68  void GenericShared<Shared, Internal>::own(Internal* node_) {
69  count_down();
70  node = node_;
71  count_up();
72  }
73 
74  template<typename Shared, typename Internal>
75  void GenericShared<Shared, Internal>::assign(Internal* node_) {
76  node = node_;
77  }
78 
79  template<typename Shared, typename Internal>
81  if (node) {
82  return node->debug_repr(node);
83  } else {
84  return "NULL";
85  }
86  }
87 
88  template<typename Shared, typename Internal>
91  // quick return if the old and new pointers point to the same object
92  if (node == ref.node) return *this;
93 
94  // decrease the counter and delete if this was the last pointer
95  count_down();
96 
97  // save the new pointer
98  node = ref.node;
99  count_up();
100  return *this;
101  }
102 
103  template<typename Shared, typename Internal>
104  Internal* GenericShared<Shared, Internal>::get() const {
105  return node;
106  }
107 
108  template<typename Shared, typename Internal>
110  return node==nullptr;
111  }
112 
113  template<typename Shared, typename Internal>
115  casadi_assert_dev(!is_null());
116  return node;
117  }
118 
119  template<typename Shared, typename Internal>
121  GenericShared<Shared, Internal> temp = *this;
122  *this = other;
123  other = temp;
124  }
125 
126  template<typename Shared, typename Internal>
127  casadi_int GenericShared<Shared, Internal>::getCount() const {
128  return (*this)->getCount();
129  }
130 
131  template<typename Shared, typename Internal>
132  GenericWeakRef<Shared, Internal>* GenericShared<Shared, Internal>::weak() {
133  return (*this)->weak();
134  }
135 
136  template<typename Shared, typename Internal>
138  return reinterpret_cast<casadi_int>(get());
139  }
140 
141  template<typename Shared, typename Internal>
143  casadi_assert_dev(dummy==0);
144  }
145 
146  template<typename Shared, typename Internal>
148  return !is_null() && (*this)->raw_ != nullptr;
149  }
150 
151  template<typename Shared, typename Internal>
153  Shared ret;
154  if (alive()) {
155  ret.own((*this)->raw_);
156  }
157  return ret;
158  }
159 
160  template<typename Shared, typename Internal>
162  if (is_null()) return false;
163 #ifdef CASADI_WITH_THREADSAFE_SYMBOLICS
164  // Safe access to ...
165  std::lock_guard<std::mutex> lock(*(*this)->mutex_);
166 #endif // CASADI_WITH_THREADSAFE_SYMBOLICS
167  if (alive()) {
168  shared.own((*this)->raw_);
169  return true;
170  }
171  return false;
172  }
173 
174  template<typename Shared, typename Internal>
175  const GenericWeakRefInternal<Shared, Internal>*
177  return static_cast<const GenericWeakRefInternal<Shared, Internal>*>(
179  }
180 
181  template<typename Shared, typename Internal>
182  GenericWeakRefInternal<Shared, Internal>*
184  return static_cast<GenericWeakRefInternal<Shared, Internal>*>(
186  }
187 
188  template<typename Shared, typename Internal>
190  this->own(shared.weak()->get());
191  }
192 
193  template<typename Shared, typename Internal>
195  this->own(new typename Internal::weak_ref_type(raw));
196  }
197 
198  template<typename Shared, typename Internal>
199  void GenericWeakRef<Shared, Internal>::kill() {
200  casadi_assert_dev((*this)->raw_);
201  (*this)->raw_ = nullptr;
202  }
203 
204 #ifdef CASADI_WITH_THREADSAFE_SYMBOLICS
205  template<typename Shared, typename Internal>
206  std::shared_ptr<std::mutex> GenericWeakRef<Shared, Internal>::get_mutex() const {
207  return (*this)->mutex_;
208  }
209 #endif // CASADI_WITH_THREADSAFE_SYMBOLICS
210 
211 } // namespace casadi
212 
213 
214 #endif // CASADI_GENERIC_SHARED_IMPL_HPP
casadi_int __hash__() const
Returns a number that is unique for a given Node.
std::string debug_repr() const
bool is_null() const
Is a null pointer?
bool alive() const
Check if alive.
Shared shared() const
Get a shared (owning) reference.
GenericWeakRefInternal< Shared, Internal > * operator->()
Access functions of the node.
bool shared_if_alive(Shared &shared) const
Thread-safe alternative to alive()/shared()
GenericWeakRef(int dummy=0)
Default constructor.
The casadi namespace.
Definition: archiver.hpp:32