src/thread/nds/SDL_syscond.c
author Ryan C. Gordon <icculus@icculus.org>
Sun, 10 Jan 2010 05:06:03 +0000
changeset 3623 9a73fecd9181
parent 2859 99210400e8b9
child 3697 f7b03b6838cb
permissions -rw-r--r--
Reverted r5460 ... this was merged from 1.2, but was later reverted there.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2735
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
     1
/*
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
     2
    SDL - Simple DirectMedia Layer
2859
99210400e8b9 Updated copyright date
Sam Lantinga <slouken@libsdl.org>
parents: 2735
diff changeset
     3
    Copyright (C) 1997-2009 Sam Lantinga
2735
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
     4
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
     5
    This library is free software; you can redistribute it and/or
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
     6
    modify it under the terms of the GNU Library General Public
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
     7
    License as published by the Free Software Foundation; either
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
     8
    version 2 of the License, or (at your option) any later version.
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
     9
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    10
    This library is distributed in the hope that it will be useful,
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    11
    but WITHOUT ANY WARRANTY; without even the implied warranty of
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    12
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    13
    Library General Public License for more details.
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    14
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    15
    You should have received a copy of the GNU Library General Public
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    16
    License along with this library; if not, write to the Free
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    17
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    18
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    19
    Sam Lantinga
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    20
    slouken@devolution.com
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    21
*/
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    22
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    23
#ifdef SAVE_RCSID
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    24
static char rcsid =
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    25
    "@(#) $Id: SDL_syscond.c,v 1.2 2001/04/26 16:50:18 hercules Exp $";
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    26
#endif
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    27
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    28
/* An implementation of condition variables using semaphores and mutexes */
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    29
/*
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    30
   This implementation borrows heavily from the BeOS condition variable
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    31
   implementation, written by Christopher Tate and Owen Smith.  Thanks!
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    32
 */
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    33
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    34
#include <stdio.h>
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    35
#include <stdlib.h>
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    36
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    37
#include "SDL_error.h"
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    38
#include "SDL_thread.h"
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    39
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    40
struct SDL_cond
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    41
{
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    42
    SDL_mutex *lock;
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    43
    int waiting;
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    44
    int signals;
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    45
    SDL_sem *wait_sem;
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    46
    SDL_sem *wait_done;
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    47
};
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    48
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    49
/* Create a condition variable */
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    50
SDL_cond *
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    51
SDL_CreateCond(void)
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    52
{
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    53
    SDL_cond *cond;
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    54
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    55
    cond = (SDL_cond *) malloc(sizeof(SDL_cond));
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    56
    if (cond) {
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    57
        cond->lock = SDL_CreateMutex();
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    58
        cond->wait_sem = SDL_CreateSemaphore(0);
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    59
        cond->wait_done = SDL_CreateSemaphore(0);
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    60
        cond->waiting = cond->signals = 0;
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    61
        if (!cond->lock || !cond->wait_sem || !cond->wait_done) {
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    62
            SDL_DestroyCond(cond);
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    63
            cond = NULL;
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    64
        }
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    65
    } else {
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    66
        SDL_OutOfMemory();
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    67
    }
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    68
    return (cond);
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    69
}
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    70
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    71
/* Destroy a condition variable */
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    72
void
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    73
SDL_DestroyCond(SDL_cond * cond)
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    74
{
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    75
    if (cond) {
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    76
        if (cond->wait_sem) {
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    77
            SDL_DestroySemaphore(cond->wait_sem);
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    78
        }
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    79
        if (cond->wait_done) {
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    80
            SDL_DestroySemaphore(cond->wait_done);
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    81
        }
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    82
        if (cond->lock) {
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    83
            SDL_DestroyMutex(cond->lock);
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    84
        }
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    85
        free(cond);
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    86
    }
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    87
}
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    88
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    89
/* Restart one of the threads that are waiting on the condition variable */
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    90
int
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    91
SDL_CondSignal(SDL_cond * cond)
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    92
{
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    93
    if (!cond) {
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    94
        SDL_SetError("Passed a NULL condition variable");
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    95
        return -1;
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    96
    }
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    97
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    98
    /* If there are waiting threads not already signalled, then
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    99
       signal the condition and wait for the thread to respond.
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   100
     */
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   101
    SDL_LockMutex(cond->lock);
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   102
    if (cond->waiting > cond->signals) {
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   103
        ++cond->signals;
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   104
        SDL_SemPost(cond->wait_sem);
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   105
        SDL_UnlockMutex(cond->lock);
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   106
        SDL_SemWait(cond->wait_done);
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   107
    } else {
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   108
        SDL_UnlockMutex(cond->lock);
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   109
    }
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   110
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   111
    return 0;
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   112
}
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   113
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   114
/* Restart all threads that are waiting on the condition variable */
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   115
int
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   116
SDL_CondBroadcast(SDL_cond * cond)
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   117
{
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   118
    if (!cond) {
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   119
        SDL_SetError("Passed a NULL condition variable");
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   120
        return -1;
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   121
    }
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   122
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   123
    /* If there are waiting threads not already signalled, then
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   124
       signal the condition and wait for the thread to respond.
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   125
     */
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   126
    SDL_LockMutex(cond->lock);
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   127
    if (cond->waiting > cond->signals) {
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   128
        int i, num_waiting;
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   129
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   130
        num_waiting = (cond->waiting - cond->signals);
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   131
        cond->signals = cond->waiting;
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   132
        for (i = 0; i < num_waiting; ++i) {
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   133
            SDL_SemPost(cond->wait_sem);
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   134
        }
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   135
        /* Now all released threads are blocked here, waiting for us.
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   136
           Collect them all (and win fabulous prizes!) :-)
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   137
         */
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   138
        SDL_UnlockMutex(cond->lock);
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   139
        for (i = 0; i < num_waiting; ++i) {
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   140
            SDL_SemWait(cond->wait_done);
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   141
        }
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   142
    } else {
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   143
        SDL_UnlockMutex(cond->lock);
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   144
    }
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   145
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   146
    return 0;
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   147
}
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   148
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   149
/* Wait on the condition variable for at most 'ms' milliseconds.
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   150
   The mutex must be locked before entering this function!
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   151
   The mutex is unlocked during the wait, and locked again after the wait.
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   152
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   153
Typical use:
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   154
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   155
Thread A:
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   156
	SDL_LockMutex(lock);
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   157
	while ( ! condition ) {
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   158
		SDL_CondWait(cond);
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   159
	}
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   160
	SDL_UnlockMutex(lock);
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   161
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   162
Thread B:
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   163
	SDL_LockMutex(lock);
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   164
	...
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   165
	condition = true;
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   166
	...
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   167
	SDL_UnlockMutex(lock);
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   168
 */
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   169
int
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   170
SDL_CondWaitTimeout(SDL_cond * cond, SDL_mutex * mutex, Uint32 ms)
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   171
{
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   172
    int retval;
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   173
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   174
    if (!cond) {
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   175
        SDL_SetError("Passed a NULL condition variable");
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   176
        return -1;
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   177
    }
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   178
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   179
    /* Obtain the protection mutex, and increment the number of waiters.
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   180
       This allows the signal mechanism to only perform a signal if there
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   181
       are waiting threads.
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   182
     */
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   183
    SDL_LockMutex(cond->lock);
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   184
    ++cond->waiting;
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   185
    SDL_UnlockMutex(cond->lock);
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   186
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   187
    /* Unlock the mutex, as is required by condition variable semantics */
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   188
    SDL_UnlockMutex(mutex);
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   189
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   190
    /* Wait for a signal */
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   191
    if (ms == SDL_MUTEX_MAXWAIT) {
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   192
        retval = SDL_SemWait(cond->wait_sem);
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   193
    } else {
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   194
        retval = SDL_SemWaitTimeout(cond->wait_sem, ms);
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   195
    }
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   196
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   197
    /* Let the signaler know we have completed the wait, otherwise
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   198
       the signaler can race ahead and get the condition semaphore
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   199
       if we are stopped between the mutex unlock and semaphore wait,
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   200
       giving a deadlock.  See the following URL for details:
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   201
       http://www-classic.be.com/aboutbe/benewsletter/volume_III/Issue40.html
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   202
     */
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   203
    SDL_LockMutex(cond->lock);
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   204
    if (cond->signals > 0) {
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   205
        /* If we timed out, we need to eat a condition signal */
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   206
        if (retval > 0) {
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   207
            SDL_SemWait(cond->wait_sem);
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   208
        }
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   209
        /* We always notify the signal thread that we are done */
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   210
        SDL_SemPost(cond->wait_done);
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   211
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   212
        /* Signal handshake complete */
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   213
        --cond->signals;
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   214
    }
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   215
    --cond->waiting;
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   216
    SDL_UnlockMutex(cond->lock);
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   217
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   218
    /* Lock the mutex, as is required by condition variable semantics */
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   219
    SDL_LockMutex(mutex);
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   220
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   221
    return retval;
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   222
}
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   223
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   224
/* Wait on the condition variable forever */
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   225
int
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   226
SDL_CondWait(SDL_cond * cond, SDL_mutex * mutex)
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   227
{
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   228
    return SDL_CondWaitTimeout(cond, mutex, SDL_MUTEX_MAXWAIT);
204be4fc2726 Final merge of Google Summer of Code 2008 work...
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   229
}