Allow recursive fc::mutexes
This commit is contained in:
parent
4e83427df0
commit
b63e6a8b81
2 changed files with 27 additions and 19 deletions
|
|
@ -102,6 +102,7 @@ namespace fc {
|
||||||
private:
|
private:
|
||||||
fc::spin_yield_lock m_blist_lock;
|
fc::spin_yield_lock m_blist_lock;
|
||||||
fc::context* m_blist;
|
fc::context* m_blist;
|
||||||
|
unsigned recursive_lock_count;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace fc
|
} // namespace fc
|
||||||
|
|
|
||||||
|
|
@ -7,8 +7,10 @@
|
||||||
|
|
||||||
namespace fc {
|
namespace fc {
|
||||||
|
|
||||||
mutex::mutex()
|
mutex::mutex() :
|
||||||
:m_blist(0){}
|
m_blist(0),
|
||||||
|
recursive_lock_count(0)
|
||||||
|
{}
|
||||||
|
|
||||||
mutex::~mutex() {
|
mutex::~mutex() {
|
||||||
if( m_blist )
|
if( m_blist )
|
||||||
|
|
@ -134,6 +136,8 @@ namespace fc {
|
||||||
{
|
{
|
||||||
// nobody else owns the mutex, so we get it; add our context as the last and only element on the mutex's list
|
// nobody else owns the mutex, so we get it; add our context as the last and only element on the mutex's list
|
||||||
m_blist = current_context;
|
m_blist = current_context;
|
||||||
|
assert(recursive_lock_count == 0);
|
||||||
|
recursive_lock_count = 1;
|
||||||
assert(!current_context->next_blocked_mutex);
|
assert(!current_context->next_blocked_mutex);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -141,18 +145,14 @@ namespace fc {
|
||||||
// allow recusive locks
|
// allow recusive locks
|
||||||
fc::context* dummy_context_to_unblock = 0;
|
fc::context* dummy_context_to_unblock = 0;
|
||||||
if ( get_tail( m_blist, dummy_context_to_unblock ) == current_context ) {
|
if ( get_tail( m_blist, dummy_context_to_unblock ) == current_context ) {
|
||||||
// if we already have the lock (meaning we're on the tail of the list) then
|
assert(recursive_lock_count > 0);
|
||||||
// we shouldn't be trying to grab the lock again
|
++recursive_lock_count;
|
||||||
assert(false);
|
|
||||||
// EMF: I think recursive locks are currently broken -- we need to
|
|
||||||
// keep track of how many times this mutex has been locked by the
|
|
||||||
// current context. Unlocking should decrement this count and unblock
|
|
||||||
// the next context only if the count drops to zero
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// add ourselves to the head of the list
|
// add ourselves to the head of the list
|
||||||
current_context->next_blocked_mutex = m_blist;
|
current_context->next_blocked_mutex = m_blist;
|
||||||
m_blist = current_context;
|
m_blist = current_context;
|
||||||
|
++recursive_lock_count;
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
int cnt = 0;
|
int cnt = 0;
|
||||||
|
|
@ -185,17 +185,24 @@ namespace fc {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void mutex::unlock() {
|
void mutex::unlock()
|
||||||
|
{
|
||||||
fc::context* context_to_unblock = 0;
|
fc::context* context_to_unblock = 0;
|
||||||
{ fc::unique_lock<fc::spin_yield_lock> lock(m_blist_lock);
|
|
||||||
get_tail(m_blist, context_to_unblock);
|
fc::unique_lock<fc::spin_yield_lock> lock(m_blist_lock);
|
||||||
if( context_to_unblock ) {
|
assert(recursive_lock_count > 0);
|
||||||
context_to_unblock->next_blocked_mutex = 0;
|
--recursive_lock_count;
|
||||||
context_to_unblock->ctx_thread->my->unblock( context_to_unblock );
|
if (recursive_lock_count != 0)
|
||||||
} else {
|
return;
|
||||||
m_blist = 0;
|
|
||||||
}
|
get_tail(m_blist, context_to_unblock);
|
||||||
|
if( context_to_unblock )
|
||||||
|
{
|
||||||
|
context_to_unblock->next_blocked_mutex = 0;
|
||||||
|
context_to_unblock->ctx_thread->my->unblock( context_to_unblock );
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
m_blist = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // fc
|
} // fc
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue