sdl

FORK: Simple Directmedia Layer
git clone https://git.neptards.moe/neptards/sdl.git
Log | Files | Refs

testlock.c (3433B)


      1 /*
      2   Copyright (C) 1997-2020 Sam Lantinga <slouken@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 
     23 static SDL_mutex *mutex = NULL;
     24 static SDL_threadID mainthread;
     25 static SDL_Thread *threads[6];
     26 static SDL_atomic_t doterminate;
     27 
     28 /*
     29  * SDL_Quit() shouldn't be used with atexit() directly because
     30  *  calling conventions may differ...
     31  */
     32 static void
     33 SDL_Quit_Wrapper(void)
     34 {
     35     SDL_Quit();
     36 }
     37 
     38 void
     39 printid(void)
     40 {
     41     SDL_Log("Process %lu:  exiting\n", SDL_ThreadID());
     42 }
     43 
     44 void
     45 terminate(int sig)
     46 {
     47     signal(SIGINT, terminate);
     48     SDL_AtomicSet(&doterminate, 1);
     49 }
     50 
     51 void
     52 closemutex(int sig)
     53 {
     54     SDL_threadID id = SDL_ThreadID();
     55     int i;
     56     SDL_Log("Process %lu:  Cleaning up...\n", id == mainthread ? 0 : id);
     57     SDL_AtomicSet(&doterminate, 1);
     58     for (i = 0; i < 6; ++i)
     59         SDL_WaitThread(threads[i], NULL);
     60     SDL_DestroyMutex(mutex);
     61     exit(sig);
     62 }
     63 
     64 int SDLCALL
     65 Run(void *data)
     66 {
     67     if (SDL_ThreadID() == mainthread)
     68         signal(SIGTERM, closemutex);
     69     while (!SDL_AtomicGet(&doterminate)) {
     70         SDL_Log("Process %lu ready to work\n", SDL_ThreadID());
     71         if (SDL_LockMutex(mutex) < 0) {
     72             SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't lock mutex: %s", SDL_GetError());
     73             exit(1);
     74         }
     75         SDL_Log("Process %lu, working!\n", SDL_ThreadID());
     76         SDL_Delay(1 * 1000);
     77         SDL_Log("Process %lu, done!\n", SDL_ThreadID());
     78         if (SDL_UnlockMutex(mutex) < 0) {
     79             SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't unlock mutex: %s", SDL_GetError());
     80             exit(1);
     81         }
     82         /* If this sleep isn't done, then threads may starve */
     83         SDL_Delay(10);
     84     }
     85     if (SDL_ThreadID() == mainthread && SDL_AtomicGet(&doterminate)) {
     86         SDL_Log("Process %lu:  raising SIGTERM\n", SDL_ThreadID());
     87         raise(SIGTERM);
     88     }
     89     return (0);
     90 }
     91 
     92 int
     93 main(int argc, char *argv[])
     94 {
     95     int i;
     96     int maxproc = 6;
     97 
     98     /* Enable standard application logging */
     99     SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO);
    100 
    101     /* Load the SDL library */
    102     if (SDL_Init(0) < 0) {
    103         SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "%s\n", SDL_GetError());
    104         exit(1);
    105     }
    106     atexit(SDL_Quit_Wrapper);
    107 
    108     SDL_AtomicSet(&doterminate, 0);
    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 }