32#ifndef _QORE_INTERN_RSETHELPER_H
34#define _QORE_INTERN_RSETHELPER_H
36#include "qore/intern/RSection.h"
37#include "qore/vector_set"
38#include "qore/vector_map"
51 mutable RSectionLock rml;
73 std::atomic_int& references;
75 bool deferred_scan : 1,
79 DLLLOCAL RObject(std::atomic_int& n_refs,
bool niv =
false) :
80 references(n_refs), deferred_scan(false), needs_is_valid(niv), rref_wait(false) {
83 DLLLOCAL
virtual ~RObject();
85 DLLLOCAL
void tRef()
const {
86#ifdef QORE_DEBUG_OBJ_REFS
92 DLLLOCAL
void tDeref() {
93#ifdef QORE_DEBUG_OBJ_REFS
104 DLLLOCAL
int deref(
bool real,
bool& do_scan,
bool& rescan);
107 DLLLOCAL
void derefRealIntern();
109 DLLLOCAL
void derefDone(
bool del);
111 DLLLOCAL
int refs()
const {
115 DLLLOCAL
void setRSet(RSet* rs,
int rcnt);
119 DLLLOCAL
int checkDeferScan();
121 DLLLOCAL
void removeInvalidateRSet();
122 DLLLOCAL
void removeInvalidateRSetIntern();
127 DLLLOCAL
bool mightHaveRecursiveReferences()
const {
128 return rset || rcount;
132 DLLLOCAL
bool isValid()
const {
133 return !needs_is_valid ? true : isValidImpl();
137 DLLLOCAL
virtual bool isValidImpl()
const {
143 DLLLOCAL
virtual bool scanMembers(RSetHelper& rsh) = 0;
148 DLLLOCAL
virtual bool needsScan(
bool scan_now) = 0;
151 DLLLOCAL
virtual void deleteObject() = 0;
154 DLLLOCAL
virtual const char* getName()
const = 0;
158typedef vector_set_t<RObject*> rset_t;
177 DLLLOCAL
void invalidateIntern() {
181 for (rset_t::iterator i = begin(), e = end(); i != e; ++i)
190 DLLLOCAL RSet() : acnt(0), valid(true) {
193 DLLLOCAL RSet(RObject* o) : acnt(0), valid(true) {
197 DLLLOCAL RSet(
bool n_valid) : acnt(1), valid(n_valid) {
205 DLLLOCAL
void deref() {
219 DLLLOCAL
void invalidate() {
225 DLLLOCAL
void invalidateDeref() {
241 DLLLOCAL
void ref() {
246 DLLLOCAL
bool active()
const {
255 DLLLOCAL
int canDelete(
int ref_copy,
int rcount);
260 DLLLOCAL
static bool isValid(
const RSet* rs) {
261 return rs ? rs->valid :
false;
265 DLLLOCAL
bool assigned()
const {
269 DLLLOCAL
void insert(RObject* o) {
270 assert(set.find(o) == set.end());
274 DLLLOCAL
void clear() {
278 DLLLOCAL rset_t::iterator begin() {
282 DLLLOCAL rset_t::iterator end() {
286 DLLLOCAL rset_t::iterator find(RObject* o) {
290 DLLLOCAL
size_t size()
const {
295 DLLLOCAL
bool pop() {
296 assert(!set.empty());
297 set.erase(set.begin());
302 DLLLOCAL
unsigned getCount()
const {
308typedef std::vector<RObject*> rvec_t;
311typedef vector_set_t<RSet*> rs_set_t;
314 RSet* rset =
nullptr;
319 DLLLOCAL RSetStat() : in_cycle(false), ok(false) {
322 DLLLOCAL RSetStat(
const RSetStat& old) : rset(old.rset), rcount(old.rcount), in_cycle(old.in_cycle), ok(old.ok) {
325 DLLLOCAL
void finalize(RSet* rs =
nullptr) {
332class QoreClosureBase;
335 friend class RSectionScanHelper;
336 friend class RObject;
338 DLLLOCAL RSetHelper(
const RSetHelper&);
342 typedef std::map<RObject*, RSetStat> omap_t;
343 typedef std::set<QoreClosureBase*> closure_set_t;
347 typedef std::vector<omap_t::iterator> ovec_t;
352 rs_set_t tr_invalidate;
361 closure_set_t closure_set;
365 DLLLOCAL
void inccnt() { ++lcnt; }
366 DLLLOCAL
void deccnt() { --lcnt; }
368 DLLLOCAL
void inccnt() {}
369 DLLLOCAL
void deccnt() {}
373 DLLLOCAL
void rollback();
376 DLLLOCAL
void commit(RObject& obj);
379 DLLLOCAL
bool checkIntern(RObject& obj);
384 DLLLOCAL
bool removeInvalidate(RSet* ors,
int tid =
q_gettid());
386 DLLLOCAL
bool inCurrentSet(omap_t::iterator fi) {
387 for (
size_t i = 0; i < ovec.size(); ++i)
393 DLLLOCAL
bool addToRSet(omap_t::iterator oi, RSet* rset,
int tid);
395 DLLLOCAL
void mergeRSet(
int i, RSet*& rset);
397 DLLLOCAL
bool makeChain(
int i, omap_t::iterator fi,
int tid);
400 DLLLOCAL RSetHelper(RObject& obj);
402 DLLLOCAL ~RSetHelper() {
403 assert(ovec.empty());
407 DLLLOCAL
unsigned size()
const {
411 DLLLOCAL
void add(RObject* ro) {
412 if (fomap.find(ro) != fomap.end())
414 rset_t::iterator i = tr_out.lower_bound(ro);
415 if (i == tr_out.end() || *i != ro)
416 tr_out.insert(i, ro);
421 return checkIntern(n);
425 DLLLOCAL
bool checkNode(RObject& robj) {
426 return checkIntern(robj);
430class qore_object_private;
437 qore_object_private* qo =
nullptr;
449 DLLLOCAL
int getRefs()
const {
454 DLLLOCAL
bool deferredScan() {
456 deferred_scan =
false;
463 DLLLOCAL
bool doScan()
const {
468 DLLLOCAL
void finalDeref(qore_object_private* obj) {
475 DLLLOCAL
void willDelete() {
The base class for all value and parse types in Qore expression trees.
Definition AbstractQoreNode.h:57
provides a safe and exception-safe way to hold write locks in Qore, only to be used on the stack,...
Definition QoreRWLock.h:144
a thread condition class implementing a wrapper for pthread_cond_t
Definition QoreCondition.h:45
provides a simple POSIX-threads-based read-write lock
Definition QoreRWLock.h:47
Provides atomic reference counting to Qore objects.
Definition QoreReferenceCounter.h:44
DLLEXPORT void ROreference() const
Atomically increments the reference count.
DLLEXPORT int reference_count() const
Gets the reference count.
DLLEXPORT bool ROdereference() const
Atomically decrements the reference count.
provides a mutually-exclusive thread lock
Definition QoreThreadLock.h:49
DLLEXPORT int q_gettid() noexcept
returns the current TID number