OCILIB (C and C++ Driver for Oracle)  4.7.6
Open source and cross platform Oracle Driver delivering efficient access to Oracle databases.
SmartHandle.hpp
1 /*
2  * OCILIB - C Driver for Oracle (C Wrapper for Oracle OCI)
3  *
4  * Website: http://www.ocilib.net
5  *
6  * Copyright (c) 2007-2023 Vincent ROGIER <vince.rogier@ocilib.net>
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  */
20 
21 #pragma once
22 
23 #include "ocilibcpp/core.hpp"
24 #include "ocilibcpp/detail/support/HandleStoreResolver.hpp"
25 #include "ocilibcpp/detail/support/HandleDeleter.hpp"
26 
27 namespace ocilib
28 {
29  namespace core
30  {
31 
32  template<class T>
33  HandleHolder<T>::SmartHandle::SmartHandle
34  (
35  HandleHolder* holder, T handle, bool allocated,
36  SmartHandleFreeNotifyFunc freeNotifyFunc, Handle* parent
37  )
38  : _holders(), _handle(handle), _allocated(allocated),
39  _freeNotifyFunc(freeNotifyFunc), _parent(parent), _extraInfo(nullptr), _store{nullptr},
40  _guard(GetSynchronizationMode())
41  {
42  _holders.SetGuard(&_guard);
43  _children.SetGuard(&_guard);
44 
45  if (support::HandleStoreResolver<T>::RequireStore)
46  {
47  _store = core::OnAllocate(new core::HandleStore(&_guard));
48  }
49 
50  HandleStore::GetStoreForHandle(parent).Set<SmartHandle*>(handle, this);
51 
52  Acquire(holder);
53 
54  if (_parent && _handle)
55  {
56  _parent->GetChildren().Add(this);
57  }
58  }
59 
60  template<class T>
61  HandleHolder<T>::SmartHandle::~SmartHandle() noexcept
62  {
63  SILENT_CATCH((Destroy()))
64  }
65 
66  template<class T>
67  void HandleHolder<T>::SmartHandle::Destroy()
68  {
69  if (_parent && _handle)
70  {
71  _parent->GetChildren().Remove(this);
72  }
73 
74  _children.ForEach(DeleteHandle);
75  _children.Clear();
76 
77  _holders.SetGuard(nullptr);
78  _children.SetGuard(nullptr);
79 
80  HandleStore::GetStoreForHandle(_parent).Set<SmartHandle*>(_handle, nullptr);
81 
82  if (_freeNotifyFunc)
83  {
84  _freeNotifyFunc(this);
85  }
86 
87  if (_handle && _allocated)
88  {
89  support::HandleDeleter<T> deleter;
90  deleter(_handle);
91  }
92 
93  if (_store)
94  {
95  delete core::OnDeallocate(_store);
96  }
97  }
98 
99  template<class T>
100  void HandleHolder<T>::SmartHandle::DeleteHandle(Handle* handle)
101  {
102  if (handle)
103  {
104  handle->DetachFromParent();
105  handle->DetachFromHolders();
106 
107  delete core::OnDeallocate(handle);
108  }
109  }
110 
111  template<class T>
112  void HandleHolder<T>::SmartHandle::ResetHolder(HandleHolder* holder)
113  {
114  if (holder)
115  {
116  holder->_smartHandle = nullptr;
117  }
118  }
119 
120  template<class T>
121  SynchronizationMode HandleHolder<T>::SmartHandle::GetSynchronizationMode()
122  {
123  if ((Environment::GetMode() & Environment::Threaded) == Environment::Threaded)
124  {
125  return support::HandleStoreResolver<T>::SynchMode;
126  }
127 
128  return SynchronizationMode::Unsafe;
129  }
130 
131  template<class T>
132  void HandleHolder<T>::SmartHandle::Acquire(HandleHolder* holder)
133  {
134  _holders.Add(holder);
135  }
136 
137  template<class T>
138  void HandleHolder<T>::SmartHandle::Release(HandleHolder* holder)
139  {
140  _holders.Remove(holder);
141 
142  if (_holders.GetSize() == 0)
143  {
144  delete core::OnDeallocate(this);
145  }
146 
147  holder->_smartHandle = nullptr;
148  }
149 
150  template<class T>
151  T HandleHolder<T>::SmartHandle::GetHandle() const
152  {
153  return _handle;
154  }
155 
156  template<class T>
157  Handle* HandleHolder<T>::SmartHandle::GetParent() const
158  {
159  return _parent;
160  }
161 
162  template<class T>
163  AnyPointer HandleHolder<T>::SmartHandle::GetExtraInfos() const
164  {
165  return _extraInfo;
166  }
167 
168  template<class T>
169  void HandleHolder<T>::SmartHandle::SetExtraInfos(AnyPointer extraInfo)
170  {
171  _extraInfo = extraInfo;
172  }
173 
174  template<class T>
175  ConcurrentList<Handle*>& HandleHolder<T>::SmartHandle::GetChildren()
176  {
177  return _children;
178  }
179 
180  template<class T>
181  void HandleHolder<T>::SmartHandle::DetachFromHolders()
182  {
183  _holders.ForEach(ResetHolder);
184  _holders.Clear();
185  }
186 
187  template<class T>
188  void HandleHolder<T>::SmartHandle::DetachFromParent()
189  {
190  _parent = nullptr;
191  }
192 
193  template<class T>
194  HandleStore* HandleHolder<T>::SmartHandle::GetStore()
195  {
196  return _store;
197  }
198  }
199 }
SynchronizationMode
Internal usage. Synchronization mode enumeration.
Definition: core.hpp:217
OCILIB ++ Namespace.
void * AnyPointer
Alias for the generic void pointer.
Definition: config.hpp:129