32#ifndef _QORE_INTERN_RSECTION_H
34#define _QORE_INTERN_RSECTION_H
36#include "qore/intern/qore_var_rwlock_priv.h"
39class qore_rsection_priv;
47 DLLLOCAL RNotifier() {
50 DLLLOCAL ~RNotifier() {
54 DLLLOCAL
void done() {
67 DLLLOCAL
void wait() {
75 RNotifier(
const RNotifier&) =
delete;
76 RNotifier& operator=(
const RNotifier&) =
delete;
79typedef std::list<RNotifier*> n_list_t;
84class qore_rsection_priv :
public qore_var_rwlock_priv {
86 DLLLOCAL qore_rsection_priv() {
90 DLLLOCAL
virtual ~qore_rsection_priv() {
97 DLLLOCAL
int tryRSectionLockNotifyWaitRead(RNotifier* rn);
99 DLLLOCAL
void upgradeReadToRSection(
int tid =
q_gettid()) {
101 assert(write_tid == -1);
103 while (rs_tid != -1) {
105 rsection_cond.wait(l);
112 DLLLOCAL
void rSectionUnlock() {
114 assert(write_tid == -1);
121 qore_rsection_priv::notifyIntern();
123 if (rsection_waiting)
124 rsection_cond.signal();
127 unlock_read_signal();
130 DLLLOCAL
bool hasRSectionLock(
int tid =
q_gettid()) {
131 return rs_tid == tid;
134 DLLLOCAL
bool checkRSectionExclusive(
int tid =
q_gettid()) {
135 return (rs_tid == tid || write_tid == tid);
138 DLLLOCAL
int rSectionTid()
const {
147 int rsection_waiting = 0;
156 DLLLOCAL
virtual void notifyIntern() {
157 for (n_list_t::iterator i = list.begin(), e = list.end(); i != e; ++i) {
163 DLLLOCAL
void setNotificationIntern(RNotifier* rn) {
164 assert(write_tid != -1 || rs_tid != -1);
171 qore_rsection_priv(
const qore_rsection_priv&) =
delete;
172 qore_rsection_priv& operator=(
const qore_rsection_priv&) =
delete;
175class RSectionLock :
public QoreVarRWLock {
177 DLLLOCAL RSectionLock() : QoreVarRWLock(new qore_rsection_priv) {
180 DLLLOCAL ~RSectionLock() {
184 DLLLOCAL
int tryRSectionLockNotifyWaitRead(RNotifier* rn) {
185 assert(priv->write_tid >= -1);
186 return static_cast<qore_rsection_priv*
>(priv)->tryRSectionLockNotifyWaitRead(rn);
189 DLLLOCAL
void rSectionUnlock() {
190 assert(priv->write_tid >= -1);
191 static_cast<qore_rsection_priv*
>(priv)->rSectionUnlock();
194 DLLLOCAL
bool hasRSectionLock(
int tid =
q_gettid()) {
195 assert(priv->write_tid >= -1);
196 return static_cast<qore_rsection_priv*
>(priv)->hasRSectionLock(tid);
199 DLLLOCAL
bool checkRSectionExclusive(
int tid =
q_gettid()) {
200 assert(priv->write_tid >= -1);
201 return static_cast<qore_rsection_priv*
>(priv)->checkRSectionExclusive(tid);
204 DLLLOCAL
void upgradeReadToRSection(
int tid =
q_gettid()) {
205 assert(priv->write_tid >= -1);
206 static_cast<qore_rsection_priv*
>(priv)->upgradeReadToRSection(tid);
209 DLLLOCAL
int rSectionTid()
const {
210 assert(priv->write_tid >= -1);
211 return static_cast<qore_rsection_priv*
>(priv)->rSectionTid();
215class QoreSafeRSectionReadLocker :
private QoreSafeVarRWReadLocker {
217 DLLLOCAL QoreSafeRSectionReadLocker(RSectionLock& n_l) : QoreSafeVarRWReadLocker(n_l), has_rsection(false) {
220 DLLLOCAL ~QoreSafeRSectionReadLocker() {
221 if (locked && has_rsection) {
222 static_cast<RSectionLock*
>(l)->rSectionUnlock();
227 DLLLOCAL
void acquireRSection(
int tid =
q_gettid()) {
228 static_cast<RSectionLock*
>(l)->upgradeReadToRSection(tid);
233 DLLLOCAL
void unlock() {
238 static_cast<RSectionLock*
>(l)->rSectionUnlock();
248class QoreRSectionLocker :
private QoreSafeVarRWReadLocker {
250 DLLLOCAL QoreRSectionLocker(RSectionLock& n_l) : QoreSafeVarRWReadLocker(n_l) {
251 static_cast<RSectionLock*
>(l)->upgradeReadToRSection();
254 DLLLOCAL ~QoreRSectionLocker() {
255 static_cast<RSectionLock*
>(l)->rSectionUnlock();
provides a safe and exception-safe way to hold locks in Qore, only to be used on the stack,...
Definition QoreThreadLock.h:136
a thread condition class implementing a wrapper for pthread_cond_t
Definition QoreCondition.h:45
DLLEXPORT int wait(pthread_mutex_t *m)
blocks a thread on a mutex until the condition is signaled
DLLEXPORT int signal()
signals a single waiting thread to wake up
provides a mutually-exclusive thread lock
Definition QoreThreadLock.h:49
DLLEXPORT int q_gettid() noexcept
returns the current TID number