2010-02-13 Jb Evain <jbevain@novell.com>
[mono-project.git] / mono / io-layer / critical-sections.c
blob3d2700da962f6a84d8ee34c964fcfe2a92c8ac64
1 /*
2 * critical-sections.c: Critical sections
4 * Author:
5 * Dick Porter (dick@ximian.com)
7 * (C) 2002 Ximian, Inc.
8 */
10 #include <config.h>
11 #include <glib.h>
12 #include <pthread.h>
14 #include <mono/io-layer/wapi.h>
15 #include <mono/io-layer/critical-section-private.h>
17 #include "mono-mutex.h"
19 #undef DEBUG
21 /* A critical section is really just like a lightweight mutex. It
22 * can't be waited for, and doesn't have a handle.
25 /* According to the MSDN docs, the Microsoft implementation spins a
26 * number of times then waits for a semaphore. I could implement that
27 * here but I'd need a mutex around the critical section structure
28 * anyway. So I may as well just use a pthread mutex.
30 static mono_once_t attr_key_once=MONO_ONCE_INIT;
31 static mono_mutexattr_t attr;
33 static void attr_init(void)
35 int ret;
37 ret = mono_mutexattr_init(&attr);
38 g_assert (ret == 0);
40 ret = mono_mutexattr_settype(&attr, MONO_MUTEX_RECURSIVE);
41 g_assert (ret == 0);
44 void _wapi_critical_section_cleanup (void)
46 mono_mutexattr_destroy (&attr);
49 /**
50 * InitializeCriticalSection:
51 * @section: The critical section to initialise
53 * Initialises a critical section.
55 void InitializeCriticalSection(WapiCriticalSection *section)
57 int ret;
59 mono_once(&attr_key_once, attr_init);
60 ret = mono_mutex_init(&section->mutex, &attr);
61 g_assert (ret == 0);
64 /**
65 * InitializeCriticalSectionAndSpinCount:
66 * @section: The critical section to initialise.
67 * @spincount: The spin count for this critical section. Not
68 * currently used.
70 * Initialises a critical section and sets the spin count. This
71 * implementation just calls InitializeCriticalSection().
73 * Return value: %TRUE on success, %FALSE otherwise. (%FALSE never
74 * happens).
76 gboolean InitializeCriticalSectionAndSpinCount(WapiCriticalSection *section,
77 guint32 spincount G_GNUC_UNUSED)
79 InitializeCriticalSection(section);
81 return(TRUE);
84 /**
85 * DeleteCriticalSection:
86 * @section: The critical section to delete.
88 * Releases all resources owned by critical section @section.
90 void DeleteCriticalSection(WapiCriticalSection *section)
92 int ret;
94 ret = mono_mutex_destroy(&section->mutex);
95 g_assert (ret == 0);
98 /**
99 * SetCriticalSectionSpinCount:
100 * @section: The critical section to set
101 * @spincount: The new spin count for this critical section. Not
102 * currently used.
104 * Sets the spin count for the critical section @section. The spin
105 * count is currently ignored, and set to zero.
107 * Return value: The previous spin count. (Currently always zero).
109 guint32 SetCriticalSectionSpinCount(WapiCriticalSection *section G_GNUC_UNUSED, guint32 spincount G_GNUC_UNUSED)
111 return(0);
115 * TryEnterCriticalSection:
116 * @section: The critical section to try and enter
118 * Attempts to enter a critical section without blocking. If
119 * successful the calling thread takes ownership of the critical
120 * section.
122 * A thread can recursively call EnterCriticalSection() and
123 * TryEnterCriticalSection(), but must call LeaveCriticalSection() an
124 * equal number of times.
126 * Return value: %TRUE if the thread successfully locked the critical
127 * section, %FALSE otherwise.
129 gboolean TryEnterCriticalSection(WapiCriticalSection *section)
131 int ret;
133 ret=mono_mutex_trylock(&section->mutex);
134 if(ret==0) {
135 return(TRUE);
136 } else {
137 return(FALSE);