This is the mail archive of the cygwin@cygwin.com mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

pthread_cond_wait does not relock mutex on release


Don't no if anyone else has noticed this:  the pthread_cond_wait when
signalled does not lock the associated mutex again.  Thus the expected
output of the attached program should be

create Test
start
bar mutex lock and wait
foo mutex lock
foo mutex lock and signal condition then sleep...
foo mutex unlock                                            <------- Should
be here
bar mutex lock and wait released
bar mutex unlock
end
delete Test

But the actual output is:

create Test
start
bar mutex lock and wait
foo mutex lock
foo mutex lock and signal condition then sleep...
bar mutex lock and wait released
bar mutex unlock
foo mutex unlock                                          <------- But here
instead
end
delete Test


Test program:

#include <stdio.h>
#include <unistd.h>
#include <assert.h>
#include <pthread.h>


struct wait_cond {
 wait_cond();
 ~wait_cond();

 pthread_mutex_t  _mutex;
 pthread_cond_t  _cond;

 bool    _status;
};

wait_cond::wait_cond()
 : _status(false)
{
 int status = ::pthread_mutex_init(&_mutex, 0);
 if( 0 == status )
  status  = ::pthread_cond_init(&_cond, 0);
  if( 0 == status )
   _status = true;
 assert(_status);
}

wait_cond::~wait_cond()
{
 int status = ::pthread_cond_destroy(&_cond);
 assert(0==status);
 status = ::pthread_mutex_destroy(&_mutex);
 assert(0==status);
}


struct Test
{
 Test()
 : _pwait_condition( new wait_cond )
 {
  ::printf("create Test\n");
 }
 ~Test()
 {
  ::printf("delete Test\n");
  delete _pwait_condition;
 }

 void *foo(void*)
 {
  int status = ::pthread_mutex_lock(&(_pwait_condition->_mutex));
  ::printf("foo mutex lock\n");

  status = ::pthread_cond_signal(&(_pwait_condition->_cond));
  ::printf("foo mutex lock and signal condition then sleep...\n");

  ::sleep(1);
  status = ::pthread_mutex_unlock(&(_pwait_condition->_mutex));
  ::printf("foo mutex unlock\n");

  return 0;
 };

 void *bar(void*)
 {
  ::pthread_mutex_lock(&(_pwait_condition->_mutex));
  ::printf("bar mutex lock and wait\n");

  ::pthread_cond_wait(&(_pwait_condition->_cond)
    , &(_pwait_condition->_mutex));
  ::printf("bar mutex lock and wait released\n");

  ::pthread_mutex_unlock(&(_pwait_condition->_mutex));
  ::printf("bar mutex unlock\n");

  return 0;
 };

 wait_cond *_pwait_condition;
};

void * foo(void* pv)
{
 ((Test *)pv)->foo(0);
}

void * bar(void* pv)
{
 ((Test *)pv)->bar(0);
}

int main(char** argc, int argv)
{
 Test test;

 pthread_t t1, t2;

 ::printf("start\n");
 int status = ::pthread_create(&t2, 0, bar, &test);
 assert(0==status);
 status = ::pthread_create(&t1, 0, foo, &test);
 assert(0==status);
 ::sleep(5);
 ::printf("end\n");

 return 0;
}



--
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
Bug reporting:         http://cygwin.com/bugs.html
Documentation:         http://cygwin.com/docs.html
FAQ:                   http://cygwin.com/faq/


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]