Commit 9591e2c3 authored by Christian Schulte zu Berge's avatar Christian Schulte zu Berge
Browse files

Merge branch 'refactor-reference-counting' into 'development'

Refactor reference counting
parents 504af5c9 5180655f
......@@ -26,12 +26,12 @@
namespace campvis {
AbstractData::AbstractData()
: ReferenceCounted()
{
AbstractData::AbstractData() {
}
AbstractData::~AbstractData() {
}
}
\ No newline at end of file
}
......@@ -2,28 +2,23 @@
//
// This file is part of the CAMPVis Software Framework.
//
// If not explicitly stated otherwise: Copyright (C) 2012, all rights reserved,
// If not explicitly stated otherwise: Copyright (C) 2012-2014, all rights reserved,
// Christian Schulte zu Berge <christian.szb@in.tum.de>
// Chair for Computer Aided Medical Procedures
// Technische Universität München
// Boltzmannstr. 3, 85748 Garching b. München, Germany
// Technische Universitaet Muenchen
// Boltzmannstr. 3, 85748 Garching b. Muenchen, Germany
//
// For a full list of authors and contributors, please refer to the file "AUTHORS.txt".
//
// The licensing of this softare is not yet resolved. Until then, redistribution in source or
// binary forms outside the CAMP chair is not permitted, unless explicitly stated in legal form.
// However, the names of the original authors and the above copyright notice must retain in its
// original state in any case.
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
// except in compliance with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Legal disclaimer provided by the BSD license:
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
// Unless required by applicable law or agreed to in writing, software distributed under the
// License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// either express or implied. See the License for the specific language governing permissions
// and limitations under the License.
//
// ================================================================================================
......@@ -34,7 +29,6 @@
#include "core/coreapi.h"
#include "core/datastructures/scopedtypeddata.h" // not directly needed here but by many classes including AbstractData
#include "core/tools/referencecounted.h"
namespace campvis {
......@@ -62,7 +56,7 @@ namespace campvis {
*
* \todo
*/
class CAMPVIS_CORE_API AbstractData : public ReferenceCounted {
class CAMPVIS_CORE_API AbstractData {
public:
/**
* Constructor, simply calles ReferenceCounted ctor.
......@@ -99,4 +93,4 @@ namespace campvis {
}
#endif // ABSTRACTDATA_H__
\ No newline at end of file
#endif // ABSTRACTDATA_H__
......@@ -29,52 +29,34 @@
namespace campvis {
DataHandle::DataHandle(AbstractData* data)
: _data(data)
: _ptr(data)
, _timestamp(clock())
{
init();
}
DataHandle::DataHandle(const DataHandle& rhs)
: _data(rhs._data)
: _ptr(rhs._ptr)
, _timestamp(rhs._timestamp)
{
init();
}
DataHandle& DataHandle::operator=(const DataHandle& rhs) {
if (_data != rhs._data) {
AbstractData* oldData = _data;
_data = rhs._data;
if (_ptr != rhs._ptr) {
_ptr = rhs._ptr;
_timestamp = rhs._timestamp;
init();
if (oldData) {
oldData->removeReference();
}
}
return *this;
}
DataHandle::~DataHandle() {
if (_data)
_data->removeReference();
}
const AbstractData* DataHandle::getData() const {
return _data;
}
void DataHandle::init() {
if (_data == 0)
return;
if (! _data->isShareable()) {
_data = _data->clone();
_timestamp = clock();
}
_data->addReference();
return _ptr.get();
}
clock_t DataHandle::getTimestamp() const {
......
......@@ -26,6 +26,7 @@
#define datahandle_h__
#include <ctime>
#include <memory>
#include "core/coreapi.h"
......@@ -91,12 +92,7 @@ namespace campvis {
private:
/**
* Initializes the reference counting for the data.
*/
void init();
AbstractData* _data; ///< managed data
std::shared_ptr<AbstractData> _ptr; ///< managed data
clock_t _timestamp; ///< Timestamp when this data has been created
};
......
// ================================================================================================
//
// This file is part of the CAMPVis Software Framework.
//
// If not explicitly stated otherwise: Copyright (C) 2012-2014, all rights reserved,
// Christian Schulte zu Berge <christian.szb@in.tum.de>
// Chair for Computer Aided Medical Procedures
// Technische Universitaet Muenchen
// Boltzmannstr. 3, 85748 Garching b. Muenchen, Germany
//
// For a full list of authors and contributors, please refer to the file "AUTHORS.txt".
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
// except in compliance with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software distributed under the
// License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// either express or implied. See the License for the specific language governing permissions
// and limitations under the License.
//
// ================================================================================================
#include "referencecounted.h"
#include "core/tools/job.h"
#include "core/tools/simplejobprocessor.h"
namespace campvis {
ReferenceCounted::ReferenceCounted()
: _shareable(true)
{
_refCount = 0;
}
ReferenceCounted::ReferenceCounted(const ReferenceCounted& rhs)
: _shareable(true)
{
_refCount = 0;
}
ReferenceCounted& ReferenceCounted::operator=(const ReferenceCounted& rhs) {
return *this;
}
ReferenceCounted::~ReferenceCounted() {
}
void ReferenceCounted::addReference() {
++_refCount;
}
void ReferenceCounted::removeReference() {
if (--_refCount == 0)
SimpleJobProc.enqueueJob(makeJob(&ReferenceCounted::deleteInstance, this));
}
void ReferenceCounted::markUnsharable() {
_shareable = false;
}
bool ReferenceCounted::isShareable() const {
return _shareable;
}
bool ReferenceCounted::isShared() const {
return _refCount > 1;
}
void ReferenceCounted::deleteInstance(ReferenceCounted* instance) {
delete instance;
}
}
// ================================================================================================
//
// This file is part of the CAMPVis Software Framework.
//
// If not explicitly stated otherwise: Copyright (C) 2012-2014, all rights reserved,
// Christian Schulte zu Berge <christian.szb@in.tum.de>
// Chair for Computer Aided Medical Procedures
// Technische Universitaet Muenchen
// Boltzmannstr. 3, 85748 Garching b. Muenchen, Germany
//
// For a full list of authors and contributors, please refer to the file "AUTHORS.txt".
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
// except in compliance with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software distributed under the
// License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// either express or implied. See the License for the specific language governing permissions
// and limitations under the License.
//
// ================================================================================================
#ifndef REFERENCECOUNTED_H__
#define REFERENCECOUNTED_H__
#include <tbb/atomic.h>
#include "core/coreapi.h"
namespace campvis {
/**
* Base class for reference counted objects.
*
* \note Implementation inspired from Scott Meyers: More Effective C++, Item 29
* \todo Check thread-safety
*/
class CAMPVIS_CORE_API ReferenceCounted {
public:
/**
* Create a new reference counted object.
*/
ReferenceCounted();
/**
* Copy-constructor for reference counted objects.
* \param rhs source object
*/
ReferenceCounted(const ReferenceCounted& rhs);
/**
* Assignment operator for reference counted objects
* \param rhs source object
* \return *this
*/
ReferenceCounted& operator= (const ReferenceCounted& rhs);
/**
* Pure virtual destructor.
*/
virtual ~ReferenceCounted() = 0;
/**
* Increment the reference count.
*/
void addReference();
/**
* Decrement the reference count and delete the object if necessary.
*/
void removeReference();
/**
* Mark this object as not shareable, i.e. there exist non-const pointers to this object.
*/
void markUnsharable();
/**
* Returns, whether this object is shareable, i.e. no non-const pointers to this object exist.
* \return _shareable
*/
bool isShareable() const;
/**
* Returns, whether this object has more than one references.
* \return _refCount > 1
*/
bool isShared() const;
static void deleteInstance(ReferenceCounted* instance);
private:
tbb::atomic<size_t> _refCount; ///< number of references to this object
bool _shareable; ///< flag whether this object is shareable, i.e. no non-const pointers to this object exist
};
}
#endif // REFERENCECOUNTED_H__
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment