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