c++ - how to prevent deadlock when using wxCRIT_SECT_LOCKER -
i'm writing singleton logger class in c++. class provides logging api multiple threads. make thread safe i'm using wxcrit_sect_locker macro.
say have in logger class following functions (simple example):
void logger::error( string msg ) { wxcrit_sect_locker(adapter_locker, gs_logbuffershield); // such getting/setting class members m_err_cnt++; do_log("error: " + msg); } void logger::warning( string msg ) { wxcrit_sect_locker(adapter_locker, gs_logbuffershield); // such getting/setting class members m_warn_cnt++; do_log("warning: " + msg); } void logger::do_log( string msg ) { wxcrit_sect_locker(adapter_locker, gs_logbuffershield); // such getting/setting class members m_log_cnt++; cout << msg << endl; }
problem:
when logger::warning() called we'll enter critical section twice, once in logger::warning() , 1 more time in *logger::do_log()*.
if agree problem real , can cause deadlock, how can avoid multiple locks (using wxcriticalsection class/macros).
what done create internal apis not take locks called public apis take locks.
void logger::error( string msg ) { wxcrit_sect_locker(adapter_locker, gs_logbuffershield); m_err_cnt++; do_log_internal("error: " + msg); } void logger::warning( string msg ) { wxcrit_sect_locker(adapter_locker, gs_logbuffershield); m_warn_cnt++; do_log_internal("warning: " + msg); } void logger::do_log( string msg ) { wxcrit_sect_locker(adapter_locker, gs_logbuffershield); do_log_internal(msg); } void logger::do_log_internal( string msg ) { m_log_cnt++; cout << msg << endl; }
however, problem, may rather use wxmutex
directly, , use type wxmutex_recursive
when construct it. way, mutex has count. when mutex first locked, count set 1. if same thread grabs mutex again, increments count. releasing mutex decrements count. when count reaches 0, mutex unlocked.
Comments
Post a Comment