delorie.com/archives/browse.cgi   search  
Mail Archives: cygwin/2002/04/16/15:03:07

Mailing-List: contact cygwin-help AT cygwin DOT com; run by ezmlm
List-Subscribe: <mailto:cygwin-subscribe AT cygwin DOT com>
List-Archive: <http://sources.redhat.com/ml/cygwin/>
List-Post: <mailto:cygwin AT cygwin DOT com>
List-Help: <mailto:cygwin-help AT cygwin DOT com>, <http://sources.redhat.com/ml/#faqs>
Sender: cygwin-owner AT cygwin DOT com
Mail-Followup-To: cygwin AT cygwin DOT com
Delivered-To: mailing list cygwin AT cygwin DOT com
Message-ID: <000b01c1e579$2c477a90$c07dadcf@homeke6pijupjp>
From: "Michael Labhard" <ince AT pacifier DOT com>
To: <cygwin AT cygwin DOT com>
Subject: pthread_cond_wait does not relock mutex on release
Date: Tue, 16 Apr 2002 12:01:19 -0700
MIME-Version: 1.0
X-Priority: 3
X-MSMail-Priority: Normal
X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2600.0000

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/

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019