SDL的关于线程中互斥锁的条件变量的封装,
#include <sys/time.h>
#include <unistd.h>
#include <errno.h>
#include <pthread.h>
#include "SDL_thread.h"
#include "SDL_sysmutex_c.h"
struct SDL_cond
{
pthread_cond_t cond;
};
/* Create a condition variable */
SDL_cond *
SDL_CreateCond(void)
{
SDL_cond *cond;
cond = (SDL_cond *) SDL_malloc(sizeof(SDL_cond));
if (cond) {
if (pthread_cond_init(&cond->cond, NULL) < 0) {
SDL_SetError("pthread_cond_init() failed");
SDL_free(cond);
cond = NULL;
}
}
return (cond);
}
/* Destroy a condition variable */
void
SDL_DestroyCond(SDL_cond * cond)
{
if (cond) {
pthread_cond_destroy(&cond->cond);
SDL_free(cond);
}
}
/* Restart one of the threads that are waiting on the condition variable */
int
SDL_CondSignal(SDL_cond * cond)
{
int retval;
if (!cond) {
SDL_SetError("Passed a NULL condition variable");
return -1;
}
retval = 0;
if (pthread_cond_signal(&cond->cond) != 0) {
SDL_SetError("pthread_cond_signal() failed");
retval = -1;
}
return retval;
}
/* Restart all threads that are waiting on the condition variable */
int
SDL_CondBroadcast(SDL_cond * cond)
{
int retval;
if (!cond) {
SDL_SetError("Passed a NULL condition variable");
return -1;
}
retval = 0;
if (pthread_cond_broadcast(&cond->cond) != 0) {
SDL_SetError("pthread_cond_broadcast() failed");
retval = -1;
}
return retval;
}
int
SDL_CondWaitTimeout(SDL_cond * cond, SDL_mutex * mutex, Uint32 ms)
{
int retval;
struct timeval delta;
struct timespec abstime;
if (!cond) {
SDL_SetError("Passed a NULL condition variable");
return -1;
}
gettimeofday(&delta, NULL);
abstime.tv_sec = delta.tv_sec + (ms / 1000);
abstime.tv_nsec = (delta.tv_usec + (ms % 1000) * 1000) * 1000;
if (abstime.tv_nsec > 1000000000) {
abstime.tv_sec += 1;
abstime.tv_nsec -= 1000000000; //这里是重点,看过很多个程序,很多都忘记对这里进行处理。
}
tryagain:
retval = pthread_cond_timedwait(&cond->cond, &mutex->id, &abstime);
switch (retval) {
case EINTR:
goto tryagain;
break;
case ETIMEDOUT:
retval = SDL_MUTEX_TIMEDOUT;
break;
case 0:
break;
default:
SDL_SetError("pthread_cond_timedwait() failed");
retval = -1;
break;
}
return retval;
}
/* Wait on the condition variable, unlocking the provided mutex.
The mutex must be locked before entering this function!
这里在实际程序中,使用这样的循环语句,可以确定的知道条件一定等到了。
while (!vp->allocated && !is->videoq.abort_request) {
SDL_CondWait(is->pictq_cond, is->pictq_mutex);
}
*/
int
SDL_CondWait(SDL_cond * cond, SDL_mutex * mutex)
{
int retval;
if (!cond) {
SDL_SetError("Passed a NULL condition variable");
return -1;
}
retval = 0;
if (pthread_cond_wait(&cond->cond, &mutex->id) != 0) {
SDL_SetError("pthread_cond_wait() failed");
retval = -1;
}
return retval;
}
#include <sys/time.h>
#include <unistd.h>
#include <errno.h>
#include <pthread.h>
#include "SDL_thread.h"
#include "SDL_sysmutex_c.h"
struct SDL_cond
{
pthread_cond_t cond;
};
/* Create a condition variable */
SDL_cond *
SDL_CreateCond(void)
{
SDL_cond *cond;
cond = (SDL_cond *) SDL_malloc(sizeof(SDL_cond));
if (cond) {
if (pthread_cond_init(&cond->cond, NULL) < 0) {
SDL_SetError("pthread_cond_init() failed");
SDL_free(cond);
cond = NULL;
}
}
return (cond);
}
/* Destroy a condition variable */
void
SDL_DestroyCond(SDL_cond * cond)
{
if (cond) {
pthread_cond_destroy(&cond->cond);
SDL_free(cond);
}
}
/* Restart one of the threads that are waiting on the condition variable */
int
SDL_CondSignal(SDL_cond * cond)
{
int retval;
if (!cond) {
SDL_SetError("Passed a NULL condition variable");
return -1;
}
retval = 0;
if (pthread_cond_signal(&cond->cond) != 0) {
SDL_SetError("pthread_cond_signal() failed");
retval = -1;
}
return retval;
}
/* Restart all threads that are waiting on the condition variable */
int
SDL_CondBroadcast(SDL_cond * cond)
{
int retval;
if (!cond) {
SDL_SetError("Passed a NULL condition variable");
return -1;
}
retval = 0;
if (pthread_cond_broadcast(&cond->cond) != 0) {
SDL_SetError("pthread_cond_broadcast() failed");
retval = -1;
}
return retval;
}
int
SDL_CondWaitTimeout(SDL_cond * cond, SDL_mutex * mutex, Uint32 ms)
{
int retval;
struct timeval delta;
struct timespec abstime;
if (!cond) {
SDL_SetError("Passed a NULL condition variable");
return -1;
}
gettimeofday(&delta, NULL);
abstime.tv_sec = delta.tv_sec + (ms / 1000);
abstime.tv_nsec = (delta.tv_usec + (ms % 1000) * 1000) * 1000;
if (abstime.tv_nsec > 1000000000) {
abstime.tv_sec += 1;
abstime.tv_nsec -= 1000000000; //这里是重点,看过很多个程序,很多都忘记对这里进行处理。
}
tryagain:
retval = pthread_cond_timedwait(&cond->cond, &mutex->id, &abstime);
switch (retval) {
case EINTR:
goto tryagain;
break;
case ETIMEDOUT:
retval = SDL_MUTEX_TIMEDOUT;
break;
case 0:
break;
default:
SDL_SetError("pthread_cond_timedwait() failed");
retval = -1;
break;
}
return retval;
}
/* Wait on the condition variable, unlocking the provided mutex.
The mutex must be locked before entering this function!
这里在实际程序中,使用这样的循环语句,可以确定的知道条件一定等到了。
while (!vp->allocated && !is->videoq.abort_request) {
SDL_CondWait(is->pictq_cond, is->pictq_mutex);
}
*/
int
SDL_CondWait(SDL_cond * cond, SDL_mutex * mutex)
{
int retval;
if (!cond) {
SDL_SetError("Passed a NULL condition variable");
return -1;
}
retval = 0;
if (pthread_cond_wait(&cond->cond, &mutex->id) != 0) {
SDL_SetError("pthread_cond_wait() failed");
retval = -1;
}
return retval;
}