coapp-packages/pthreads

pthread_cond_wait works only once and doesn't lock mutex

Opened this issue · 0 comments

This example works fine on linux:

#include <stdio.h>
#define PTW32_STATIC_LIB
#define _TIMESPEC_DEFINED
#include <pthread.h>

pthread_mutex_t wait_mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t  wait_cond  = PTHREAD_COND_INITIALIZER;
int do_something = 0;

void * waiter_thread(void* dummy)
{
	printf("Thread started\r\n");

	pthread_mutex_lock(&wait_mutex);

	// Wait for signal #1
	while(do_something == 0)
		pthread_cond_wait(&wait_cond, &wait_mutex);
	printf("Thread shall do something #1\r\n");
	
	// Wait for signal #2
	do_something = 0;
	while(do_something == 0)
		pthread_cond_wait(&wait_cond, &wait_mutex);
	printf("Thread shall do something #2\r\n");
	
	printf("Thread ends\r\n");
	pthread_mutex_unlock(&wait_mutex);

	return NULL;
}

int main()
{
	pthread_t pt;

	pthread_mutex_init(&wait_mutex, NULL);
	pthread_cond_init(&wait_cond, NULL);
	
	printf("Starting thread (press enter so send signal #1)\r\n");
	pthread_create(&pt, NULL, waiter_thread, NULL);
	getchar();
	
	printf("Sending signal #1 (press enter so send signal #2)\r\n");
	pthread_mutex_lock(&wait_mutex);
	do_something = 1;
	pthread_cond_signal(&wait_cond);
	pthread_mutex_unlock(&wait_mutex);
	getchar();
	
	printf("Sending signal #2 (press enter so wait for thread finish)\r\n");
	pthread_mutex_lock(&wait_mutex);
	do_something = 1;
	pthread_cond_signal(&wait_cond);
	pthread_mutex_unlock(&wait_mutex);
	getchar();

	printf("Waiting for thread end\r\n");
	pthread_join(pt, NULL);
	
	printf("Finished\r\n");

	pthread_cond_destroy(&wait_cond);
	pthread_mutex_destroy(&wait_mutex);

	return 0;
}

But with your Windows version of pthreads the program get stuck when trying to signal the thread the second time. It never wakes up, because signaling works only once with your library.
Furthermore the signaled thread doesn't have the mutex locked when running the first time after being signaled. I experienced this while debugging. So there is a short time period where both threads think that they have the mutex locked and running simultaneously. Usually the pthread_cond_wait should wait until the pthread_cond_t is signaled AND it can lock pthread_mutex_t.