upgrade SDL to version 2.0.8
[platform/upstream/SDL.git] / test / testlock.c
1 /*
2   Copyright (C) 1997-2018 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         signal(SIGTERM, closemutex);
70     while (!SDL_AtomicGet(&doterminate)) {
71         SDL_Log("Process %lu ready to work\n", SDL_ThreadID());
72         if (SDL_LockMutex(mutex) < 0) {
73             SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't lock mutex: %s", SDL_GetError());
74             exit(1);
75         }
76         SDL_Log("Process %lu, working!\n", SDL_ThreadID());
77         SDL_Delay(1 * 1000);
78         SDL_Log("Process %lu, done!\n", SDL_ThreadID());
79         if (SDL_UnlockMutex(mutex) < 0) {
80             SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't unlock mutex: %s", SDL_GetError());
81             exit(1);
82         }
83         /* If this sleep isn't done, then threads may starve */
84         SDL_Delay(10);
85     }
86     if (SDL_ThreadID() == mainthread && SDL_AtomicGet(&doterminate)) {
87         SDL_Log("Process %lu:  raising SIGTERM\n", SDL_ThreadID());
88         raise(SIGTERM);
89     }
90     return (0);
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 }