c++ - What is the race condition in this code? -
the following implementation of sleepconditionvariablecs
, wakeallconditionvariable
, , thread creation functions. problem when try create thread creating thread gets stuck on waitforsingleobject( cv->mut, infinite );
in sleepconditionvariablecs
. cant figure out race condition here is.
typedef struct { int waiters_count; handle sema_; handle mut; } condition_variable; void sleepconditionvariablecs(condition_variable *cv, critical_section *cs, int32_t dwmilliseconds){ waitforsingleobject( cv->mut, infinite ); //acuire object lock cv->waiters_count++; leavecriticalsection (cs); if (signalobjectandwait(cv->mut, cv->sema_, dwmilliseconds, false) == wait_timeout){ //signalobjectandwait releases lock cv->waiters_count--; } entercriticalsection(cs); } void wakeallconditionvariable(condition_variable *cv){ waitforsingleobject( cv->mut, infinite ); while (cv->waiters_count > 0){ cv->waiters_count = cv->waiters_count - 1; releasesemaphore (cv->sema_, 1, 0); } releasemutex(cv->mut); } void kernelthread_creationwait(void *kthread){ kernelthread *thread = (kernelthread *) kthread; entercriticalsection(thread->lock); thread->state = thread_created; wakeallconditionvariable(thread->condition_variable); leavecriticalsection(thread->lock); kernelthread_main(kthread); } kernelthread* createkernelthread(){ eventhandler_gethandler(); unsigned long threadid; int t; void *hand; kernelthread *thread = kernelthread_malloc(); entercriticalsection(thread->lock); thread->state = thread_waitingforcreation; hand = createthread(null, 0, // security, stack size (lpthread_start_routine)&kernelthread_creationwait, // start (void *)thread, 0, &threadid); // param, creation flags, id if (hand == null){ printf("error: return handle createthread() null\n"); exit(-1); } thread->thread = hand; thread->thread_id = threadid; sleepconditionvariablecs(thread->condition_variable,thread->lock,infinite); leavecriticalsection(thread->lock); return thread; } void initializeconditionvariable (condition_variable *cv){ cv->waiters_count = 0; cv->sema_ = createsemaphore (null, // no security 0, // 0 0x7fffffff, // max count null); // unnamed cv->mut = createmutex( null, // default security attributes false, // not owned null); // unnamed mutex }
check out following detailed analysis of gotchas when trying implement pthread-style condition variables using win32 apis. http://www.cs.wustl.edu/~schmidt/win32-cv-1.html. (section 3.4, in particular).
in code see 1 problem @ moment. in sleepconditionvariablecs()
:
leavecriticalsection (cs); if (signalobjectandwait(cv->mut, cv->sema_, dwmilliseconds, false) == wait_timeout){ //signalobjectandwait releases lock // right here have not acquired cv->mut cv->waiters_count--; // data race (with cv->waiters_count uses in wakeallconditionvariable() }
Comments
Post a Comment