test/testlock.c
author Sam Lantinga <slouken@libsdl.org>
Sun, 07 Jul 2019 09:10:56 -0700
changeset 12928 3c4a4b1077cd
parent 12503 806492103856
permissions -rw-r--r--
Fixed bug 4710 - audio/alsa: avoid configuring hardware parameters with only a single period

Anthony Pesch

The previous code first configured the period size using snd_pcm_hw_par-
ams_set_period_size_near. Then, it further narrowed the configuration
space by calling snd_pcm_hw_params_set_buffer_size_near using a buffer
size of 2 times the _requested_ period size in order to try and get a
configuration with only 2 periods. If the configured period size was
larger than the requested size, the second call could inadvertently
narrow the configuration space to contain only a single period.

Rather than fixing the call to snd_pcm_hw_params_set_buffer_size_near
to use a size of 2 times the configured period size, the code has been
changed to use snd_pcm_hw_params_set_periods_min in order to more
clearly explain the intent.
     1 /*
     2   Copyright (C) 1997-2019 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 }