summaryrefslogtreecommitdiffstats
path: root/contrib/restricted/wavm/Lib/Platform/POSIX/MutexPOSIX.cpp
blob: 874b0aa1259f7f3eb905a4d796298a542f5ddac4 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
#include <pthread.h>
#include "WAVM/Inline/Assert.h"
#include "WAVM/Inline/Errors.h"
#include "WAVM/Platform/Defines.h"
#include "WAVM/Platform/Mutex.h"

using namespace WAVM;
using namespace WAVM::Platform;

Platform::Mutex::Mutex()
{
	static_assert(sizeof(LockData) >= sizeof(pthread_mutex_t), "");
	static_assert(alignof(LockData) >= alignof(pthread_mutex_t), "");

#if WAVM_ENABLE_ASSERTS
	// Use a recursive mutex in debug builds to support isLockedByCurrentThread.
	pthread_mutexattr_t pthreadMutexAttr;
	WAVM_ERROR_UNLESS(!pthread_mutexattr_init(&pthreadMutexAttr));
	WAVM_ERROR_UNLESS(!pthread_mutexattr_settype(&pthreadMutexAttr, PTHREAD_MUTEX_RECURSIVE));
	WAVM_ERROR_UNLESS(!pthread_mutex_init((pthread_mutex_t*)&lockData, &pthreadMutexAttr));
	WAVM_ERROR_UNLESS(!pthread_mutexattr_destroy(&pthreadMutexAttr));
	isLocked = false;
#else
	WAVM_ERROR_UNLESS(!pthread_mutex_init((pthread_mutex_t*)&lockData, nullptr));
#endif
}

Platform::Mutex::~Mutex()
{
	WAVM_ERROR_UNLESS(!pthread_mutex_destroy((pthread_mutex_t*)&lockData));
}

void Platform::Mutex::lock()
{
	WAVM_ERROR_UNLESS(!pthread_mutex_lock((pthread_mutex_t*)&lockData));
#if WAVM_ENABLE_ASSERTS
	if(isLocked) { Errors::fatal("Recursive mutex lock"); }
	isLocked = true;
#endif
}

void Platform::Mutex::unlock()
{
#if WAVM_ENABLE_ASSERTS
	isLocked = false;
#endif
	WAVM_ERROR_UNLESS(!pthread_mutex_unlock((pthread_mutex_t*)&lockData));
}

#if WAVM_ENABLE_ASSERTS
bool Platform::Mutex::isLockedByCurrentThread()
{
	// Try to lock the mutex, and if EDEADLK is returned, it means the mutex was already locked by
	// this thread.
	int tryLockResult = pthread_mutex_trylock((pthread_mutex_t*)&lockData);
	if(tryLockResult) { return false; }

	const bool result = isLocked;
	WAVM_ERROR_UNLESS(!pthread_mutex_unlock((pthread_mutex_t*)&lockData));
	return result;
}
#endif