thread_win32.c

Go to the documentation of this file.
00001 /*
00002  * MUSCLE SmartCard Development ( http://www.linuxnet.com )
00003  *
00004  * Copyright (C) 2003
00005  *  Jamie Nicolson / Netscape Communications Corporation
00006  *
00007  * $Id: thread_win32.c 1421 2005-04-12 12:09:21Z rousseau $
00008  */
00009 
00015 #include "config.h"
00016 #include "thread_generic.h"
00017 #include <assert.h>
00018 
00022 int
00023 SYS_MutexInit(CRITICAL_SECTION *mutex)
00024 {
00025     InitializeCriticalSection(mutex);
00026     return 1;
00027 }
00028 
00029 
00033 int
00034 SYS_MutexDestroy(CRITICAL_SECTION *mutex)
00035 {
00036     DeleteCriticalSection(mutex);
00037     return 1;
00038 }
00039 
00043 int
00044 SYS_MutexLock(CRITICAL_SECTION *mutex)
00045 {
00046     EnterCriticalSection(mutex);
00047     return 1;
00048 }
00049 
00053 int
00054 SYS_MutexUnLock(CRITICAL_SECTION *mutex)
00055 {
00056     LeaveCriticalSection(mutex);
00057     return 1;
00058 }
00059 
00060 /*
00061  * Our thread start routine has the prototype:
00062  *
00063  *     void *(*start_routine)(void *arg);
00064  *
00065  * which is different from the prototype for the start routine of a
00066  * Win32 thread:
00067  *
00068  *     DWORD WINAPI (*start_routine)(void *arg);
00069  *
00070  * I don't know what WINAPI means. Assuming we can ignore that, the
00071  * difference between the two prototypes is the return type.  On
00072  * 64-bit Windows, void * is 64-bit but DWORD is 32-bit.
00073  *
00074  * The current implementation should work on 32-bit Windows. If we
00075  * want the code to be portable, we need to define PCSCLITE_THREAD_T
00076  * as a structure:
00077  *
00078  *     typedef struct {
00079  *         HANDLE handle;
00080  *         void *(start_routine)(void *);
00081  *         void *arg;
00082  *         void *rv;
00083  *     } PCSCLITE_THREAD_T;
00084  *
00085  * and define a Win32 thread start routine wrapper like this:
00086  *
00087  *     static DWORD WINAPI Win32StartRoutine(void *arg)
00088  *     {
00089  *         PCSCLITE_THREAD_T *thread = (PCSCLITE_THREAD_T *)arg;
00090  *         thread->rv = thread->start_routine(thread->arg);
00091  *         return 0;
00092  *     }
00093  */
00094 
00098 int
00099 SYS_ThreadCreate(HANDLE *thread, int attributes,
00100     void* start_routine, void* arg)
00101 {
00102 
00103     *thread = CreateThread(
00104                 NULL,       /* thread is not inheritable by child processes */
00105                 0,          /* default stack size */
00106                 start_routine,
00107                 arg,
00108                 0,          /* no flags */
00109                 NULL        /* don't receive thread ID */
00110               );
00111 
00112     if( *thread == NULL ) {
00113         return 0;
00114     } else {
00115         return 1;
00116     }
00117 }
00118 
00122 int
00123 SYS_ThreadJoin(HANDLE *thread, void **retval)
00124 {
00125     DWORD status;
00126     BOOL rv;
00127 
00128     /* go to sleep waiting for the thread to exit */
00129     if( WaitForSingleObject(*thread, INFINITE) == WAIT_FAILED ) {
00130         return 0;
00131     }
00132     if( retval != NULL ) {
00133         rv = GetExitCodeThread(*thread, &status);
00134         if( rv == 0 ) {
00135             /* the call failed */
00136             return 0;
00137         }
00138         *retval = (void *)status;
00139     }
00140     /* success */
00141     CloseHandle(*thread);
00142     *thread = NULL;
00143     return 1;
00144 }
00145 
00146 int
00147 SYS_ThreadExit(void* arg)
00148 {
00149     DWORD status;
00150 
00151     status = (DWORD)arg;  /* FIXME: will truncate on 64-bit Windows */
00152     ExitThread(status);
00153 
00154     /* should not get here--we just exited the thread! */
00155     assert(0);
00156 
00157     return 0;
00158 }

Generated on Wed Jul 14 18:43:52 2010 for pcsc-lite by  doxygen 1.4.7