Mailing Lists: Apple Mailing Lists
Image of Mac OS face in stamp
Re: Delayed Events
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Delayed Events




On Sep 21, 2004, at 7:13 AM, Philippe Wicker wrote:

Oops. Made a "little" error in the code. Corrections below :)


On Sep 21, 2004, at 3:01 AM, Angelo Fraietta wrote:

I originally developed an application in Jaguar (using GCC) that used events and threads. I had the event working so it would wait for an event for a period of time, and if it did not receive it, it would return false.

wait_ret = pthread_cond_timedwait(&_eventId, &count_mutex, &tv);

Maybe your condvar code has been stripped. If this is not the case then it is incorrect.
A condition variable must be associated with a predicate (a logical condition which may range from a simple boolean to a complex state that can be evaluated to true or false). The predicate is used as follows:


At signaler side:
pthread_mutex_lock(&count_mutex);
// set the predicate: eg increment a counter
pthread_mutex_unlock(&count_mutex);
pthread_cond_signal(&_eventId); // This call may (but do not need to) be within the lock/unlock


At waiter side:
	pthread_mutex_lock(&count_mutex);
	while (/* predicate evaluates to false */) {
		wait_ret = pthread_cond_timedwait (&_eventId, &count_mutex, &tv);
		if (wait_ret  == EINVAL) {
			// bad parameter to pthread_cond_timedwait -> some error processing
			pthread_mutex_unlock(&count_mutex);
			break;  // Note the break here
		}
		else if (wait_ret  == ETIMEDOUT) {
			// guess ...
			pthread_mutex_unlock(&count_mutex);
		}
		else if (wait_ret  == 0) {
			// The tricky point: 0 means signaled *OR* spurious wake up. That's
			// why you need to check the predicate in a while loop.
			// Update the predicate: eg decrement the counter.
			pthread_mutex_unlock(&count_mutex);
		}
		else {
			// Extremely defensive code: should never happen :))
			pthread_mutex_unlock(&count_mutex);
		}
	}
	if (wait_ret == 0) .... etc ... process your event ...

Corrected (and simplified) code:

pthread_mutex_lock(&count_mutex);
while (/* predicate evaluates to false */) {
wait_ret = pthread_cond_timedwait (&_eventId, &count_mutex, &tv);
if (wait_ret == 0) {
// The tricky point: 0 means signaled *OR* spurious wake up. That's
// why you need to check the predicate in a while loop.
}
else {
break;
}
}
if (wait_ret == 0) {
// Update the predicate: eg decrement the counter. It must be done outside the loop.
// That was the error in the original code.
}
pthread_mutex_unlock(&count_mutex);


// Check again wait_ret and process your event, your timeout or the error ...



A condition variable has no memory (state) associated with it. Its state role is played by the predicate. It cannot remember that it has been signaled. A call to pthread_cond_signal while no thread is waiting is simply lost in a black hole. that's why you need to check the predicate before calling pthread_cond_timedwait. Additionaly, pthread_cond_timedwait and pthread_cond_wait may spuriously wake up (especially in a multi-processor environment but not only), that's why it is *ABSOLUTELY* necessary to check the predicate after the return. Hence the while loop.


Any modification (set or update) of the predicate *must* be done while the mutex is locked.

Regards.


The thread could be released by another thread as follows

pthread_mutex_lock(&count_mutex);
pthread_cond_signal(&_eventId);
pthread_mutex_unlock(&count_mutex);

This all worked fine until I upgraded to Panther. Now what happens is that the thread that is waiting for the event does not continue immediately after receiving the event.

For example, if I had the thread wait for 2 seconds for the event and had the other thread set the event after half a second, the thread that waited for the event does not continue immediately. The call to pthread_cond_timedwait, however, returns successful.

My code is compiled as part of a JNI library being called by a Java GUI

Any suggestions?

--
Angelo Fraietta

PO Box 859
Hamilton NSW 2303

Home Page


http://www.users.bigpond.com/angelo_f/

There are those who seek knowledge for the sake of knowledge - that is CURIOSITY
There are those who seek knowledge to be known by others - that is VANITY
There are those who seek knowledge in order to serve - that is LOVE
Bernard of Clairvaux (1090 - 1153)




_______________________________________________
Do not post admin requests to the list. They will be ignored.
Mt-smp mailing list      (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden


Philippe Wicker
email@hidden


_______________________________________________ Do not post admin requests to the list. They will be ignored. Mt-smp mailing list (email@hidden) Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden


Philippe Wicker
email@hidden


_______________________________________________ Do not post admin requests to the list. They will be ignored. Mt-smp mailing list (email@hidden) Help/Unsubscribe/Update your Subscription: This email sent to email@hidden
References: 
 >Delayed Events (From: Angelo Fraietta <email@hidden>)
 >Re: Delayed Events (From: Philippe Wicker <email@hidden>)



Visit the Apple Store online or at retail locations.
1-800-MY-APPLE

Contact Apple | Terms of Use | Privacy Policy

Copyright © 2011 Apple Inc. All rights reserved.