Mailing-List: contact cygwin-help AT cygwin DOT com; run by ezmlm List-Subscribe: List-Archive: List-Post: List-Help: , Sender: cygwin-owner AT cygwin DOT com Mail-Followup-To: cygwin AT cygwin DOT com Delivered-To: mailing list cygwin AT cygwin DOT com From: "Gerald S. Williams" To: Subject: RE: pthread_cond_wait does not relock mutex on release Date: Wed, 17 Apr 2002 10:04:20 -0400 Message-ID: MIME-Version: 1.0 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: 7bit X-Priority: 3 (Normal) X-MSMail-Priority: Normal Importance: Normal In-Reply-To: <000b01c1e579$2c477a90$c07dadcf@homeke6pijupjp> X-MimeOLE: Produced By Microsoft MimeOLE V5.50.4807.1700 Independent of any other issues, the test case is wrong. Specifically, pthread_cond_wait is allowed to spuriously return (it's in the standard that way). You do have the lock, though. That allows you to look at the variable and determine if this was a spurious signal. You have to wrap cond_wait with a check of the associated variable (which would have to be set when you signalled it). In other words, this: > 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; > }; should become something like this: void *foo(void*) { int status = ::pthread_mutex_lock(&(_pwait_condition->_mutex)); ::printf("foo mutex lock\n"); _pwait_condition->_status = false; 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"); while (_pwait_condition->_status) { ::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; }; That could cause the results you are seeing. Or it could be something much simpler. Calling printf simultaneously from multiple threads can mess up the output. Mine was really strange for this program. You might want to try adding this to the top of your program: #include void SAFE_PRINTF(char *format,...) { va_list vargs; static pthread_mutex_t printMutex; static int initialized = 0; /* OK as long as printf is called in single-threaded context first: */ if (!initialized) { int status = pthread_mutex_init(&printMutex, 0); assert(0==status); initialized = 1; } pthread_mutex_lock(&printMutex); va_start(vargs,format); vprintf(format,vargs); va_end(vargs); pthread_mutex_unlock(&printMutex); } #define printf SAFE_PRINTF I get the following output after changing printf: 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 foo mutex unlock bar mutex unlock end delete Test That is still not exactly what you expected, but makes sense since foo()'s printf is racing the two in bar(). (I.e., bar() gets to run before foo()'s mutex_unlock() returns, then foo() gets to run while bar() is unlocking the mutex again.) -Jerry -O Gerald S. Williams, 55A-134A-E : mailto:gsw AT agere DOT com O- -O AGERE SYSTEMS, 6755 SNOWDRIFT RD : office:610-712-8661 O- -O ALLENTOWN, PA, USA 18106-9353 : mobile:908-672-7592 O- -- 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/