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;
72#ifdef _QORE_CYCLE_CHECK
74 std::set<RObject*> refmap;
78 std::atomic_int& references;
80 bool deferred_scan : 1,
84 DLLLOCAL RObject(std::atomic_int& n_refs,
bool niv =
false) :
85 references(n_refs), deferred_scan(false), needs_is_valid(niv), rref_wait(false) {
88 DLLLOCAL
virtual ~RObject();
90 DLLLOCAL
void tRef()
const {
91#ifdef QORE_DEBUG_OBJ_REFS
92 printd(QORE_DEBUG_OBJ_REFS,
"RObject::tRef() this: %p tref %d->%d\n",
this, tRefs.
reference_count(),
98 DLLLOCAL
void tDeref() {
99#ifdef QORE_DEBUG_OBJ_REFS
100 printd(QORE_DEBUG_OBJ_REFS,
"RObject::tDeref() this: %p tref %d->%d\n",
this, tRefs.
reference_count(),
111 DLLLOCAL
int deref(
bool real,
bool& do_scan,
bool& rescan);
114 DLLLOCAL
void derefRealIntern();
116 DLLLOCAL
void derefDone(
bool del);
118 DLLLOCAL
int refs()
const {
122 DLLLOCAL
void setRSet(RSet* rs,
int rcnt);
126 DLLLOCAL
int checkDeferScan();
128 DLLLOCAL
void removeInvalidateRSet();
129 DLLLOCAL
void removeInvalidateRSetIntern();
134 DLLLOCAL
bool mightHaveRecursiveReferences()
const {
135 return rset || rcount;
139 DLLLOCAL
bool isValid()
const {
140 return !needs_is_valid ? true : isValidImpl();
144 DLLLOCAL
virtual bool isValidImpl()
const {
150 DLLLOCAL
virtual bool scanMembers(RSetHelper& rsh) = 0;
155 DLLLOCAL
virtual bool needsScan(
bool scan_now) = 0;
158 DLLLOCAL
virtual void deleteObject() = 0;
161 DLLLOCAL
virtual const char* getName()
const = 0;
165typedef vector_set_t<RObject*> rset_t;
181 DLLLOCAL RSet() : acnt(0), valid(true) {
184 DLLLOCAL RSet(RObject* o) : acnt(0), valid(true) {
188 DLLLOCAL RSet(
bool n_valid) : acnt(1), valid(n_valid) {
196 DLLLOCAL
void deref() {
212 DLLLOCAL
void invalidate() {
219 DLLLOCAL
void invalidateDeref() {
236 DLLLOCAL
void ref() {
241 DLLLOCAL
bool active()
const {
250 DLLLOCAL
int canDelete(
int ref_copy,
int rcount);
255 DLLLOCAL
static bool isValid(
const RSet* rs) {
256 return rs ? rs->valid :
false;
260 DLLLOCAL
bool assigned()
const {
264 DLLLOCAL
void insert(RObject* o) {
265 assert(set.find(o) == set.end());
269 DLLLOCAL
void clear() {
273 DLLLOCAL rset_t::iterator begin() {
277 DLLLOCAL rset_t::iterator end() {
281 DLLLOCAL rset_t::iterator find(RObject* o) {
285 DLLLOCAL
size_t size()
const {
290 DLLLOCAL
bool pop() {
291 assert(!set.empty());
292 set.erase(set.begin());
297 DLLLOCAL
unsigned getCount()
const {
308 DLLLOCAL
void invalidateIntern() {
312 for (rset_t::iterator i = begin(), e = end(); i != e; ++i) {
320typedef std::vector<RObject*> rvec_t;
323typedef vector_set_t<RSet*> rs_set_t;
326 RSet* rset =
nullptr;
331 DLLLOCAL RSetStat() : in_cycle(false), ok(false) {
334 DLLLOCAL RSetStat(
const RSetStat& old) : rset(old.rset), rcount(old.rcount), in_cycle(old.in_cycle), ok(old.ok) {
337 DLLLOCAL
void finalize(RSet* rs =
nullptr) {
344class QoreClosureBase;
347 friend class RSectionScanHelper;
348 friend class RObject;
349#ifdef _QORE_CYCLE_CHECK
350 friend class RSetContextHelper;
351 friend class RSetScanContextHelper;
354 DLLLOCAL RSetHelper(RObject& obj);
356 DLLLOCAL ~RSetHelper() {
357 assert(ovec.empty());
361 DLLLOCAL
unsigned size()
const {
365 DLLLOCAL
void add(RObject* ro) {
366 if (fomap.find(ro) != fomap.end())
368 rset_t::iterator i = tr_out.lower_bound(ro);
369 if (i == tr_out.end() || *i != ro)
370 tr_out.insert(i, ro);
375 return checkIntern(n);
379 DLLLOCAL
bool checkNode(RObject& robj) {
380 return checkIntern(robj);
383#ifdef _QORE_CYCLE_CHECK
384 DLLLOCAL
void setScanContext(RObject* scan_context) {
385 this->scan_context = scan_context;
391 typedef std::map<RObject*, RSetStat> omap_t;
392 typedef std::set<QoreClosureBase*> closure_set_t;
397 typedef std::set<QoreHashNode*> hset_t;
401 typedef std::set<QoreListNode*> lset_t;
404 typedef std::vector<omap_t::iterator> ovec_t;
409 rs_set_t tr_invalidate;
418 closure_set_t closure_set;
420#ifdef _QORE_CYCLE_CHECK
421 RObject* scan_context =
nullptr;
426 DLLLOCAL
void inccnt() { ++lcnt; }
427 DLLLOCAL
void deccnt() { --lcnt; }
429 DLLLOCAL
void inccnt() {}
430 DLLLOCAL
void deccnt() {}
434 DLLLOCAL
void rollback();
437 DLLLOCAL
void commit(RObject& obj);
440 DLLLOCAL
bool checkIntern(RObject& obj);
445 DLLLOCAL
bool removeInvalidate(RSet* ors,
int tid =
q_gettid());
447 DLLLOCAL
bool inCurrentSet(omap_t::iterator fi) {
448 for (
size_t i = 0; i < ovec.size(); ++i) {
457 DLLLOCAL
bool addToRSet(omap_t::iterator oi, RSet* rset,
int tid);
459 DLLLOCAL
void mergeRSet(
int i, RSet*& rset);
461 DLLLOCAL
void mergeRSetIntern(RSet*& rset, RSet* old_rset);
463 DLLLOCAL
bool makeChain(
int i, omap_t::iterator fi,
int tid);
465#ifdef _QORE_CYCLE_CHECK
466 DLLLOCAL
void setObjectScanContext(RObject& obj,
int rcount);
470 DLLLOCAL RSetHelper(
const RSetHelper&);
473#ifdef _QORE_CYCLE_CHECK
474class RSetContextHelper {
476 DLLLOCAL RSetContextHelper(RSetHelper& rsh) : rsh(rsh), scan_context_save(rsh.scan_context) {
479 DLLLOCAL ~RSetContextHelper() {
480 if (rsh.scan_context != scan_context_save) {
481 rsh.scan_context = scan_context_save;
487 RObject* scan_context_save;
490class RSetScanContextHelper {
492 DLLLOCAL RSetScanContextHelper(RSetHelper& rsh, RObject* new_context) : rsh(rsh),
493 scan_context_save(rsh.scan_context) {
494 rsh.scan_context = new_context;
497 DLLLOCAL ~RSetScanContextHelper() {
498 if (rsh.scan_context != scan_context_save) {
499 rsh.scan_context = scan_context_save;
505 RObject* scan_context_save;
509class qore_object_private;
516 qore_object_private* qo =
nullptr;
528 DLLLOCAL
int getRefs()
const {
533 DLLLOCAL
bool deferredScan() {
535 deferred_scan =
false;
542 DLLLOCAL
bool doScan()
const {
547 DLLLOCAL
void finalDeref(qore_object_private* obj) {
554 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:143
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