Home | History | Annotate | Download | only in unix
      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 
     34 DE_STATIC_ASSERT(sizeof(deMutex) >= sizeof(pthread_mutex_t*));
     35 
     36 deMutex 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 
     88 void 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 
     96 void 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 
    103 void 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 
    110 deBool deMutex_tryLock (deMutex mutex)
    111 {
    112 	return (pthread_mutex_trylock((pthread_mutex_t*)mutex) == 0);
    113 }
    114 
    115 #endif /* DE_OS */
    116