test/testlock.c
author Ryan C. Gordon <icculus@icculus.org>
Tue, 22 Jul 2014 21:41:49 -0400
changeset 9012 aa058c87737b
parent 8149 681eb46b8ac4
child 9356 e87d6e1e812a
permissions -rw-r--r--
Added audio device buffer queueing API.
slouken@5535
     1
/*
slouken@8149
     2
  Copyright (C) 1997-2014 Sam Lantinga <slouken@libsdl.org>
slouken@5535
     3
slouken@5535
     4
  This software is provided 'as-is', without any express or implied
slouken@5535
     5
  warranty.  In no event will the authors be held liable for any damages
slouken@5535
     6
  arising from the use of this software.
slouken@5535
     7
slouken@5535
     8
  Permission is granted to anyone to use this software for any purpose,
slouken@5535
     9
  including commercial applications, and to alter it and redistribute it
slouken@5535
    10
  freely.
slouken@5535
    11
*/
slouken@0
    12
slouken@7191
    13
/* Test the thread and mutex locking functions
slouken@0
    14
   Also exercises the system's signal/thread interaction
slouken@0
    15
*/
slouken@0
    16
slouken@0
    17
#include <signal.h>
slouken@0
    18
#include <stdio.h>
philipp@7442
    19
#include <stdlib.h> /* for atexit() */
slouken@0
    20
slouken@0
    21
#include "SDL.h"
slouken@0
    22
#include "SDL_mutex.h"
slouken@0
    23
#include "SDL_thread.h"
slouken@0
    24
slouken@0
    25
static SDL_mutex *mutex = NULL;
slouken@3578
    26
static SDL_threadID mainthread;
slouken@0
    27
static SDL_Thread *threads[6];
slouken@1769
    28
static volatile int doterminate = 0;
slouken@0
    29
icculus@1151
    30
/*
icculus@1151
    31
 * SDL_Quit() shouldn't be used with atexit() directly because
icculus@1151
    32
 *  calling conventions may differ...
icculus@1151
    33
 */
slouken@1895
    34
static void
slouken@1895
    35
SDL_Quit_Wrapper(void)
icculus@1151
    36
{
slouken@1895
    37
    SDL_Quit();
icculus@1151
    38
}
icculus@1151
    39
slouken@1895
    40
void
slouken@1895
    41
printid(void)
slouken@0
    42
{
aschiffler@7639
    43
    SDL_Log("Process %lu:  exiting\n", SDL_ThreadID());
slouken@0
    44
}
slouken@0
    45
slouken@1895
    46
void
slouken@1895
    47
terminate(int sig)
slouken@0
    48
{
slouken@1895
    49
    signal(SIGINT, terminate);
slouken@1895
    50
    doterminate = 1;
slouken@1895
    51
}
slouken@0
    52
slouken@1895
    53
void
slouken@1895
    54
closemutex(int sig)
slouken@1895
    55
{
slouken@3578
    56
    SDL_threadID id = SDL_ThreadID();
slouken@1895
    57
    int i;
aschiffler@7639
    58
    SDL_Log("Process %lu:  Cleaning up...\n", id == mainthread ? 0 : id);
slouken@2779
    59
    doterminate = 1;
slouken@1895
    60
    for (i = 0; i < 6; ++i)
slouken@2779
    61
        SDL_WaitThread(threads[i], NULL);
slouken@1895
    62
    SDL_DestroyMutex(mutex);
slouken@1895
    63
    exit(sig);
slouken@1895
    64
}
slouken@0
    65
slouken@1895
    66
int SDLCALL
slouken@1895
    67
Run(void *data)
slouken@1895
    68
{
slouken@1895
    69
    if (SDL_ThreadID() == mainthread)
slouken@1895
    70
        signal(SIGTERM, closemutex);
slouken@2779
    71
    while (!doterminate) {
aschiffler@7639
    72
        SDL_Log("Process %lu ready to work\n", SDL_ThreadID());
slouken@6977
    73
        if (SDL_LockMutex(mutex) < 0) {
aschiffler@7639
    74
            SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't lock mutex: %s", SDL_GetError());
slouken@1895
    75
            exit(1);
slouken@1895
    76
        }
aschiffler@7639
    77
        SDL_Log("Process %lu, working!\n", SDL_ThreadID());
slouken@1895
    78
        SDL_Delay(1 * 1000);
aschiffler@7639
    79
        SDL_Log("Process %lu, done!\n", SDL_ThreadID());
slouken@6977
    80
        if (SDL_UnlockMutex(mutex) < 0) {
aschiffler@7639
    81
            SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't unlock mutex: %s", SDL_GetError());
slouken@1895
    82
            exit(1);
slouken@1895
    83
        }
slouken@1895
    84
        /* If this sleep isn't done, then threads may starve */
slouken@1895
    85
        SDL_Delay(10);
slouken@2779
    86
    }
slouken@2779
    87
    if (SDL_ThreadID() == mainthread && doterminate) {
aschiffler@7639
    88
        SDL_Log("Process %lu:  raising SIGTERM\n", SDL_ThreadID());
slouken@2779
    89
        raise(SIGTERM);
slouken@1895
    90
    }
slouken@1895
    91
    return (0);
slouken@1895
    92
}
slouken@0
    93
slouken@1895
    94
int
slouken@1895
    95
main(int argc, char *argv[])
slouken@1895
    96
{
slouken@1895
    97
    int i;
slouken@1895
    98
    int maxproc = 6;
slouken@0
    99
aschiffler@7639
   100
	/* Enable standard application logging */
aschiffler@7639
   101
    SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO);
aschiffler@7639
   102
slouken@1895
   103
    /* Load the SDL library */
slouken@1895
   104
    if (SDL_Init(0) < 0) {
aschiffler@7639
   105
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "%s\n", SDL_GetError());
slouken@1895
   106
        exit(1);
slouken@1895
   107
    }
slouken@1895
   108
    atexit(SDL_Quit_Wrapper);
slouken@1895
   109
slouken@1895
   110
    if ((mutex = SDL_CreateMutex()) == NULL) {
aschiffler@7639
   111
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create mutex: %s\n", SDL_GetError());
slouken@1895
   112
        exit(1);
slouken@1895
   113
    }
slouken@1895
   114
slouken@1895
   115
    mainthread = SDL_ThreadID();
aschiffler@7639
   116
    SDL_Log("Main thread: %lu\n", mainthread);
slouken@1895
   117
    atexit(printid);
slouken@1895
   118
    for (i = 0; i < maxproc; ++i) {
icculus@5969
   119
        char name[64];
icculus@5969
   120
        SDL_snprintf(name, sizeof (name), "Worker%d", i);
icculus@5969
   121
        if ((threads[i] = SDL_CreateThread(Run, name, NULL)) == NULL)
aschiffler@7639
   122
            SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create thread!\n");
slouken@1895
   123
    }
slouken@1895
   124
    signal(SIGINT, terminate);
slouken@1895
   125
    Run(NULL);
slouken@1895
   126
slouken@1895
   127
    return (0);                 /* Never reached */
slouken@0
   128
}