src/thread/psp/SDL_syscond.c
author Sam Lantinga <slouken@libsdl.org>
Wed, 10 Jul 2013 21:57:31 -0700
changeset 7396 a36ab6149a10
parent 7037 3fedf1f25b94
child 8093 b43765095a6f
permissions -rw-r--r--
Fixed bug 1953 - Crash at memcpy X11_DispatchEvent(_THIS) Function Nitz In Function X11_DispatchEvent(_THIS), case SelectionNotify : static void X11_DispatchEvent(_THIS) { // Some Code case SelectionNotify: { //Some Code SDL_bool expect_lf = SDL_FALSE; char *start = NULL; // Initialised with NULL char *scan = (char*)p.data; char *fn; char *uri; int length = 0; while (p.count--) { if (!expect_lf) { if (*scan==0x0D) { expect_lf = SDL_TRUE; } else if(start == NULL) { start = scan; length = 0; } length++; } else { if (*scan==0x0A && length>0) { uri = malloc(length--); memcpy(uri, start, length); // Problem is Here, start is still NULL if control comes to else statement without initialising the start pointer, which is wrong uri[length] = 0; fn = X11_URIToLocal(uri); if (fn) SDL_SendDropFile(fn); free(uri); } expect_lf = SDL_FALSE; start = NULL; } scan++; } } As shown above how start pointer remains NULL, Patch for this issue would be: if (*scan==0x0D) { expect_lf = SDL_TRUE; } if(start == NULL) { start = scan; length = 0; } Just replace else if statement with if.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
7009
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
     1
/*
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
     2
  Simple DirectMedia Layer
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
     3
  Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
     4
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
     5
  This software is provided 'as-is', without any express or implied
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
     6
  warranty.  In no event will the authors be held liable for any damages
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
     7
  arising from the use of this software.
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
     8
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
     9
  Permission is granted to anyone to use this software for any purpose,
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
    10
  including commercial applications, and to alter it and redistribute it
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
    11
  freely, subject to the following restrictions:
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
    12
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
    13
  1. The origin of this software must not be misrepresented; you must not
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
    14
     claim that you wrote the original software. If you use this software
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
    15
     in a product, an acknowledgment in the product documentation would be
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
    16
     appreciated but is not required.
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
    17
  2. Altered source versions must be plainly marked as such, and must not be
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
    18
     misrepresented as being the original software.
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
    19
  3. This notice may not be removed or altered from any source distribution.
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
    20
*/
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
    21
#include "SDL_config.h"
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
    22
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
    23
/* An implementation of condition variables using semaphores and mutexes */
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
    24
/*
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
    25
   This implementation borrows heavily from the BeOS condition variable
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
    26
   implementation, written by Christopher Tate and Owen Smith.  Thanks!
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
    27
 */
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
    28
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
    29
#include "SDL_thread.h"
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
    30
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
    31
struct SDL_cond
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
    32
{
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
    33
    SDL_mutex *lock;
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
    34
    int waiting;
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
    35
    int signals;
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
    36
    SDL_sem *wait_sem;
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
    37
    SDL_sem *wait_done;
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
    38
};
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
    39
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
    40
/* Create a condition variable */
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
    41
SDL_cond *
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
    42
SDL_CreateCond(void)
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
    43
{
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
    44
    SDL_cond *cond;
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
    45
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
    46
    cond = (SDL_cond *) SDL_malloc(sizeof(SDL_cond));
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
    47
    if (cond) {
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
    48
        cond->lock = SDL_CreateMutex();
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
    49
        cond->wait_sem = SDL_CreateSemaphore(0);
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
    50
        cond->wait_done = SDL_CreateSemaphore(0);
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
    51
        cond->waiting = cond->signals = 0;
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
    52
        if (!cond->lock || !cond->wait_sem || !cond->wait_done) {
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
    53
            SDL_DestroyCond(cond);
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
    54
            cond = NULL;
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
    55
        }
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
    56
    } else {
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
    57
        SDL_OutOfMemory();
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
    58
    }
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
    59
    return (cond);
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
    60
}
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
    61
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
    62
/* Destroy a condition variable */
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
    63
void
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
    64
SDL_DestroyCond(SDL_cond * cond)
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
    65
{
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
    66
    if (cond) {
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
    67
        if (cond->wait_sem) {
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
    68
            SDL_DestroySemaphore(cond->wait_sem);
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
    69
        }
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
    70
        if (cond->wait_done) {
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
    71
            SDL_DestroySemaphore(cond->wait_done);
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
    72
        }
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
    73
        if (cond->lock) {
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
    74
            SDL_DestroyMutex(cond->lock);
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
    75
        }
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
    76
        SDL_free(cond);
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
    77
    }
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
    78
}
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
    79
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
    80
/* Restart one of the threads that are waiting on the condition variable */
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
    81
int
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
    82
SDL_CondSignal(SDL_cond * cond)
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
    83
{
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
    84
    if (!cond) {
7037
3fedf1f25b94 Make SDL_SetError and friends unconditionally return -1.
Ryan C. Gordon <icculus@icculus.org>
parents: 7009
diff changeset
    85
        return SDL_SetError("Passed a NULL condition variable");
7009
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
    86
    }
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
    87
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
    88
    /* If there are waiting threads not already signalled, then
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
    89
       signal the condition and wait for the thread to respond.
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
    90
     */
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
    91
    SDL_LockMutex(cond->lock);
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
    92
    if (cond->waiting > cond->signals) {
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
    93
        ++cond->signals;
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
    94
        SDL_SemPost(cond->wait_sem);
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
    95
        SDL_UnlockMutex(cond->lock);
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
    96
        SDL_SemWait(cond->wait_done);
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
    97
    } else {
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
    98
        SDL_UnlockMutex(cond->lock);
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
    99
    }
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
   100
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
   101
    return 0;
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
   102
}
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
   103
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
   104
/* Restart all threads that are waiting on the condition variable */
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
   105
int
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
   106
SDL_CondBroadcast(SDL_cond * cond)
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
   107
{
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
   108
    if (!cond) {
7037
3fedf1f25b94 Make SDL_SetError and friends unconditionally return -1.
Ryan C. Gordon <icculus@icculus.org>
parents: 7009
diff changeset
   109
        return SDL_SetError("Passed a NULL condition variable");
7009
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
   110
    }
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
   111
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
   112
    /* If there are waiting threads not already signalled, then
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
   113
       signal the condition and wait for the thread to respond.
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
   114
     */
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
   115
    SDL_LockMutex(cond->lock);
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
   116
    if (cond->waiting > cond->signals) {
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
   117
        int i, num_waiting;
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
   118
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
   119
        num_waiting = (cond->waiting - cond->signals);
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
   120
        cond->signals = cond->waiting;
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
   121
        for (i = 0; i < num_waiting; ++i) {
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
   122
            SDL_SemPost(cond->wait_sem);
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
   123
        }
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
   124
        /* Now all released threads are blocked here, waiting for us.
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
   125
           Collect them all (and win fabulous prizes!) :-)
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
   126
         */
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
   127
        SDL_UnlockMutex(cond->lock);
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
   128
        for (i = 0; i < num_waiting; ++i) {
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
   129
            SDL_SemWait(cond->wait_done);
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
   130
        }
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
   131
    } else {
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
   132
        SDL_UnlockMutex(cond->lock);
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
   133
    }
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
   134
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
   135
    return 0;
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
   136
}
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
   137
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
   138
/* Wait on the condition variable for at most 'ms' milliseconds.
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
   139
   The mutex must be locked before entering this function!
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
   140
   The mutex is unlocked during the wait, and locked again after the wait.
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
   141
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
   142
Typical use:
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
   143
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
   144
Thread A:
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
   145
    SDL_LockMutex(lock);
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
   146
    while ( ! condition ) {
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
   147
        SDL_CondWait(cond, lock);
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
   148
    }
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
   149
    SDL_UnlockMutex(lock);
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
   150
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
   151
Thread B:
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
   152
    SDL_LockMutex(lock);
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
   153
    ...
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
   154
    condition = true;
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
   155
    ...
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
   156
    SDL_CondSignal(cond);
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
   157
    SDL_UnlockMutex(lock);
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
   158
 */
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
   159
int
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
   160
SDL_CondWaitTimeout(SDL_cond * cond, SDL_mutex * mutex, Uint32 ms)
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
   161
{
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
   162
    int retval;
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
   163
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
   164
    if (!cond) {
7037
3fedf1f25b94 Make SDL_SetError and friends unconditionally return -1.
Ryan C. Gordon <icculus@icculus.org>
parents: 7009
diff changeset
   165
        return SDL_SetError("Passed a NULL condition variable");
7009
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
   166
    }
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
   167
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
   168
    /* Obtain the protection mutex, and increment the number of waiters.
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
   169
       This allows the signal mechanism to only perform a signal if there
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
   170
       are waiting threads.
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
   171
     */
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
   172
    SDL_LockMutex(cond->lock);
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
   173
    ++cond->waiting;
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
   174
    SDL_UnlockMutex(cond->lock);
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
   175
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
   176
    /* Unlock the mutex, as is required by condition variable semantics */
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
   177
    SDL_UnlockMutex(mutex);
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
   178
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
   179
    /* Wait for a signal */
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
   180
    if (ms == SDL_MUTEX_MAXWAIT) {
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
   181
        retval = SDL_SemWait(cond->wait_sem);
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
   182
    } else {
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
   183
        retval = SDL_SemWaitTimeout(cond->wait_sem, ms);
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
   184
    }
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
   185
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
   186
    /* Let the signaler know we have completed the wait, otherwise
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
   187
       the signaler can race ahead and get the condition semaphore
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
   188
       if we are stopped between the mutex unlock and semaphore wait,
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
   189
       giving a deadlock.  See the following URL for details:
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
   190
       http://www-classic.be.com/aboutbe/benewsletter/volume_III/Issue40.html
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
   191
     */
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
   192
    SDL_LockMutex(cond->lock);
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
   193
    if (cond->signals > 0) {
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
   194
        /* If we timed out, we need to eat a condition signal */
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
   195
        if (retval > 0) {
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
   196
            SDL_SemWait(cond->wait_sem);
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
   197
        }
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
   198
        /* We always notify the signal thread that we are done */
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
   199
        SDL_SemPost(cond->wait_done);
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
   200
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
   201
        /* Signal handshake complete */
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
   202
        --cond->signals;
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
   203
    }
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
   204
    --cond->waiting;
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
   205
    SDL_UnlockMutex(cond->lock);
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
   206
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
   207
    /* Lock the mutex, as is required by condition variable semantics */
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
   208
    SDL_LockMutex(mutex);
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
   209
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
   210
    return retval;
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
   211
}
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
   212
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
   213
/* Wait on the condition variable forever */
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
   214
int
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
   215
SDL_CondWait(SDL_cond * cond, SDL_mutex * mutex)
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
   216
{
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
   217
    return SDL_CondWaitTimeout(cond, mutex, SDL_MUTEX_MAXWAIT);
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
   218
}
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
   219
161b7b6a5303 Add PSP support
Captain Lex <kimonline@126.com>
parents:
diff changeset
   220
/* vi: set ts=4 sw=4 expandtab: */