src/thread/win32/SDL_systhread.c
author Sam Lantinga
Sun, 14 Feb 2010 15:16:13 +0000
changeset 3705 794f31fb9505
parent 3697 f7b03b6838cb
child 4426 1bceff8f008f
permissions -rw-r--r--
Fixed compile error using Borland C++
     1 /*
     2     SDL - Simple DirectMedia Layer
     3     Copyright (C) 1997-2010 Sam Lantinga
     4 
     5     This library is free software; you can redistribute it and/or
     6     modify it under the terms of the GNU Lesser General Public
     7     License as published by the Free Software Foundation; either
     8     version 2.1 of the License, or (at your option) any later version.
     9 
    10     This library is distributed in the hope that it will be useful,
    11     but WITHOUT ANY WARRANTY; without even the implied warranty of
    12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    13     Lesser General Public License for more details.
    14 
    15     You should have received a copy of the GNU Lesser General Public
    16     License along with this library; if not, write to the Free Software
    17     Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
    18 
    19     Sam Lantinga
    20     slouken@libsdl.org
    21 */
    22 #include "SDL_config.h"
    23 
    24 /* Win32 thread management routines for SDL */
    25 
    26 #define WIN32_LEAN_AND_MEAN
    27 #include <windows.h>
    28 
    29 #include "SDL_thread.h"
    30 #include "../SDL_thread_c.h"
    31 #include "../SDL_systhread.h"
    32 
    33 #ifndef SDL_PASSED_BEGINTHREAD_ENDTHREAD
    34 #ifndef _WIN32_WCE
    35 /* We'll use the C library from this DLL */
    36 #include <process.h>
    37 #endif
    38 
    39 #if __GNUC__
    40 typedef unsigned long (__cdecl * pfnSDL_CurrentBeginThread) (void *, unsigned,
    41                                                              unsigned
    42                                                              (__stdcall *
    43                                                               func) (void *),
    44                                                              void *arg,
    45                                                              unsigned,
    46                                                              unsigned
    47                                                              *threadID);
    48 typedef void (__cdecl * pfnSDL_CurrentEndThread) (unsigned code);
    49 #elif defined(__WATCOMC__)
    50 /* This is for Watcom targets except OS2 */
    51 #if __WATCOMC__ < 1240
    52 #define __watcall
    53 #endif
    54 typedef unsigned long (__watcall * pfnSDL_CurrentBeginThread) (void *,
    55                                                                unsigned,
    56                                                                unsigned
    57                                                                (__stdcall *
    58                                                                 func) (void
    59                                                                        *),
    60                                                                void *arg,
    61                                                                unsigned,
    62                                                                unsigned
    63                                                                *threadID);
    64 typedef void (__watcall * pfnSDL_CurrentEndThread) (unsigned code);
    65 #else
    66 typedef uintptr_t(__cdecl * pfnSDL_CurrentBeginThread) (void *, unsigned,
    67                                                         unsigned (__stdcall *
    68                                                                   func) (void
    69                                                                          *),
    70                                                         void *arg, unsigned,
    71                                                         unsigned *threadID);
    72 typedef void (__cdecl * pfnSDL_CurrentEndThread) (unsigned code);
    73 #endif
    74 #endif /* !SDL_PASSED_BEGINTHREAD_ENDTHREAD */
    75 
    76 
    77 typedef struct ThreadStartParms
    78 {
    79     void *args;
    80     pfnSDL_CurrentEndThread pfnCurrentEndThread;
    81 } tThreadStartParms, *pThreadStartParms;
    82 
    83 static DWORD __stdcall
    84 RunThread(void *data)
    85 {
    86     pThreadStartParms pThreadParms = (pThreadStartParms) data;
    87     pfnSDL_CurrentEndThread pfnCurrentEndThread = NULL;
    88 
    89     // Call the thread function!
    90     SDL_RunThread(pThreadParms->args);
    91 
    92     // Get the current endthread we have to use!
    93     if (pThreadParms) {
    94         pfnCurrentEndThread = pThreadParms->pfnCurrentEndThread;
    95         SDL_free(pThreadParms);
    96     }
    97     // Call endthread!
    98     if (pfnCurrentEndThread)
    99         (*pfnCurrentEndThread) (0);
   100     return (0);
   101 }
   102 
   103 #ifdef SDL_PASSED_BEGINTHREAD_ENDTHREAD
   104 int
   105 SDL_SYS_CreateThread(SDL_Thread * thread, void *args,
   106                      pfnSDL_CurrentBeginThread pfnBeginThread,
   107                      pfnSDL_CurrentEndThread pfnEndThread)
   108 {
   109 #else
   110 int
   111 SDL_SYS_CreateThread(SDL_Thread * thread, void *args)
   112 {
   113 #ifdef _WIN32_WCE
   114     pfnSDL_CurrentBeginThread pfnBeginThread = NULL;
   115     pfnSDL_CurrentEndThread pfnEndThread = NULL;
   116 #else
   117     pfnSDL_CurrentBeginThread pfnBeginThread = _beginthreadex;
   118     pfnSDL_CurrentEndThread pfnEndThread = _endthreadex;
   119 #endif
   120 #endif /* SDL_PASSED_BEGINTHREAD_ENDTHREAD */
   121     unsigned threadid;
   122     pThreadStartParms pThreadParms =
   123         (pThreadStartParms) SDL_malloc(sizeof(tThreadStartParms));
   124     if (!pThreadParms) {
   125         SDL_OutOfMemory();
   126         return (-1);
   127     }
   128     // Save the function which we will have to call to clear the RTL of calling app!
   129     pThreadParms->pfnCurrentEndThread = pfnEndThread;
   130     // Also save the real parameters we have to pass to thread function
   131     pThreadParms->args = args;
   132 
   133     if (pfnBeginThread) {
   134         thread->handle =
   135             (SYS_ThreadHandle) pfnBeginThread(NULL, 0, RunThread,
   136                                               pThreadParms, 0, &threadid);
   137     } else {
   138         thread->handle =
   139             CreateThread(NULL, 0, RunThread, pThreadParms, 0, &threadid);
   140     }
   141     if (thread->handle == NULL) {
   142         SDL_SetError("Not enough resources to create thread");
   143         return (-1);
   144     }
   145     return (0);
   146 }
   147 
   148 void
   149 SDL_SYS_SetupThread(void)
   150 {
   151     return;
   152 }
   153 
   154 SDL_threadID
   155 SDL_ThreadID(void)
   156 {
   157     return ((SDL_threadID) GetCurrentThreadId());
   158 }
   159 
   160 void
   161 SDL_SYS_WaitThread(SDL_Thread * thread)
   162 {
   163     WaitForSingleObject(thread->handle, INFINITE);
   164     CloseHandle(thread->handle);
   165 }
   166 
   167 /* vi: set ts=4 sw=4 expandtab: */