Home | History | Annotate | Download | only in pth
      1 /*
      2     SDL - Simple DirectMedia Layer
      3     Copyright (C) 1997-2012 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 (at) libsdl.org
     21 */
     22 #include "SDL_config.h"
     23 
     24 /*
     25  *	GNU pth conditions variables
     26  *
     27  *	Patrice Mandin
     28  */
     29 
     30 #include <pth.h>
     31 
     32 #include "SDL_thread.h"
     33 #include "SDL_sysmutex_c.h"
     34 
     35 struct SDL_cond
     36 {
     37 	pth_cond_t	condpth_p;
     38 };
     39 
     40 /* Create a condition variable */
     41 SDL_cond * SDL_CreateCond(void)
     42 {
     43 	SDL_cond *cond;
     44 
     45 	cond = (SDL_cond *) SDL_malloc(sizeof(SDL_cond));
     46 	if ( cond ) {
     47 		if ( pth_cond_init(&(cond->condpth_p)) < 0 ) {
     48 			SDL_SetError("pthread_cond_init() failed");
     49 			SDL_free(cond);
     50 			cond = NULL;
     51 		}
     52 	} else {
     53 		SDL_OutOfMemory();
     54 	}
     55 	return(cond);
     56 }
     57 
     58 /* Destroy a condition variable */
     59 void SDL_DestroyCond(SDL_cond *cond)
     60 {
     61 	if ( cond ) {
     62 		SDL_free(cond);
     63 	}
     64 }
     65 
     66 /* Restart one of the threads that are waiting on the condition variable */
     67 int SDL_CondSignal(SDL_cond *cond)
     68 {
     69 	int retval;
     70 
     71 	if ( ! cond ) {
     72 		SDL_SetError("Passed a NULL condition variable");
     73 		return -1;
     74 	}
     75 
     76 	retval = 0;
     77 	if ( pth_cond_notify(&(cond->condpth_p), FALSE) != 0 ) {
     78 		SDL_SetError("pth_cond_notify() failed");
     79 		retval = -1;
     80 	}
     81 	return retval;
     82 }
     83 
     84 /* Restart all threads that are waiting on the condition variable */
     85 int SDL_CondBroadcast(SDL_cond *cond)
     86 {
     87 	int retval;
     88 
     89 	if ( ! cond ) {
     90 		SDL_SetError("Passed a NULL condition variable");
     91 		return -1;
     92 	}
     93 
     94 	retval = 0;
     95 	if ( pth_cond_notify(&(cond->condpth_p), TRUE) != 0 ) {
     96 		SDL_SetError("pth_cond_notify() failed");
     97 		retval = -1;
     98 	}
     99 	return retval;
    100 }
    101 
    102 /* Wait on the condition variable for at most 'ms' milliseconds.
    103    The mutex must be locked before entering this function!
    104    The mutex is unlocked during the wait, and locked again after the wait.
    105 
    106 Typical use:
    107 
    108 Thread A:
    109 	SDL_LockMutex(lock);
    110 	while ( ! condition ) {
    111 		SDL_CondWait(cond);
    112 	}
    113 	SDL_UnlockMutex(lock);
    114 
    115 Thread B:
    116 	SDL_LockMutex(lock);
    117 	...
    118 	condition = true;
    119 	...
    120 	SDL_UnlockMutex(lock);
    121  */
    122 int SDL_CondWaitTimeout(SDL_cond *cond, SDL_mutex *mutex, Uint32 ms)
    123 {
    124 	int retval;
    125 	pth_event_t ev;
    126 	int sec;
    127 
    128 	if ( ! cond ) {
    129 		SDL_SetError("Passed a NULL condition variable");
    130 		return -1;
    131 	}
    132 
    133 	retval = 0;
    134 
    135 	sec = ms/1000;
    136 	ev = pth_event(PTH_EVENT_TIME, pth_timeout(sec,(ms-sec*1000)*1000));
    137 
    138 	if ( pth_cond_await(&(cond->condpth_p), &(mutex->mutexpth_p), ev) != 0 ) {
    139 		SDL_SetError("pth_cond_await() failed");
    140 		retval = -1;
    141 	}
    142 
    143     pth_event_free(ev, PTH_FREE_ALL);
    144 
    145 	return retval;
    146 }
    147 
    148 /* Wait on the condition variable forever */
    149 int SDL_CondWait(SDL_cond *cond, SDL_mutex *mutex)
    150 {
    151 	int retval;
    152 
    153 	if ( ! cond ) {
    154 		SDL_SetError("Passed a NULL condition variable");
    155 		return -1;
    156 	}
    157 
    158 	retval = 0;
    159 	if ( pth_cond_await(&(cond->condpth_p), &(mutex->mutexpth_p), NULL) != 0 ) {
    160 		SDL_SetError("pth_cond_await() failed");
    161 		retval = -1;
    162 	}
    163 	return retval;
    164 }
    165