int ret;
mono_mutex_lock(&sem_mutex);
+
+#ifdef DEBUG
+ g_message(G_GNUC_PRETTY_FUNCTION ": Sem %p val %d ms %d", handle,
+ sem_handle->val, ms);
+#endif
/* Signal this handle after we have obtained the semaphore
* global lock
*/
if(signal!=NULL) {
+#ifdef DEBUG
+ g_message(G_GNUC_PRETTY_FUNCTION ": signalling %p", signal);
+#endif
signal->ops->signal(signal);
}
}
if(ms==INFINITE) {
+#ifdef DEBUG
+ g_message(G_GNUC_PRETTY_FUNCTION ": wait for %p INFINITE",
+ sem_handle);
+#endif
+ try_again_infinite:
ret=mono_cond_wait(&sem_cond, &sem_mutex);
- waited=TRUE;
+ if(ret==0) {
+ /* See if we were signalled (it might have been
+ * another semaphore)
+ */
+ if(sem_handle->val>0) {
+#ifdef DEBUG
+ g_message(G_GNUC_PRETTY_FUNCTION
+ ": sem %p has been signalled",
+ sem_handle);
+#endif
+ waited=TRUE;
+ } else {
+#ifdef DEBUG
+ g_message(G_GNUC_PRETTY_FUNCTION
+ ": sem %p not signalled",
+ sem_handle);
+#endif
+ goto try_again_infinite;
+ }
+ }
} else {
struct timespec timeout;
+#ifdef DEBUG
+ g_message(G_GNUC_PRETTY_FUNCTION ": wait for %p for %d ms",
+ sem_handle, ms);
+#endif
+
_wapi_calc_timeout(&timeout, ms);
+ try_again_timed:
ret=mono_cond_timedwait(&sem_cond, &sem_mutex, &timeout);
if(ret==0) {
- waited=TRUE;
+ /* See if we were signalled (it might have been
+ * another semaphore)
+ */
+ if(sem_handle->val>0) {
+#ifdef DEBUG
+ g_message(G_GNUC_PRETTY_FUNCTION
+ ": sem %p has been signalled",
+ sem_handle);
+#endif
+ waited=TRUE;
+ } else {
+#ifdef DEBUG
+ g_message(G_GNUC_PRETTY_FUNCTION
+ ": sem %p not signalled",
+ sem_handle);
+#endif
+ goto try_again_timed;
+ }
} else {
/* ret might be ETIMEDOUT for timeout, or
* other for error */
end:
if(waited==TRUE) {
sem_handle->val--;
+#ifdef DEBUG
+ g_message(G_GNUC_PRETTY_FUNCTION
+ ": Waited TRUE, sem %p val now %d", sem_handle,
+ sem_handle->val);
+#endif
}
+#ifdef DEBUG
+ else {
+ g_message(G_GNUC_PRETTY_FUNCTION ": Waited FALSE, sem %p",
+ sem_handle);
+ }
+#endif
mono_mutex_unlock(&sem_mutex);
return(waited);
mono_mutex_lock(&sem_mutex);
+
+#ifdef DEBUG
+ g_message(G_GNUC_PRETTY_FUNCTION ": sem %p val %d count %d",
+ sem_handle, sem_handle->val, count);
+#endif
/* Do this before checking for count overflow, because overflowing max
* is a listed technique for finding the current value
sem_handle->val+=count;
pthread_cond_broadcast(&sem_cond);
ret=TRUE;
+
+#ifdef DEBUG
+ g_message(G_GNUC_PRETTY_FUNCTION ": sem %p val now %d", sem_handle,
+ sem_handle->val);
+#endif
end:
mono_mutex_unlock(&sem_mutex);