slapi2nspr.c 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276
  1. /** BEGIN COPYRIGHT BLOCK
  2. * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
  3. * Copyright (C) 2005 Red Hat, Inc.
  4. * All rights reserved.
  5. *
  6. * License: GPL (version 3 or any later version).
  7. * See LICENSE for details.
  8. * END COPYRIGHT BLOCK **/
  9. #ifdef HAVE_CONFIG_H
  10. # include <config.h>
  11. #endif
  12. /*
  13. * slapi2nspr.c - expose a subset of the NSPR20/21 API to SLAPI plugin writers
  14. *
  15. */
  16. #include "slap.h"
  17. #include <nspr.h>
  18. /*
  19. * Note that Slapi_Mutex and Slapi_CondVar are defined like this in
  20. * slapi-plugin.h:
  21. *
  22. * typedef struct slapi_mutex Slapi_Mutex;
  23. * typedef struct slapi_condvar Slapi_CondVar;
  24. *
  25. * but there is no definition for struct slapi_mutex or struct slapi_condvar.
  26. * This seems to work okay since we always use them in pointer form and cast
  27. * directly to their NSPR equivalents. Clever, huh?
  28. */
  29. /*
  30. * ---------------- SLAPI API Functions --------------------------------------
  31. */
  32. /*
  33. * Function: slapi_new_mutex
  34. * Description: behaves just like PR_NewLock().
  35. * Returns: a pointer to the new mutex (NULL if a mutex can't be created).
  36. */
  37. Slapi_Mutex *
  38. slapi_new_mutex( void )
  39. {
  40. return( (Slapi_Mutex *)PR_NewLock());
  41. }
  42. /*
  43. * Function: slapi_destroy_mutex
  44. * Description: behaves just like PR_DestroyLock().
  45. */
  46. void
  47. slapi_destroy_mutex( Slapi_Mutex *mutex )
  48. {
  49. if ( mutex != NULL ) {
  50. PR_DestroyLock( (PRLock *)mutex );
  51. }
  52. }
  53. /*
  54. * Function: slapi_lock_mutex
  55. * Description: behaves just like PR_Lock().
  56. */
  57. void
  58. slapi_lock_mutex( Slapi_Mutex *mutex )
  59. {
  60. if ( mutex != NULL ) {
  61. PR_Lock( (PRLock *)mutex );
  62. }
  63. }
  64. /*
  65. * Function: slapi_unlock_mutex
  66. * Description: behaves just like PR_Unlock().
  67. * Returns:
  68. * non-zero if mutex was successfully unlocked.
  69. * 0 if mutex is NULL or is not locked by the calling thread.
  70. */
  71. int
  72. slapi_unlock_mutex( Slapi_Mutex *mutex )
  73. {
  74. if ( mutex == NULL || PR_Unlock( (PRLock *)mutex ) == PR_FAILURE ) {
  75. return( 0 );
  76. } else {
  77. return( 1 );
  78. }
  79. }
  80. /*
  81. * Function: slapi_new_condvar
  82. * Description: behaves just like PR_NewCondVar().
  83. * Returns: pointer to a new condition variable (NULL if one can't be created).
  84. */
  85. Slapi_CondVar *
  86. slapi_new_condvar( Slapi_Mutex *mutex )
  87. {
  88. if ( mutex == NULL ) {
  89. return( NULL );
  90. }
  91. return( (Slapi_CondVar *)PR_NewCondVar( (PRLock *)mutex ));
  92. }
  93. /*
  94. * Function: slapi_destroy_condvar
  95. * Description: behaves just like PR_DestroyCondVar().
  96. */
  97. void
  98. slapi_destroy_condvar( Slapi_CondVar *cvar )
  99. {
  100. if ( cvar != NULL ) {
  101. PR_DestroyCondVar( (PRCondVar *)cvar );
  102. }
  103. }
  104. /*
  105. * Function: slapi_wait_condvar
  106. * Description: behaves just like PR_WaitCondVar() except timeout is
  107. * in seconds and microseconds instead of PRIntervalTime units.
  108. * If timeout is NULL, this call blocks indefinitely.
  109. * Returns:
  110. * non-zero is all goes well.
  111. * 0 if cvar is NULL, the caller has not locked the mutex associated
  112. * with cvar, or the waiting thread was interrupted.
  113. */
  114. int
  115. slapi_wait_condvar( Slapi_CondVar *cvar, struct timeval *timeout )
  116. {
  117. PRIntervalTime prit;
  118. if ( cvar == NULL ) {
  119. return( 0 );
  120. }
  121. if ( timeout == NULL ) {
  122. prit = PR_INTERVAL_NO_TIMEOUT;
  123. } else {
  124. prit = PR_SecondsToInterval( timeout->tv_sec )
  125. + PR_MicrosecondsToInterval( timeout->tv_usec );
  126. }
  127. if ( PR_WaitCondVar( (PRCondVar *)cvar, prit ) != PR_SUCCESS ) {
  128. return( 0 );
  129. }
  130. return( 1 );
  131. }
  132. /*
  133. * Function: slapi_notify_condvar
  134. * Description: if notify_all is zero, behaves just like PR_NotifyCondVar().
  135. * if notify_all is non-zero, behaves just like PR_NotifyAllCondVar().
  136. * Returns:
  137. * non-zero if all goes well.
  138. * 0 if cvar is NULL or the caller has not locked the mutex associated
  139. * with cvar.
  140. */
  141. int
  142. slapi_notify_condvar( Slapi_CondVar *cvar, int notify_all )
  143. {
  144. PRStatus prrc;
  145. if ( cvar == NULL ) {
  146. return( 0 );
  147. }
  148. if ( notify_all ) {
  149. prrc = PR_NotifyAllCondVar( (PRCondVar *)cvar );
  150. } else {
  151. prrc = PR_NotifyCondVar( (PRCondVar *)cvar );
  152. }
  153. return( prrc == PR_SUCCESS ? 1 : 0 );
  154. }
  155. Slapi_RWLock *
  156. slapi_new_rwlock(void)
  157. {
  158. #ifdef USE_POSIX_RWLOCKS
  159. pthread_rwlock_t *rwlock = NULL;
  160. rwlock = (pthread_rwlock_t *)slapi_ch_malloc(sizeof(pthread_rwlock_t));
  161. if (rwlock) {
  162. pthread_rwlock_init(rwlock, NULL);
  163. }
  164. return((Slapi_RWLock *)rwlock);
  165. #else
  166. return((Slapi_RWLock *)PR_NewRWLock(PR_RWLOCK_RANK_NONE, "slapi_rwlock"));
  167. #endif
  168. }
  169. void
  170. slapi_destroy_rwlock(Slapi_RWLock *rwlock)
  171. {
  172. if (rwlock != NULL) {
  173. #ifdef USE_POSIX_RWLOCKS
  174. pthread_rwlock_destroy((pthread_rwlock_t *)rwlock);
  175. slapi_ch_free((void **)&rwlock);
  176. #else
  177. PR_DestroyLock((PRRWLock *)rwlock);
  178. #endif
  179. }
  180. }
  181. int
  182. slapi_rwlock_rdlock( Slapi_RWLock *rwlock )
  183. {
  184. int ret = 0;
  185. if (rwlock != NULL) {
  186. #ifdef USE_POSIX_RWLOCKS
  187. ret = pthread_rwlock_rdlock((pthread_rwlock_t *)rwlock);
  188. #else
  189. PR_RWLock_Rlock((PRRWLock *)rwlock);
  190. #endif
  191. }
  192. return ret;
  193. }
  194. int
  195. slapi_rwlock_wrlock( Slapi_RWLock *rwlock )
  196. {
  197. int ret = 0;
  198. if (rwlock != NULL) {
  199. #ifdef USE_POSIX_RWLOCKS
  200. ret = pthread_rwlock_wrlock((pthread_rwlock_t *)rwlock);
  201. #else
  202. PR_RWLock_Wlock((PRRWLock *)rwlock);
  203. #endif
  204. }
  205. return ret;
  206. }
  207. int
  208. slapi_rwlock_unlock( Slapi_RWLock *rwlock )
  209. {
  210. int ret = 0;
  211. if (rwlock != NULL) {
  212. #ifdef USE_POSIX_RWLOCKS
  213. ret = pthread_rwlock_unlock((pthread_rwlock_t *)rwlock);
  214. #else
  215. PR_RWLock_Unlock((PRRWLock *)rwlock);
  216. #endif
  217. }
  218. return ret;
  219. }
  220. int
  221. slapi_rwlock_get_size( void )
  222. {
  223. #ifdef USE_POSIX_RWLOCKS
  224. return sizeof(pthread_rwlock_t);
  225. #else
  226. /*
  227. * NSPR does not provide the size of PRRWLock.
  228. * This is a rough estimate to maintain the entry size sane.
  229. */
  230. return sizeof("slapi_rwlock") + sizeof(void *) * 6;
  231. #endif
  232. }