thread_mutex_emul.c
来自「CS架构的多平台的GUI系统」· C语言 代码 · 共 229 行
C
229 行
/*************************************************************************** begin : Thu Mar 25 2004 copyright : (C) 2004 - 2005 by Alper Akcan email : distchx@yahoo.com ***************************************************************************//*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU Lesser General Public License as * * published by the Free Software Foundation; either version 2.1 of the * * License, or (at your option) any later version. * * * ***************************************************************************//* Emulation is heavily based on SDL Library www.libsdl.org */struct s_thread_mutex_s { int recursive; int owner; s_thread_sem_t *sem;};struct s_thread_cond_s { s_thread_mutex_t *lock; int waiting; int signals; s_thread_sem_t *wait_sem; s_thread_sem_t *wait_done;};/* Implementation of mutexes using semaphores */static int s_thread_emul_mutex_init (s_thread_mutex_t *mut){ mut->sem = (s_thread_sem_t *) s_malloc(sizeof(s_thread_sem_t)); if (s_thread_sem_create(mut->sem, 1)) { goto err0; } mut->recursive = 0; mut->owner = 0; return 0;err0: s_free(mut->sem); mut->sem = NULL; return -1;}static int s_thread_emul_mutex_destroy (s_thread_mutex_t *mut){ int ret = -1; if (mut->sem) { ret = s_thread_sem_destroy(mut->sem); s_free(mut->sem); mut->sem = NULL; } return ret;}static int s_thread_emul_mutex_lock (s_thread_mutex_t *mut){ int ret = 0; int tid; if (mut->sem == NULL) { return -1; } tid = s_thread_self(); if (mut->owner == tid) { ++mut->recursive; } else { ret = s_thread_sem_wait(mut->sem); mut->owner = tid; mut->recursive = 0; } return ret;}static int s_thread_emul_mutex_trylock (s_thread_mutex_t *mut){ return -1;}static int s_thread_emul_mutex_unlock (s_thread_mutex_t *mut){ int ret = 0; if (mut->sem == NULL) { return -1; } if (s_thread_self() != mut->owner) { return -1; } if (mut->recursive) { --mut->recursive; } else { mut->owner = 0; ret = s_thread_sem_post(mut->sem); } return ret;}/* Implementation of condition variables using semaphores and mutexes */static int s_thread_emul_cond_init (s_thread_cond_t *cond){ if (s_thread_mutex_init(&(cond->lock))) { goto err0; } cond->wait_sem = (s_thread_sem_t *) s_malloc(sizeof(s_thread_sem_t)); if (s_thread_sem_create(cond->wait_sem, 0)) { goto err1; } cond->wait_done = (s_thread_sem_t *) s_malloc(sizeof(s_thread_sem_t)); if (s_thread_sem_create(cond->wait_done, 0)) { goto err2; } cond->waiting = 0; cond->signals = 0; return 0;err2: s_free(cond->wait_done); cond->wait_done = NULL; s_thread_sem_destroy(cond->wait_sem);err1: s_free(cond->wait_sem); cond->wait_sem = NULL; s_thread_mutex_destroy(cond->lock);err0: return -1;}static int s_thread_emul_cond_destroy (s_thread_cond_t *cond){ int ret = 0; if (cond->wait_done) { ret |= s_thread_sem_destroy(cond->wait_done); s_free(cond->wait_done); cond->wait_done = NULL; } if (cond->wait_sem) { ret |= s_thread_sem_destroy(cond->wait_sem); s_free(cond->wait_sem); cond->wait_sem = NULL; } if (cond->lock) { ret |= s_thread_mutex_destroy(cond->lock); } return ret;}static int s_thread_emul_cond_signal (s_thread_cond_t *cond){ s_thread_mutex_lock(cond->lock); if (cond->waiting > cond->signals) { ++cond->signals; s_thread_sem_post(cond->wait_sem); s_thread_mutex_unlock(cond->lock); s_thread_sem_wait(cond->wait_done); } else { s_thread_mutex_unlock(cond->lock); } return 0;}static int s_thread_emul_cond_broadcast (s_thread_cond_t *cond){ s_thread_mutex_lock(cond->lock); if (cond->waiting > cond->signals) { int i; int num_waiting; num_waiting = (cond->waiting - cond->signals); cond->signals = cond->waiting; for (i = 0; i < num_waiting; ++i) { s_thread_sem_post(cond->wait_sem); } s_thread_mutex_unlock(cond->lock); for (i = 0; i < num_waiting; ++i) { s_thread_sem_wait(cond->wait_done); } } else { s_thread_mutex_unlock(cond->lock); } return 0;}static int s_thread_emul_cond_wait (s_thread_cond_t *cond, s_thread_mutex_t *mut){ s_thread_mutex_lock(cond->lock); ++cond->waiting; s_thread_mutex_unlock(cond->lock); s_thread_mutex_unlock(mut); s_thread_sem_wait(cond->wait_sem); s_thread_mutex_lock(cond->lock); if (cond->signals > 0) { s_thread_sem_post(cond->wait_done); --cond->signals; } --cond->waiting; s_thread_mutex_unlock(cond->lock); s_thread_mutex_lock(mut); return 0;}static int s_thread_emul_cond_timedwait (s_thread_cond_t *cond, s_thread_mutex_t *mut, int msec){ int ret = 0; s_thread_mutex_lock(cond->lock); ++cond->waiting; s_thread_mutex_unlock(cond->lock); s_thread_mutex_unlock(mut); ret = s_thread_sem_wait_timeout(cond->wait_sem, msec); s_thread_mutex_lock(cond->lock); if (cond->signals > 0) { if (ret > 0) { s_thread_sem_wait(cond->wait_sem); } s_thread_sem_post(cond->wait_done); --cond->signals; } --cond->waiting; s_thread_mutex_unlock(cond->lock); s_thread_mutex_lock(mut); return ret;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?