upgrade SDL to version 2.0.8
[platform/upstream/SDL.git] / src / timer / SDL_timer.c
index 379b852..f6451c5 100755 (executable)
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2016 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
@@ -24,7 +24,7 @@
 #include "SDL_timer_c.h"
 #include "SDL_atomic.h"
 #include "SDL_cpuinfo.h"
-#include "SDL_thread.h"
+#include "../thread/SDL_systhread.h"
 #include "xf86drm.h"
 #include <fcntl.h>
 
@@ -38,7 +38,7 @@ typedef struct _SDL_Timer
     void *param;
     Uint32 interval;
     Uint32 scheduled;
-    volatile SDL_bool canceled;
+    SDL_atomic_t canceled;
     struct _SDL_Timer *next;
 } SDL_Timer;
 
@@ -63,9 +63,9 @@ typedef struct {
     /* Data used to communicate with the timer thread */
     SDL_SpinLock lock;
     SDL_sem *sem;
-    SDL_Timer * volatile pending;
-    SDL_Timer * volatile freelist;
-    volatile SDL_bool active;
+    SDL_Timer *pending;
+    SDL_Timer *freelist;
+    SDL_atomic_t active;
 
     /* List of timers - this is only touched by the timer thread */
     SDL_Timer *timers;
@@ -103,7 +103,7 @@ SDL_AddTimerInternal(SDL_TimerData *data, SDL_Timer *timer)
     timer->next = curr;
 }
 
-static int
+static int SDLCALL
 SDL_TimerThread(void *_data)
 {
     SDL_TimerData *data = (SDL_TimerData *)_data;
@@ -121,7 +121,7 @@ SDL_TimerThread(void *_data)
     for ( ; ; ) {
 #if defined(__TIZEN__)
         if(data->drm_fd > -1) {
-            if(!data->active)
+            if(!SDL_AtomicGet(&data->active))
                 break;
             if(drmWaitVBlank(data->drm_fd, &(data->vblankInfo)) == 0) {
                 if(data->pending) {
@@ -157,8 +157,10 @@ SDL_TimerThread(void *_data)
             freelist_head = NULL;
             freelist_tail = NULL;
 
+        /* Check to see if we're still running, after maintenance */
+        if (!SDL_AtomicGet(&data->active)) {
+
             /* Check to see if we're still running, after maintenance */
-            if (!data->active) {
                 break;
             }
 
@@ -180,13 +182,16 @@ SDL_TimerThread(void *_data)
                 /* We're going to do something with this timer */
                 data->timers = current->next;
 
-                if (current->canceled) {
-                    interval = 0;
-                } else {
-                    interval = current->callback(current->interval, current->param);
-                }
+            if (SDL_AtomicGet(&current->canceled)) {
+                interval = 0;
+            } else {
+                interval = current->callback(current->interval, current->param);
+            }
+
+            if (interval > 0) {
+                /* Reschedule this timer */
+                current->interval = interval;
 
-                if (interval > 0) {
                     /* Reschedule this timer */
                     current->scheduled = tick + interval;
                     SDL_AddTimerInternal(data, current);
@@ -199,7 +204,7 @@ SDL_TimerThread(void *_data)
                     }
                     freelist_tail = current;
 
-                    current->canceled = SDL_TRUE;
+                    SDL_AtomicSet(&current->canceled, 1);
                 }
             }
 
@@ -228,7 +233,7 @@ SDL_TimerInit(void)
 {
     SDL_TimerData *data = &SDL_timer_data;
 
-    if (!data->active) {
+    if (!SDL_AtomicGet(&data->active)) {
         const char *name = "SDLTimer";
         data->timermap_lock = SDL_CreateMutex();
         if (!data->timermap_lock) {
@@ -241,7 +246,7 @@ SDL_TimerInit(void)
             return -1;
         }
 
-        data->active = SDL_TRUE;
+        SDL_AtomicSet(&data->active, 1);
 
 #if defined(__TIZEN__)
     const char* DRM_DEVICE = "/dev/dri/card0";
@@ -260,16 +265,9 @@ SDL_TimerInit(void)
     }
 #endif
         /* !!! FIXME: this is nasty. */
-#if defined(__WIN32__) && !defined(HAVE_LIBC)
-#undef SDL_CreateThread
-#if SDL_DYNAMIC_API
-        data->thread = SDL_CreateThread_REAL(SDL_TimerThread, name, data, NULL, NULL);
-#else
-        data->thread = SDL_CreateThread(SDL_TimerThread, name, data, NULL, NULL);
-#endif
-#else
-        data->thread = SDL_CreateThread(SDL_TimerThread, name, data);
-#endif
+
+        /* Timer threads use a callback into the app, so we can't set a limited stack size here. */
+        data->thread = SDL_CreateThreadInternal(SDL_TimerThread, name, 0, data);
         if (!data->thread) {
             SDL_TimerQuit();
             return -1;
@@ -287,9 +285,7 @@ SDL_TimerQuit(void)
     SDL_Timer *timer;
     SDL_TimerMap *entry;
 
-    if (data->active) {
-        data->active = SDL_FALSE;
-
+    if (SDL_AtomicCAS(&data->active, 1, 0)) {  /* active? Move to inactive. */
         /* Shutdown the timer thread */
         if (data->thread) {
             SDL_SemPost(data->sem);
@@ -329,21 +325,14 @@ SDL_AddTimer(Uint32 interval, SDL_TimerCallback callback, void *param)
     SDL_Timer *timer;
     SDL_TimerMap *entry;
 
-    if (!data->active) {
-        int status = 0;
-
-        SDL_AtomicLock(&data->lock);
-        if (!data->active) {
-            status = SDL_TimerInit();
-        }
-        SDL_AtomicUnlock(&data->lock);
-
-        if (status < 0) {
+    SDL_AtomicLock(&data->lock);
+    if (!SDL_AtomicGet(&data->active)) {
+        if (SDL_TimerInit() < 0) {
+            SDL_AtomicUnlock(&data->lock);
             return 0;
         }
     }
 
-    SDL_AtomicLock(&data->lock);
     timer = data->freelist;
     if (timer) {
         data->freelist = timer->next;
@@ -364,7 +353,7 @@ SDL_AddTimer(Uint32 interval, SDL_TimerCallback callback, void *param)
     timer->param = param;
     timer->interval = interval;
     timer->scheduled = SDL_GetTicks() + interval;
-    timer->canceled = SDL_FALSE;
+    SDL_AtomicSet(&timer->canceled, 0);
 
     entry = (SDL_TimerMap *)SDL_malloc(sizeof(*entry));
     if (!entry) {
@@ -415,8 +404,8 @@ SDL_RemoveTimer(SDL_TimerID id)
     SDL_UnlockMutex(data->timermap_lock);
 
     if (entry) {
-        if (!entry->timer->canceled) {
-            entry->timer->canceled = SDL_TRUE;
+        if (!SDL_AtomicGet(&entry->timer->canceled)) {
+            SDL_AtomicSet(&entry->timer->canceled, 1);
             canceled = SDL_TRUE;
         }
         SDL_free(entry);