1/*-------------------------------------------------------------------------
2 * drawElements Thread Library
3 * ---------------------------
4 *
5 * Copyright 2014 The Android Open Source Project
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 *      http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 *//*!
20 * \file
21 * \brief Unix implementation of mutex.
22 *//*--------------------------------------------------------------------*/
23
24#include "deMutex.h"
25
26#if (DE_OS == DE_OS_UNIX || DE_OS == DE_OS_OSX || DE_OS == DE_OS_ANDROID || DE_OS == DE_OS_SYMBIAN || DE_OS == DE_OS_IOS)
27
28#include "deMemory.h"
29
30#include <pthread.h>
31
32/* \todo [2009-11-12 pyry] It is quite nasty to allocate mutex structs from heap. */
33
34DE_STATIC_ASSERT(sizeof(deMutex) >= sizeof(pthread_mutex_t*));
35
36deMutex deMutex_create (const deMutexAttributes* attributes)
37{
38	pthread_mutexattr_t	attr;
39	int					ret;
40	pthread_mutex_t*	mutex = deMalloc(sizeof(pthread_mutex_t));
41
42	if (!mutex)
43		return 0;
44
45	if (pthread_mutexattr_init(&attr) != 0)
46	{
47		deFree(mutex);
48		return 0;
49	}
50
51#if defined(DE_DEBUG)
52	if (pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK) != 0)
53#else
54	if (pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_NORMAL) != 0)
55#endif
56	{
57		pthread_mutexattr_destroy(&attr);
58		deFree(mutex);
59		return 0;
60	}
61
62	if (attributes)
63	{
64		if (attributes->flags & DE_MUTEX_RECURSIVE)
65		{
66			if (pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE) != 0)
67			{
68				pthread_mutexattr_destroy(&attr);
69				deFree(mutex);
70				return 0;
71			}
72		}
73	}
74
75	ret = pthread_mutex_init(mutex, &attr);
76	if (ret != 0)
77	{
78		pthread_mutexattr_destroy(&attr);
79		deFree(mutex);
80		return 0;
81	}
82
83	pthread_mutexattr_destroy(&attr);
84
85	return (deMutex)mutex;
86}
87
88void deMutex_destroy (deMutex mutex)
89{
90	pthread_mutex_t* pMutex = (pthread_mutex_t*)mutex;
91	DE_ASSERT(pMutex);
92	pthread_mutex_destroy(pMutex);
93	deFree(pMutex);
94}
95
96void deMutex_lock (deMutex mutex)
97{
98	int ret = pthread_mutex_lock((pthread_mutex_t*)mutex);
99	DE_ASSERT(ret == 0);
100	DE_UNREF(ret);
101}
102
103void deMutex_unlock (deMutex mutex)
104{
105	int ret = pthread_mutex_unlock((pthread_mutex_t*)mutex);
106	DE_ASSERT(ret == 0);
107	DE_UNREF(ret);
108}
109
110deBool deMutex_tryLock (deMutex mutex)
111{
112	return (pthread_mutex_trylock((pthread_mutex_t*)mutex) == 0);
113}
114
115#endif /* DE_OS */
116