00001 /* SVN FILE INFO 00002 * $Revision: 316 $ : Last Committed Revision 00003 * $Date: 2009-04-29 16:40:54 -0700 (Wed, 29 Apr 2009) $ : Last Committed Date */ 00004 /*[ 00005 * Copyright (c) 2007 Integration Engineering Laboratory 00006 University of California, Davis 00007 * 00008 * Permission to use, copy, and distribute this software and its 00009 * documentation for any purpose with or without fee is hereby granted, 00010 * provided that the above copyright notice appear in all copies and 00011 * that both that copyright notice and this permission notice appear 00012 * in supporting documentation. 00013 * 00014 * Permission to modify the software is granted, but not the right to 00015 * distribute the complete modified source code. Modifications are to 00016 * be distributed as patches to the released version. Permission to 00017 * distribute binaries produced by compiling modified sources is granted, 00018 * provided you 00019 * 1. distribute the corresponding source modifications from the 00020 * released version in the form of a patch file along with the binaries, 00021 * 2. add special version identification to distinguish your version 00022 * in addition to the base release version number, 00023 * 3. provide your name and address as the primary contact for the 00024 * support of your modified version, and 00025 * 4. retain our contact information in regard to use of the base 00026 * software. 00027 * Permission to distribute the released version of the source code along 00028 * with corresponding source modifications in the form of a patch file is 00029 * granted with same provisions 2 through 4 for binary distributions. 00030 * 00031 * This software is provided "as is" without express or implied warranty 00032 * to the extent permitted by applicable law. 00033 ]*/ 00034 #ifndef _WIN32 00035 #include "config.h" 00036 #else 00037 #include "winconfig.h" 00038 #endif 00039 00040 #include <stdio.h> 00041 #include <stdlib.h> 00042 #include "include/macros.h" 00043 #include "include/mc_error.h" 00044 #include "include/mc_rwlock.h" 00045 00046 int mc_rwlock_init(mc_rwlock_p rwlock) 00047 { 00048 /* Init values */ 00049 rwlock->num_readers = 0; 00050 rwlock->write_flag = 0; 00051 rwlock->write_request = 0; 00052 00053 /* Alloc sync */ 00054 rwlock->lock = (MUTEX_T*)malloc(sizeof(MUTEX_T)); 00055 CHECK_NULL(rwlock->lock, return MC_ERR_MEMORY;); 00056 rwlock->cond = (COND_T*)malloc(sizeof(COND_T)); 00057 CHECK_NULL(rwlock->cond, return MC_ERR_MEMORY;); 00058 00059 /* Init sync */ 00060 MUTEX_INIT(rwlock->lock); 00061 COND_INIT(rwlock->cond); 00062 00063 return 0; 00064 } 00065 00066 int mc_rwlock_destroy(mc_rwlock_p rwlock) 00067 { 00068 /* Destroy mutex/conds */ 00069 MUTEX_DESTROY(rwlock->lock); 00070 COND_DESTROY(rwlock->cond); 00071 00072 /* De-alloc */ 00073 free(rwlock->lock); 00074 free(rwlock->cond); 00075 00076 return 0; 00077 } 00078 00079 int mc_rwlock_rdlock(mc_rwlock_p rwlock) 00080 { 00081 MUTEX_LOCK(rwlock->lock); 00082 while ( 00083 (rwlock->write_flag != 0) || 00084 (rwlock->write_request != 0) 00085 ) 00086 { 00087 COND_WAIT(rwlock->cond, rwlock->lock); 00088 } 00089 rwlock->num_readers++; 00090 MUTEX_UNLOCK(rwlock->lock); 00091 return 0; 00092 } 00093 00094 int mc_rwlock_rdunlock(mc_rwlock_p rwlock) 00095 { 00096 MUTEX_LOCK(rwlock->lock); 00097 if (rwlock->num_readers > 0) { 00098 rwlock->num_readers--; 00099 } 00100 if (rwlock->num_readers == 0) { 00101 COND_SIGNAL( rwlock->cond ); 00102 } 00103 MUTEX_UNLOCK(rwlock->lock); 00104 return 0; 00105 } 00106 00107 int mc_rwlock_wrlock(mc_rwlock_p rwlock) 00108 { 00109 MUTEX_LOCK(rwlock->lock); 00110 rwlock->write_request++; 00111 00112 while ( 00113 (rwlock->num_readers != 0) || 00114 (rwlock->write_flag != 0) 00115 ) 00116 { 00117 COND_WAIT(rwlock->cond, rwlock->lock); 00118 } 00119 00120 rwlock->write_request--; 00121 rwlock->write_flag++; 00122 MUTEX_UNLOCK(rwlock->lock); 00123 return 0; 00124 } 00125 00126 int mc_rwlock_wrunlock(mc_rwlock_p rwlock) 00127 { 00128 MUTEX_LOCK(rwlock->lock); 00129 rwlock->write_flag = 0; 00130 COND_SIGNAL(rwlock->cond); 00131 MUTEX_UNLOCK(rwlock->lock); 00132 return 0; 00133 }