Skip to content

Commit

Permalink
char: attempt to make Character class thread-safe
Browse files Browse the repository at this point in the history
  • Loading branch information
rdb committed Feb 10, 2020
1 parent 141482f commit 3ac504e
Show file tree
Hide file tree
Showing 4 changed files with 97 additions and 78 deletions.
3 changes: 3 additions & 0 deletions panda/src/chan/partBundleNode.I
Expand Up @@ -46,6 +46,7 @@ PartBundleNode(const PartBundleNode &copy) :
*/
INLINE int PartBundleNode::
get_num_bundles() const {
LightMutexHolder holder(_lock);
return _bundles.size();
}

Expand All @@ -54,6 +55,7 @@ get_num_bundles() const {
*/
INLINE PartBundle *PartBundleNode::
get_bundle(int n) const {
LightMutexHolder holder(_lock);
nassertr(n >= 0 && n < (int)_bundles.size(), nullptr);
return _bundles[n]->get_bundle();
}
Expand All @@ -65,6 +67,7 @@ get_bundle(int n) const {
*/
INLINE PartBundleHandle *PartBundleNode::
get_bundle_handle(int n) const {
LightMutexHolder holder(_lock);
nassertr(n >= 0 && n < (int)_bundles.size(), nullptr);
return _bundles[n];
}
49 changes: 27 additions & 22 deletions panda/src/chan/partBundleNode.cxx
Expand Up @@ -25,9 +25,9 @@ TypeHandle PartBundleNode::_type_handle;
*/
PartBundleNode::
~PartBundleNode() {
Bundles::iterator bi;
for (bi = _bundles.begin(); bi != _bundles.end(); ++bi) {
(*bi)->get_bundle()->remove_node(this);
LightMutexHolder holder(_lock);
for (PartBundleHandle *handle : _bundles) {
handle->get_bundle()->remove_node(this);
}
}

Expand All @@ -44,9 +44,8 @@ void PartBundleNode::
apply_attribs_to_vertices(const AccumulatedAttribs &attribs, int attrib_types,
GeomTransformer &transformer) {
if ((attrib_types & SceneGraphReducer::TT_transform) != 0) {
Bundles::iterator bi;
for (bi = _bundles.begin(); bi != _bundles.end(); ++bi) {
PT(PartBundleHandle) handle = (*bi);
LightMutexHolder holder(_lock);
for (PT(PartBundleHandle) handle : _bundles) {
PartBundle *bundle = handle->get_bundle();
PT(PartBundle) new_bundle = bundle->apply_transform(attribs._transform);
update_bundle(handle, new_bundle);
Expand All @@ -71,9 +70,8 @@ xform(const LMatrix4 &mat) {
return;
}

Bundles::iterator bi;
for (bi = _bundles.begin(); bi != _bundles.end(); ++bi) {
PT(PartBundleHandle) handle = (*bi);
LightMutexHolder holder(_lock);
for (PT(PartBundleHandle) handle : _bundles) {
PartBundle *bundle = handle->get_bundle();
if (bundle->get_num_nodes() > 1) {
PT(PartBundle) new_bundle = DCAST(PartBundle, bundle->copy_subgraph());
Expand All @@ -90,14 +88,15 @@ xform(const LMatrix4 &mat) {
void PartBundleNode::
add_bundle(PartBundle *bundle) {
PT(PartBundleHandle) handle = new PartBundleHandle(bundle);
add_bundle_handle(handle);
LightMutexHolder holder(_lock);
do_add_bundle_handle(handle);
}

/**
*
* Assumes the lock is held.
*/
void PartBundleNode::
add_bundle_handle(PartBundleHandle *handle) {
do_add_bundle_handle(PartBundleHandle *handle) {
Bundles::iterator bi = find(_bundles.begin(), _bundles.end(), handle);
if (bi != _bundles.end()) {
// This handle is already within the node.
Expand All @@ -117,18 +116,24 @@ steal_bundles(PartBundleNode *other) {
return;
}

Bundles::iterator bi;
for (bi = other->_bundles.begin(); bi != other->_bundles.end(); ++bi) {
PartBundleHandle *handle = (*bi);
LightMutexHolder other_holder(other->_lock);
if (other->_bundles.empty()) {
return;
}

LightMutexHolder holder(_lock);
for (PartBundleHandle *handle : other->_bundles) {
handle->get_bundle()->remove_node(other);
add_bundle_handle(handle);
do_add_bundle_handle(handle);
}
other->_bundles.clear();
}

/**
* Replaces the contents of the indicated PartBundleHandle (presumably stored
* within this node) with new_bundle.
*
* Assumes the lock is held.
*/
void PartBundleNode::
update_bundle(PartBundleHandle *old_bundle_handle, PartBundle *new_bundle) {
Expand All @@ -146,10 +151,10 @@ void PartBundleNode::
write_datagram(BamWriter *manager, Datagram &dg) {
PandaNode::write_datagram(manager, dg);

LightMutexHolder holder(_lock);
dg.add_uint16(_bundles.size());
Bundles::iterator bi;
for (bi = _bundles.begin(); bi != _bundles.end(); ++bi) {
manager->write_pointer(dg, (*bi)->get_bundle());
for (PartBundleHandle *handle : _bundles) {
manager->write_pointer(dg, handle->get_bundle());
}
}

Expand All @@ -161,11 +166,11 @@ int PartBundleNode::
complete_pointers(TypedWritable **p_list, BamReader* manager) {
int pi = PandaNode::complete_pointers(p_list, manager);

Bundles::iterator bi;
for (bi = _bundles.begin(); bi != _bundles.end(); ++bi) {
LightMutexHolder holder(_lock);
for (PT(PartBundleHandle) &handle : _bundles) {
PT(PartBundle) bundle = DCAST(PartBundle, p_list[pi++]);
bundle->add_node(this);
(*bi) = new PartBundleHandle(bundle);
handle = new PartBundleHandle(bundle);
}

return pi;
Expand Down
5 changes: 3 additions & 2 deletions panda/src/chan/partBundleNode.h
Expand Up @@ -18,7 +18,7 @@

#include "partBundle.h"
#include "partBundleHandle.h"

#include "lightMutex.h"
#include "pandaNode.h"
#include "dcast.h"
#include "pvector.h"
Expand Down Expand Up @@ -59,12 +59,13 @@ class EXPCL_PANDA_CHAN PartBundleNode : public PandaNode {

protected:
void add_bundle(PartBundle *bundle);
void add_bundle_handle(PartBundleHandle *handle);
void do_add_bundle_handle(PartBundleHandle *handle);
void steal_bundles(PartBundleNode *other);
virtual void update_bundle(PartBundleHandle *old_bundle_handle,
PartBundle *new_bundle);

protected:
LightMutex _lock;
typedef pvector< PT(PartBundleHandle) > Bundles;
Bundles _bundles;

Expand Down

0 comments on commit 3ac504e

Please sign in to comment.