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 rscan(0), rcount(0), rwaiting(0), rcycle(0), ref_inprogress(0),
81 ref_waiting(0), rref_waiting(0), rrefs(0),
82 rset(0), references(n_refs),
83 deferred_scan(false), needs_is_valid(niv), rref_wait(false) {
86 DLLLOCAL
virtual ~RObject();
88 DLLLOCAL
void tRef()
const {
89 #ifdef QORE_DEBUG_OBJ_REFS
95 DLLLOCAL
void tDeref() {
96 #ifdef QORE_DEBUG_OBJ_REFS
107 DLLLOCAL
int deref(
bool real,
bool& do_scan,
bool& rescan);
110 DLLLOCAL
void derefRealIntern();
112 DLLLOCAL
void derefDone(
bool del);
114 DLLLOCAL
int refs()
const {
118 DLLLOCAL
void setRSet(RSet* rs,
int rcnt);
122 DLLLOCAL
int checkDeferScan();
124 DLLLOCAL
void removeInvalidateRSet();
125 DLLLOCAL
void removeInvalidateRSetIntern();
130 DLLLOCAL
bool mightHaveRecursiveReferences()
const {
131 return rset || rcount;
135 DLLLOCAL
bool isValid()
const {
136 return !needs_is_valid ? true : isValidImpl();
140 DLLLOCAL
virtual bool isValidImpl()
const {
146 DLLLOCAL
virtual bool scanMembers(RSetHelper& rsh) = 0;
151 DLLLOCAL
virtual bool needsScan(
bool scan_now) = 0;
154 DLLLOCAL
virtual void deleteObject() = 0;
157 DLLLOCAL
virtual const char* getName()
const = 0;
161 typedef vector_set_t<RObject*> rset_t;
180 DLLLOCAL
void invalidateIntern() {
184 for (rset_t::iterator i = begin(), e = end(); i != e; ++i)
193 DLLLOCAL RSet() : acnt(0), valid(true) {
196 DLLLOCAL RSet(RObject* o) : acnt(0), valid(true) {
200 DLLLOCAL RSet(
bool n_valid) : acnt(1), valid(n_valid) {
208 DLLLOCAL
void deref() {
222 DLLLOCAL
void invalidate() {
228 DLLLOCAL
void invalidateDeref() {
244 DLLLOCAL
void ref() {
249 DLLLOCAL
bool active()
const {
258 DLLLOCAL
int canDelete(
int ref_copy,
int rcount);
263 DLLLOCAL
static bool isValid(
const RSet* rs) {
264 return rs ? rs->valid :
false;
268 DLLLOCAL
bool assigned()
const {
272 DLLLOCAL
void insert(RObject* o) {
273 assert(set.find(o) == set.end());
277 DLLLOCAL
void clear() {
281 DLLLOCAL rset_t::iterator begin() {
285 DLLLOCAL rset_t::iterator end() {
289 DLLLOCAL rset_t::iterator find(RObject* o) {
293 DLLLOCAL
size_t size()
const {
298 DLLLOCAL
bool pop() {
299 assert(!set.empty());
300 set.erase(set.begin());
305 DLLLOCAL
unsigned getCount()
const {
312 typedef std::vector<RObject*> rvec_t;
315 typedef vector_set_t<RSet*> rs_set_t;
323 DLLLOCAL RSetStat() : rset(0), rcount(0), in_cycle(false), ok(false) {
326 DLLLOCAL RSetStat(
const RSetStat& old) : rset(old.rset), rcount(old.rcount), in_cycle(old.in_cycle), ok(old.ok) {
329 DLLLOCAL
void finalize(RSet* rs = 0) {
336 class QoreClosureBase;
339 friend class RSectionScanHelper;
340 friend class RObject;
342 DLLLOCAL RSetHelper(
const RSetHelper&);
346 typedef std::map<RObject*, RSetStat> omap_t;
347 typedef std::set<QoreClosureBase*> closure_set_t;
351 typedef std::vector<omap_t::iterator> ovec_t;
356 rs_set_t tr_invalidate;
365 closure_set_t closure_set;
369 DLLLOCAL
void inccnt() { ++lcnt; }
370 DLLLOCAL
void deccnt() { --lcnt; }
372 DLLLOCAL
void inccnt() {}
373 DLLLOCAL
void deccnt() {}
377 DLLLOCAL
void rollback();
380 DLLLOCAL
void commit(RObject& obj);
383 DLLLOCAL
bool checkIntern(RObject& obj);
388 DLLLOCAL
bool removeInvalidate(RSet* ors,
int tid =
q_gettid());
390 DLLLOCAL
bool inCurrentSet(omap_t::iterator fi) {
391 for (
size_t i = 0; i < ovec.size(); ++i)
397 DLLLOCAL
bool addToRSet(omap_t::iterator oi, RSet* rset,
int tid);
399 DLLLOCAL
void mergeRSet(
int i, RSet*& rset);
401 DLLLOCAL
bool makeChain(
int i, omap_t::iterator fi,
int tid);
404 DLLLOCAL RSetHelper(RObject& obj);
406 DLLLOCAL ~RSetHelper() {
407 assert(ovec.empty());
411 DLLLOCAL
unsigned size()
const {
415 DLLLOCAL
void add(RObject* ro) {
416 if (fomap.find(ro) != fomap.end())
418 rset_t::iterator i = tr_out.lower_bound(ro);
419 if (i == tr_out.end() || *i != ro)
420 tr_out.insert(i, ro);
425 return checkIntern(n);
429 DLLLOCAL
bool checkNode(RObject& robj) {
430 return checkIntern(robj);
434 class qore_object_private;
441 qore_object_private* qo;
453 DLLLOCAL
int getRefs()
const {
458 DLLLOCAL
bool deferredScan() {
460 deferred_scan =
false;
467 DLLLOCAL
bool doScan()
const {
472 DLLLOCAL
void finalDeref(qore_object_private* obj) {
479 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