Skip to content

Instantly share code, notes, and snippets.

@toddlipcon
Created April 7, 2020 16:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save toddlipcon/5d5c6629dd29bc6975dd509e75424454 to your computer and use it in GitHub Desktop.
Save toddlipcon/5d5c6629dd29bc6975dd509e75424454 to your computer and use it in GitHub Desktop.
// Curiously-recurring-template-pattern base class for private arrow data.
//
// This is similar to RefCountedThreadSafe<T> except that it participates in the
// C-style release callback expected by the Arrow C interface.
template<class T>
struct ArrowPrivateDataBase {
~ArrowPrivateDataBase() {
DCHECK_EQ(0, ref_count);
}
template<class ArrowType>
static void Release(ArrowType* arrow) {
// In case this is called on the top-level struct, release all the children.
// Rather than doing an atomic reference count decrement for each child, we
// just accumulate them and do them once outside the loop.
int n_refs = 1;
for (int i = 0; i < arrow->n_children; i++) {
auto* child = arrow->children[i];
// Note that consumers may have released children already or moved them out
// of the top-level schema, in which case they will have their 'release' function
// set to nullptr.
if (child->release) {
DCHECK_EQ(child->private_data, arrow->private_data);
n_refs++;
child->release = nullptr;
}
}
T* priv = static_cast<T*>(arrow->private_data);
if (!base::RefCountDecN(&priv->ref_count, n_refs)) {
delete priv;
}
}
Atomic32 ref_count = 0;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment