os0sync.c
上传用户:tsgydb
上传日期:2007-04-14
资源大小:10674k
文件大小:9k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. /******************************************************
  2. The interface to the operating system
  3. synchronization primitives.
  4. (c) 1995 Innobase Oy
  5. Created 9/6/1995 Heikki Tuuri
  6. *******************************************************/
  7. #include "os0sync.h"
  8. #ifdef UNIV_NONINL
  9. #include "os0sync.ic"
  10. #endif
  11. #ifdef __WIN__
  12. #include <windows.h>
  13. #endif
  14. #include "ut0mem.h"
  15. /* Type definition for an operating system mutex struct */
  16. struct os_mutex_struct{ 
  17. void* handle; /* OS handle to mutex */
  18. ulint count; /* we use this counter to check
  19. that the same thread does not
  20. recursively lock the mutex: we
  21. do not assume that the OS mutex
  22. supports recursive locking, though
  23. NT seems to do that */
  24. };
  25. /*************************************************************
  26. Creates an event semaphore, i.e., a semaphore which may
  27. just have two states: signaled and nonsignaled.
  28. The created event is manual reset: it must be reset
  29. explicitly by calling sync_os_reset_event. */
  30. os_event_t
  31. os_event_create(
  32. /*============*/
  33. /* out: the event handle */
  34. char* name) /* in: the name of the event, if NULL
  35. the event is created without a name */
  36. {
  37. #ifdef __WIN__
  38. HANDLE event;
  39. event = CreateEvent(NULL, /* No security attributes */
  40. TRUE, /* Manual reset */
  41. FALSE, /* Initial state nonsignaled */
  42. name);
  43. ut_a(event);
  44. return(event);
  45. #else
  46. os_event_t event;
  47. UT_NOT_USED(name);
  48. event = ut_malloc(sizeof(struct os_event_struct));
  49. os_fast_mutex_init(&(event->os_mutex));
  50. pthread_cond_init(&(event->cond_var), NULL);
  51. event->is_set = FALSE;
  52. return(event);
  53. #endif
  54. }
  55. /*************************************************************
  56. Creates an auto-reset event semaphore, i.e., an event
  57. which is automatically reset when a single thread is
  58. released. */
  59. os_event_t
  60. os_event_create_auto(
  61. /*=================*/
  62. /* out: the event handle */
  63. char* name) /* in: the name of the event, if NULL
  64. the event is created without a name */
  65. {
  66. #ifdef __WIN__
  67. HANDLE event;
  68. event = CreateEvent(NULL, /* No security attributes */
  69. FALSE, /* Auto-reset */
  70. FALSE, /* Initial state nonsignaled */
  71. name);
  72. ut_a(event);
  73. return(event);
  74. #else
  75. /* Does nothing in Posix because we do not need this with MySQL  */
  76. UT_NOT_USED(name);
  77. return(NULL);
  78. #endif
  79. }
  80. /**************************************************************
  81. Sets an event semaphore to the signaled state: lets waiting threads
  82. proceed. */
  83. void
  84. os_event_set(
  85. /*=========*/
  86. os_event_t event) /* in: event to set */
  87. {
  88. #ifdef __WIN__
  89. ut_a(event);
  90. ut_a(SetEvent(event));
  91. #else
  92. ut_a(event);
  93. os_fast_mutex_lock(&(event->os_mutex));
  94. if (event->is_set) {
  95. /* Do nothing */
  96. } else {
  97. event->is_set = TRUE;
  98. pthread_cond_broadcast(&(event->cond_var));
  99. }
  100. os_fast_mutex_unlock(&(event->os_mutex));
  101. #endif
  102. }
  103. /**************************************************************
  104. Resets an event semaphore to the nonsignaled state. Waiting threads will
  105. stop to wait for the event. */
  106. void
  107. os_event_reset(
  108. /*===========*/
  109. os_event_t event) /* in: event to reset */
  110. {
  111. #ifdef __WIN__
  112. ut_a(event);
  113. ut_a(ResetEvent(event));
  114. #else
  115. ut_a(event);
  116. os_fast_mutex_lock(&(event->os_mutex));
  117. if (!event->is_set) {
  118. /* Do nothing */
  119. } else {
  120. event->is_set = FALSE;
  121. }
  122. os_fast_mutex_unlock(&(event->os_mutex));
  123. #endif
  124. }
  125. /**************************************************************
  126. Frees an event object. */
  127. void
  128. os_event_free(
  129. /*==========*/
  130. os_event_t event) /* in: event to free */
  131. {
  132. #ifdef __WIN__
  133. ut_a(event);
  134. ut_a(CloseHandle(event));
  135. #else
  136. ut_a(event);
  137. os_fast_mutex_free(&(event->os_mutex));
  138. pthread_cond_destroy(&(event->cond_var));
  139. ut_free(event);
  140. #endif
  141. }
  142. /**************************************************************
  143. Waits for an event object until it is in the signaled state. */
  144. void
  145. os_event_wait(
  146. /*==========*/
  147. os_event_t event) /* in: event to wait */
  148. {
  149. #ifdef __WIN__
  150. DWORD err;
  151. ut_a(event);
  152. /* Specify an infinite time limit for waiting */
  153. err = WaitForSingleObject(event, INFINITE);
  154. ut_a(err == WAIT_OBJECT_0);
  155. #else
  156. os_fast_mutex_lock(&(event->os_mutex));
  157. loop:
  158. if (event->is_set == TRUE) {
  159. os_fast_mutex_unlock(&(event->os_mutex));
  160. /* Ok, we may return */
  161. return;
  162. }
  163. pthread_cond_wait(&(event->cond_var), &(event->os_mutex));
  164. /* Solaris manual said that spurious wakeups may occur: we have
  165. to check the 'is_set' variable again */
  166. goto loop;
  167. #endif
  168. }
  169. /**************************************************************
  170. Waits for an event object until it is in the signaled state or
  171. a timeout is exceeded. */
  172. ulint
  173. os_event_wait_time(
  174. /*===============*/
  175. /* out: 0 if success, OS_SYNC_TIME_EXCEEDED if
  176. timeout was exceeded */
  177. os_event_t event, /* in: event to wait */
  178. ulint time) /* in: timeout in microseconds, or
  179. OS_SYNC_INFINITE_TIME */
  180. {
  181. #ifdef __WIN__
  182. DWORD err;
  183. ut_a(event);
  184. if (time != OS_SYNC_INFINITE_TIME) {
  185. err = WaitForSingleObject(event, time / 1000);
  186. } else {
  187. err = WaitForSingleObject(event, INFINITE);
  188. }
  189. if (err == WAIT_OBJECT_0) {
  190. return(0);
  191. } else if (err == WAIT_TIMEOUT) {
  192. return(OS_SYNC_TIME_EXCEEDED);
  193. } else {
  194. ut_error;
  195. }
  196. #else
  197. UT_NOT_USED(time);
  198. /* In Posix this is just an ordinary, infinite wait */
  199. os_event_wait(event);
  200. return(0);
  201. #endif
  202. }
  203. /**************************************************************
  204. Waits for any event in an event array. Returns if even a single
  205. one is signaled or becomes signaled. */
  206. ulint
  207. os_event_wait_multiple(
  208. /*===================*/
  209. /* out: index of the event
  210. which was signaled */
  211. ulint n, /* in: number of events in the
  212. array */
  213. os_event_t* event_array) /* in: pointer to an array of event
  214. handles */
  215. {
  216. #ifdef __WIN__
  217. DWORD index;
  218. ut_a(event_array);
  219. ut_a(n > 0);
  220. index = WaitForMultipleObjects(n,
  221. event_array,
  222. FALSE,    /* Wait for any 1 event */
  223. INFINITE); /* Infinite wait time
  224.    limit */
  225. ut_a(index >= WAIT_OBJECT_0);
  226. ut_a(index < WAIT_OBJECT_0 + n);
  227. return(index - WAIT_OBJECT_0);
  228. #else
  229. ut_a(n == 0);
  230. /* In Posix we can only wait for a single event */
  231. os_event_wait(*event_array);
  232. return(0);
  233. #endif
  234. }
  235. /*************************************************************
  236. Creates an operating system mutex semaphore.
  237. Because these are slow, the mutex semaphore of the database
  238. itself (sync_mutex_t) should be used where possible. */
  239. os_mutex_t
  240. os_mutex_create(
  241. /*============*/
  242. /* out: the mutex handle */
  243. char* name) /* in: the name of the mutex, if NULL
  244. the mutex is created without a name */
  245. {
  246. #ifdef __WIN__
  247. HANDLE mutex;
  248. os_mutex_t mutex_str;
  249. mutex = CreateMutex(NULL, /* No security attributes */
  250. FALSE, /* Initial state: no owner */
  251. name);
  252. ut_a(mutex);
  253. mutex_str = ut_malloc(sizeof(os_mutex_str_t));
  254. mutex_str->handle = mutex;
  255. mutex_str->count = 0;
  256. return(mutex_str);
  257. #else
  258. os_fast_mutex_t* os_mutex;
  259. os_mutex_t mutex_str;
  260. UT_NOT_USED(name);
  261. os_mutex = ut_malloc(sizeof(os_fast_mutex_t));
  262. os_fast_mutex_init(os_mutex);
  263. mutex_str = ut_malloc(sizeof(os_mutex_str_t));
  264. mutex_str->handle = os_mutex;
  265. mutex_str->count = 0;
  266. return(mutex_str);
  267. #endif
  268. }
  269. /**************************************************************
  270. Acquires ownership of a mutex semaphore. */
  271. void
  272. os_mutex_enter(
  273. /*===========*/
  274. os_mutex_t mutex) /* in: mutex to acquire */
  275. {
  276. #ifdef __WIN__
  277. DWORD err;
  278. ut_a(mutex);
  279. /* Specify infinite time limit for waiting */
  280. err = WaitForSingleObject(mutex->handle, INFINITE);
  281. ut_a(err == WAIT_OBJECT_0);
  282. (mutex->count)++;
  283. ut_a(mutex->count == 1);
  284. #else
  285. os_fast_mutex_lock(mutex->handle);
  286. (mutex->count)++;
  287. ut_a(mutex->count == 1);
  288. #endif
  289. }
  290. /**************************************************************
  291. Releases ownership of a mutex. */
  292. void
  293. os_mutex_exit(
  294. /*==========*/
  295. os_mutex_t mutex) /* in: mutex to release */
  296. {
  297. #ifdef __WIN__
  298. ut_a(mutex);
  299. ut_a(mutex->count == 1);
  300. (mutex->count)--;
  301. ut_a(ReleaseMutex(mutex->handle));
  302. #else
  303. ut_a(mutex);
  304. ut_a(mutex->count == 1);
  305. (mutex->count)--;
  306. os_fast_mutex_unlock(mutex->handle);
  307. #endif
  308. }
  309. /**************************************************************
  310. Frees a mutex object. */
  311. void
  312. os_mutex_free(
  313. /*==========*/
  314. os_mutex_t mutex) /* in: mutex to free */
  315. {
  316. #ifdef __WIN__
  317. ut_a(mutex);
  318. ut_a(CloseHandle(mutex->handle));
  319. ut_free(mutex);
  320. #else
  321. os_fast_mutex_free(mutex->handle);
  322. ut_free(mutex->handle);
  323. ut_free(mutex);
  324. #endif
  325. }
  326. #ifndef _WIN32
  327. /*************************************************************
  328. Initializes an operating system fast mutex semaphore. */
  329. void
  330. os_fast_mutex_init(
  331. /*===============*/
  332. os_fast_mutex_t* fast_mutex) /* in: fast mutex */
  333. {
  334. #ifdef __WIN__
  335. ut_a(fast_mutex);
  336. InitializeCriticalSection((LPCRITICAL_SECTION) fast_mutex);
  337. #else
  338. pthread_mutex_init(fast_mutex, NULL);
  339. #endif
  340. }
  341. /**************************************************************
  342. Acquires ownership of a fast mutex. */
  343. void
  344. os_fast_mutex_lock(
  345. /*===============*/
  346. os_fast_mutex_t* fast_mutex) /* in: mutex to acquire */
  347. {
  348. #ifdef __WIN__
  349. EnterCriticalSection((LPCRITICAL_SECTION) fast_mutex);
  350. #else
  351. pthread_mutex_lock(fast_mutex);
  352. #endif
  353. }
  354. /**************************************************************
  355. Frees a mutex object. */
  356. void
  357. os_fast_mutex_free(
  358. /*===============*/
  359. os_fast_mutex_t* fast_mutex) /* in: mutex to free */
  360. {
  361. #ifdef __WIN__
  362. ut_a(fast_mutex);
  363. DeleteCriticalSection((LPCRITICAL_SECTION) fast_mutex);
  364. #else
  365. UT_NOT_USED(fast_mutex);
  366. #endif
  367. }
  368. #endif