Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
137 changes: 123 additions & 14 deletions iocore/eventsystem/I_Lock.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,13 +48,20 @@
@param _t The current EThread executing your code.

*/

// A weak version of the SCOPED_MUTEX_LOCK macro, allows the mutex to be a nullptr.
#ifdef DEBUG
#define SCOPED_MUTEX_LOCK(_l, _m, _t) MutexLock _l(MakeSourceLocation(), nullptr, _m, _t)
#else
#define SCOPED_MUTEX_LOCK(_l, _m, _t) MutexLock _l(_m, _t)
#define WEAK_SCOPED_MUTEX_LOCK(_l, _m, _t) WeakMutexLock _l(MakeSourceLocation(), (char *)nullptr, _m, _t);
#else // DEBUG
#define WEAK_SCOPED_MUTEX_LOCK(_l, _m, _t) WeakMutexLock _l(_m, _t);
#endif // DEBUG

#ifdef DEBUG
#define SCOPED_MUTEX_LOCK(_l, _m, _t) MutexLock _l(MakeSourceLocation(), (char *)nullptr, _m, _t)
#else // DEBUG
#define SCOPED_MUTEX_LOCK(_l, _m, _t) MutexLock _l(_m, _t)
#endif // DEBUG

/**
Attempts to acquire the lock to the ProxyMutex.

Expand All @@ -68,8 +75,15 @@
@param _t The current EThread executing your code.

*/
#define MUTEX_TRY_LOCK(_l, _m, _t) MutexTryLock _l(MakeSourceLocation(), (char *)nullptr, _m, _t)

#ifdef DEBUG
#define WEAK_MUTEX_TRY_LOCK(_l, _m, _t) WeakMutexTryLock _l(MakeSourceLocation(), (char *)nullptr, _m, _t);
#else // DEBUG
#define WEAK_MUTEX_TRY_LOCK(_l, _m, _t) WeakMutexTryLock _l(_m, _t);
#endif // DEBUG

#ifdef DEBUG
#define MUTEX_TRY_LOCK(_l, _m, _t) MutexTryLock _l(MakeSourceLocation(), (char *)nullptr, _m, _t)
#else // DEBUG
#define MUTEX_TRY_LOCK(_l, _m, _t) MutexTryLock _l(_m, _t)
#endif // DEBUG
Expand Down Expand Up @@ -337,23 +351,21 @@ Mutex_unlock(Ptr<ProxyMutex> &m, EThread *t)
}
}

/** Scoped lock class for ProxyMutex
*/
class MutexLock
class WeakMutexLock
{
private:
Ptr<ProxyMutex> m;
bool locked_p;

public:
MutexLock(
WeakMutexLock(
#ifdef DEBUG
const SourceLocation &location, const char *ahandler,
#endif // DEBUG
Ptr<ProxyMutex> &am, EThread *t)
: m(am), locked_p(true)
{
if (am) {
if (m.get()) {
Mutex_lock(
#ifdef DEBUG
location, ahandler,
Expand All @@ -365,7 +377,42 @@ class MutexLock
void
release()
{
if (locked_p && m) {
if (locked_p && m.get()) {
Mutex_unlock(m, m->thread_holding);
}
locked_p = false;
}

~WeakMutexLock() { this->release(); }
};

/** Scoped lock class for ProxyMutex
*/
class MutexLock
{
private:
Ptr<ProxyMutex> m;
bool locked_p;

public:
MutexLock(
#ifdef DEBUG
const SourceLocation &location, const char *ahandler,
#endif // DEBUG
Ptr<ProxyMutex> &am, EThread *t)
: m(am), locked_p(true)
{
Mutex_lock(
#ifdef DEBUG
location, ahandler,
#endif // DEBUG
m, t);
}

void
release()
{
if (locked_p) {
Mutex_unlock(m, m->thread_holding);
}
locked_p = false;
Expand All @@ -376,21 +423,21 @@ class MutexLock

/** Scoped try lock class for ProxyMutex
*/
class MutexTryLock
class WeakMutexTryLock
{
private:
Ptr<ProxyMutex> m;
bool lock_acquired;

public:
MutexTryLock(
WeakMutexTryLock(
#ifdef DEBUG
const SourceLocation &location, const char *ahandler,
#endif // DEBUG
Ptr<ProxyMutex> &am, EThread *t)
: m(am)
{
if (am) {
if (m.get()) {
lock_acquired = Mutex_trylock(
#ifdef DEBUG
location, ahandler,
Expand All @@ -401,11 +448,12 @@ class MutexTryLock
}
}

~MutexTryLock()
~WeakMutexTryLock()
{
if (lock_acquired && m.get()) {
Mutex_unlock(m, m->thread_holding);
}
lock_acquired = false;
}

/** Spin till lock is acquired
Expand Down Expand Up @@ -441,6 +489,67 @@ class MutexTryLock
}
};

/** Scoped try lock class for ProxyMutex
*/
class MutexTryLock
{
private:
Ptr<ProxyMutex> m;
bool lock_acquired;

public:
MutexTryLock(
#ifdef DEBUG
const SourceLocation &location, const char *ahandler,
#endif // DEBUG
Ptr<ProxyMutex> &am, EThread *t)
: m(am)
{
lock_acquired = Mutex_trylock(
#ifdef DEBUG
location, ahandler,
#endif // DEBUG
m, t);
}

~MutexTryLock()
{
if (lock_acquired) {
Mutex_unlock(m, m->thread_holding);
}
}

/** Spin till lock is acquired
*/
void
acquire(EThread *t)
{
MUTEX_TAKE_LOCK(m, t);
lock_acquired = true;
}

void
release()
{
if (lock_acquired) {
Mutex_unlock(m, m->thread_holding);
}
lock_acquired = false;
}

bool
is_locked() const
{
return lock_acquired;
}

const ProxyMutex *
get_mutex() const
{
return m.get();
}
};

inline void
ProxyMutex::free()
{
Expand Down
2 changes: 1 addition & 1 deletion iocore/hostdb/HostDB.cc
Original file line number Diff line number Diff line change
Expand Up @@ -994,7 +994,7 @@ HostDBContinuation::removeEvent(int /* event ATS_UNUSED */, Event *e)
if (cont) {
proxy_mutex = cont->mutex;
}
MUTEX_TRY_LOCK(lock, proxy_mutex, e->ethread);
WEAK_MUTEX_TRY_LOCK(lock, proxy_mutex, e->ethread);
if (!lock.is_locked()) {
e->schedule_in(HOST_DB_RETRY_PERIOD);
return EVENT_CONT;
Expand Down
1 change: 1 addition & 0 deletions iocore/net/SSLNetVConnection.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1747,6 +1747,7 @@ SSLNetVConnection::callHooks(TSEvent eventId)
}

if (curHook != nullptr) {
WEAK_SCOPED_MUTEX_LOCK(lock, curHook->m_cont->mutex, this_ethread());
curHook->invoke(eventId, this);
reenabled =
(this->sslHandshakeHookState != HANDSHAKE_HOOKS_CERT_INVOKE && this->sslHandshakeHookState != HANDSHAKE_HOOKS_PRE_INVOKE &&
Expand Down
2 changes: 1 addition & 1 deletion proxy/ProxySession.cc
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ ProxySession::state_api_callout(int event, void *data)
if (nullptr != cur_hook) {
APIHook const *hook = cur_hook;

MUTEX_TRY_LOCK(lock, hook->m_cont->mutex, mutex->thread_holding);
WEAK_MUTEX_TRY_LOCK(lock, hook->m_cont->mutex, mutex->thread_holding);

// Have a mutex but didn't get the lock, reschedule
if (!lock.is_locked()) {
Expand Down
2 changes: 1 addition & 1 deletion proxy/http/HttpSM.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1463,7 +1463,7 @@ plugins required to work with sni_routing.
callout_state = HTTP_API_IN_CALLOUT;
}

MUTEX_TRY_LOCK(lock, cur_hook->m_cont->mutex, mutex->thread_holding);
WEAK_MUTEX_TRY_LOCK(lock, cur_hook->m_cont->mutex, mutex->thread_holding);

// Have a mutex but didn't get the lock, reschedule
if (!lock.is_locked()) {
Expand Down
4 changes: 2 additions & 2 deletions src/traffic_server/InkAPI.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1330,7 +1330,7 @@ APIHook::invoke(int event, void *edata) const
ink_assert(!"not reached");
}
}
MUTEX_TRY_LOCK(lock, m_cont->mutex, this_ethread());
WEAK_MUTEX_TRY_LOCK(lock, m_cont->mutex, this_ethread());
if (!lock.is_locked()) {
// If we cannot get the lock, the caller needs to restructure to handle rescheduling
ink_release_assert(0);
Expand Down Expand Up @@ -4785,7 +4785,7 @@ int
TSContCall(TSCont contp, TSEvent event, void *edata)
{
Continuation *c = (Continuation *)contp;
MUTEX_TRY_LOCK(lock, c->mutex, this_ethread());
WEAK_MUTEX_TRY_LOCK(lock, c->mutex, this_ethread());
if (!lock.is_locked()) {
// If we cannot get the lock, the caller needs to restructure to handle rescheduling
ink_release_assert(0);
Expand Down
4 changes: 2 additions & 2 deletions src/traffic_server/traffic_server.cc
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,7 @@ struct AutoStopCont : public Continuation {

APIHook *hook = lifecycle_hooks->get(TS_LIFECYCLE_SHUTDOWN_HOOK);
while (hook) {
SCOPED_MUTEX_LOCK(lock, hook->m_cont->mutex, this_ethread());
WEAK_SCOPED_MUTEX_LOCK(lock, hook->m_cont->mutex, this_ethread());
hook->invoke(TS_EVENT_LIFECYCLE_SHUTDOWN, nullptr);
hook = hook->next();
}
Expand Down Expand Up @@ -2113,7 +2113,7 @@ task_threads_started_callback()
{
APIHook *hook = lifecycle_hooks->get(TS_LIFECYCLE_TASK_THREADS_READY_HOOK);
while (hook) {
SCOPED_MUTEX_LOCK(lock, hook->m_cont->mutex, this_ethread());
WEAK_SCOPED_MUTEX_LOCK(lock, hook->m_cont->mutex, this_ethread());
hook->invoke(TS_EVENT_LIFECYCLE_TASK_THREADS_READY, nullptr);
hook = hook->next();
}
Expand Down