diff options
Diffstat (limited to 'src/threading.c')
-rw-r--r-- | src/threading.c | 54 |
1 files changed, 26 insertions, 28 deletions
diff --git a/src/threading.c b/src/threading.c index 22d18d4..8966dc6 100644 --- a/src/threading.c +++ b/src/threading.c | |||
@@ -41,9 +41,9 @@ THE SOFTWARE. | |||
41 | #include "threading.h" | 41 | #include "threading.h" |
42 | #include "lua.h" | 42 | #include "lua.h" |
43 | 43 | ||
44 | #if !((defined PLATFORM_WIN32) || (defined PLATFORM_POCKETPC)) | 44 | #if THREADAPI == THREADAPI_PTHREAD |
45 | # include <sys/time.h> | 45 | # include <sys/time.h> |
46 | #endif | 46 | #endif // THREADAPI == THREADAPI_PTHREAD |
47 | 47 | ||
48 | 48 | ||
49 | #if defined(PLATFORM_LINUX) || defined(PLATFORM_CYGWIN) | 49 | #if defined(PLATFORM_LINUX) || defined(PLATFORM_CYGWIN) |
@@ -71,7 +71,7 @@ THE SOFTWARE. | |||
71 | * FAIL is for unexpected API return values - essentially programming | 71 | * FAIL is for unexpected API return values - essentially programming |
72 | * error in _this_ code. | 72 | * error in _this_ code. |
73 | */ | 73 | */ |
74 | #if (defined PLATFORM_WIN32) || (defined PLATFORM_POCKETPC) | 74 | #if THREADAPI == THREADAPI_WINDOWS |
75 | static void FAIL( const char *funcname, int rc ) { | 75 | static void FAIL( const char *funcname, int rc ) { |
76 | fprintf( stderr, "%s() failed! (%d)\n", funcname, rc ); | 76 | fprintf( stderr, "%s() failed! (%d)\n", funcname, rc ); |
77 | #ifdef _MSC_VER | 77 | #ifdef _MSC_VER |
@@ -79,7 +79,7 @@ static void FAIL( const char *funcname, int rc ) { | |||
79 | #endif // _MSC_VER | 79 | #endif // _MSC_VER |
80 | abort(); | 80 | abort(); |
81 | } | 81 | } |
82 | #endif | 82 | #endif // THREADAPI == THREADAPI_WINDOWS |
83 | 83 | ||
84 | 84 | ||
85 | /* | 85 | /* |
@@ -90,7 +90,7 @@ static void FAIL( const char *funcname, int rc ) { | |||
90 | */ | 90 | */ |
91 | time_d now_secs(void) { | 91 | time_d now_secs(void) { |
92 | 92 | ||
93 | #if (defined PLATFORM_WIN32) || (defined PLATFORM_POCKETPC) | 93 | #if THREADAPI == THREADAPI_WINDOWS |
94 | /* | 94 | /* |
95 | * Windows FILETIME values are "100-nanosecond intervals since | 95 | * Windows FILETIME values are "100-nanosecond intervals since |
96 | * January 1, 1601 (UTC)" (MSDN). Well, we'd want Unix Epoch as | 96 | * January 1, 1601 (UTC)" (MSDN). Well, we'd want Unix Epoch as |
@@ -145,7 +145,7 @@ time_d now_secs(void) { | |||
145 | // <= 2.0.2 code | 145 | // <= 2.0.2 code |
146 | return (double)(uli.QuadPart - uli_epoch.QuadPart) / 10000000.0; | 146 | return (double)(uli.QuadPart - uli_epoch.QuadPart) / 10000000.0; |
147 | # endif | 147 | # endif |
148 | #else | 148 | #else // THREADAPI == THREADAPI_PTHREAD |
149 | struct timeval tv; | 149 | struct timeval tv; |
150 | // { | 150 | // { |
151 | // time_t tv_sec; /* seconds since Jan. 1, 1970 */ | 151 | // time_t tv_sec; /* seconds since Jan. 1, 1970 */ |
@@ -156,7 +156,7 @@ time_d now_secs(void) { | |||
156 | assert( rc==0 ); | 156 | assert( rc==0 ); |
157 | 157 | ||
158 | return ((double)tv.tv_sec) + ((tv.tv_usec)/1000) / 1000.0; | 158 | return ((double)tv.tv_sec) + ((tv.tv_usec)/1000) / 1000.0; |
159 | #endif | 159 | #endif // THREADAPI THREADAPI_PTHREAD |
160 | } | 160 | } |
161 | 161 | ||
162 | 162 | ||
@@ -168,7 +168,7 @@ time_d SIGNAL_TIMEOUT_PREPARE( double secs ) { | |||
168 | } | 168 | } |
169 | 169 | ||
170 | 170 | ||
171 | #if !((defined PLATFORM_WIN32) || (defined PLATFORM_POCKETPC)) | 171 | #if THREADAPI == THREADAPI_PTHREAD |
172 | /* | 172 | /* |
173 | * Prepare 'abs_secs' kind of timeout to 'timespec' format | 173 | * Prepare 'abs_secs' kind of timeout to 'timespec' format |
174 | */ | 174 | */ |
@@ -187,7 +187,7 @@ static void prepare_timeout( struct timespec *ts, time_d abs_secs ) { | |||
187 | ts->tv_sec = ts->tv_sec + 1; | 187 | ts->tv_sec = ts->tv_sec + 1; |
188 | } | 188 | } |
189 | } | 189 | } |
190 | #endif | 190 | #endif // THREADAPI == THREADAPI_PTHREAD |
191 | 191 | ||
192 | 192 | ||
193 | /*---=== Threading ===---*/ | 193 | /*---=== Threading ===---*/ |
@@ -230,7 +230,7 @@ static void prepare_timeout( struct timespec *ts, time_d abs_secs ) { | |||
230 | # endif | 230 | # endif |
231 | #endif | 231 | #endif |
232 | 232 | ||
233 | #if (defined PLATFORM_WIN32) || (defined PLATFORM_POCKETPC) | 233 | #if THREADAPI == THREADAPI_WINDOWS |
234 | // | 234 | // |
235 | void MUTEX_INIT( MUTEX_T *ref ) { | 235 | void MUTEX_INIT( MUTEX_T *ref ) { |
236 | *ref= CreateMutex( NULL /*security attr*/, FALSE /*not locked*/, NULL ); | 236 | *ref= CreateMutex( NULL /*security attr*/, FALSE /*not locked*/, NULL ); |
@@ -282,7 +282,8 @@ static void prepare_timeout( struct timespec *ts, time_d abs_secs ) { | |||
282 | *ref= h; | 282 | *ref= h; |
283 | } | 283 | } |
284 | // | 284 | // |
285 | bool_t THREAD_WAIT( THREAD_T *ref, double secs ) { | 285 | bool_t THREAD_WAIT_IMPL( THREAD_T *ref, double secs) |
286 | { | ||
286 | DWORD ms = (secs<0.0) ? INFINITE : (DWORD)((secs*1000.0)+0.5); | 287 | DWORD ms = (secs<0.0) ? INFINITE : (DWORD)((secs*1000.0)+0.5); |
287 | 288 | ||
288 | DWORD rc= WaitForSingleObject( *ref, ms /*timeout*/ ); | 289 | DWORD rc= WaitForSingleObject( *ref, ms /*timeout*/ ); |
@@ -373,7 +374,7 @@ static void prepare_timeout( struct timespec *ts, time_d abs_secs ) { | |||
373 | if (!PulseEvent( *ref )) | 374 | if (!PulseEvent( *ref )) |
374 | FAIL( "PulseEvent", GetLastError() ); | 375 | FAIL( "PulseEvent", GetLastError() ); |
375 | } | 376 | } |
376 | #else | 377 | #else // THREADAPI == THREADAPI_PTHREAD |
377 | // PThread (Linux, OS X, ...) | 378 | // PThread (Linux, OS X, ...) |
378 | // | 379 | // |
379 | // On OS X, user processes seem to be able to change priorities. | 380 | // On OS X, user processes seem to be able to change priorities. |
@@ -652,7 +653,7 @@ static void prepare_timeout( struct timespec *ts, time_d abs_secs ) { | |||
652 | } | 653 | } |
653 | } | 654 | } |
654 | // | 655 | // |
655 | /* | 656 | /* |
656 | * Wait for a thread to finish. | 657 | * Wait for a thread to finish. |
657 | * | 658 | * |
658 | * 'mu_ref' is a lock we should use for the waiting; initially unlocked. | 659 | * 'mu_ref' is a lock we should use for the waiting; initially unlocked. |
@@ -660,11 +661,7 @@ static void prepare_timeout( struct timespec *ts, time_d abs_secs ) { | |||
660 | * | 661 | * |
661 | * Returns TRUE for succesful wait, FALSE for timed out | 662 | * Returns TRUE for succesful wait, FALSE for timed out |
662 | */ | 663 | */ |
663 | #ifdef PTHREAD_TIMEDJOIN | 664 | bool_t THREAD_WAIT( THREAD_T *ref, double secs , SIGNAL_T *signal_ref, MUTEX_T *mu_ref, volatile enum e_status *st_ref) |
664 | bool_t THREAD_WAIT( THREAD_T *ref, double secs ) | ||
665 | #else | ||
666 | bool_t THREAD_WAIT( THREAD_T *ref, SIGNAL_T *signal_ref, MUTEX_T *mu_ref, volatile enum e_status *st_ref, double secs ) | ||
667 | #endif | ||
668 | { | 665 | { |
669 | struct timespec ts_store; | 666 | struct timespec ts_store; |
670 | const struct timespec *timeout= NULL; | 667 | const struct timespec *timeout= NULL; |
@@ -672,16 +669,17 @@ static void prepare_timeout( struct timespec *ts, time_d abs_secs ) { | |||
672 | 669 | ||
673 | // Do timeout counting before the locks | 670 | // Do timeout counting before the locks |
674 | // | 671 | // |
675 | #ifdef PTHREAD_TIMEDJOIN | 672 | #if THREADWAIT_METHOD == THREADWAIT_TIMEOUT |
676 | if (secs>=0.0) { | 673 | if (secs>=0.0) |
677 | #else | 674 | #else // THREADWAIT_METHOD == THREADWAIT_CONDVAR |
678 | if (secs>0.0) { | 675 | if (secs>0.0) |
679 | #endif | 676 | #endif // THREADWAIT_METHOD == THREADWAIT_CONDVAR |
677 | { | ||
680 | prepare_timeout( &ts_store, now_secs()+secs ); | 678 | prepare_timeout( &ts_store, now_secs()+secs ); |
681 | timeout= &ts_store; | 679 | timeout= &ts_store; |
682 | } | 680 | } |
683 | 681 | ||
684 | #ifdef PTHREAD_TIMEDJOIN | 682 | #if THREADWAIT_METHOD == THREADWAIT_TIMEOUT |
685 | /* Thread is joinable | 683 | /* Thread is joinable |
686 | */ | 684 | */ |
687 | if (!timeout) { | 685 | if (!timeout) { |
@@ -694,7 +692,7 @@ static void prepare_timeout( struct timespec *ts, time_d abs_secs ) { | |||
694 | } | 692 | } |
695 | done= rc==0; | 693 | done= rc==0; |
696 | } | 694 | } |
697 | #else | 695 | #else // THREADWAIT_METHOD == THREADWAIT_CONDVAR |
698 | /* Since we've set the thread up as PTHREAD_CREATE_DETACHED, we cannot | 696 | /* Since we've set the thread up as PTHREAD_CREATE_DETACHED, we cannot |
699 | * join with it. Use the cond.var. | 697 | * join with it. Use the cond.var. |
700 | */ | 698 | */ |
@@ -718,13 +716,13 @@ static void prepare_timeout( struct timespec *ts, time_d abs_secs ) { | |||
718 | done= *st_ref >= DONE; // DONE|ERROR_ST|CANCELLED | 716 | done= *st_ref >= DONE; // DONE|ERROR_ST|CANCELLED |
719 | 717 | ||
720 | MUTEX_UNLOCK( mu_ref ); | 718 | MUTEX_UNLOCK( mu_ref ); |
721 | #endif | 719 | #endif // THREADWAIT_METHOD == THREADWAIT_CONDVAR |
722 | return done; | 720 | return done; |
723 | } | 721 | } |
724 | // | 722 | // |
725 | void THREAD_KILL( THREAD_T *ref ) { | 723 | void THREAD_KILL( THREAD_T *ref ) { |
726 | pthread_cancel( *ref ); | 724 | pthread_cancel( *ref ); |
727 | } | 725 | } |
728 | #endif | 726 | #endif // THREADAPI == THREADAPI_PTHREAD |
729 | 727 | ||
730 | static const lua_Alloc alloc_f= 0; | 728 | static const lua_Alloc alloc_f= 0; |