ObjFW  Check-in [dfd52d5220]

Overview
Comment:of_mutex_t -> OFPlainMutex

Also rename of_rmutex_t -> OFPlainRecursiveMutex.

Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | new-naming-convention
Files: files | file ages | folders
SHA3-256: dfd52d5220f098541e8179aae0d7c4c5a3c41828572540de1b28d9e0422c5ba7
User & Date: js on 2021-04-17 16:24:13
Other Links: branch diff | manifest | tags
Context
2021-04-17
16:29
of_spinlock_t -> OFSpinlock check-in: fabf53041a user: js tags: new-naming-convention
16:24
of_mutex_t -> OFPlainMutex check-in: dfd52d5220 user: js tags: new-naming-convention
16:13
of_once_t -> OFOnceControl check-in: 26aa88fc9b user: js tags: new-naming-convention
Changes

Modified src/OFMutex.h from [e51e28c02b] to [5171988a3a].

23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
/**
 * @class OFMutex OFMutex.h ObjFW/OFMutex.h
 *
 * @brief A class for creating mutual exclusions.
 */
@interface OFMutex: OFObject <OFLocking>
{
	of_mutex_t _mutex;
	bool _initialized;
	OFString *_Nullable _name;
	OF_RESERVE_IVARS(OFMutex, 4)
}

/**
 * @brief Creates a new mutex.







|







23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
/**
 * @class OFMutex OFMutex.h ObjFW/OFMutex.h
 *
 * @brief A class for creating mutual exclusions.
 */
@interface OFMutex: OFObject <OFLocking>
{
	OFPlainMutex _mutex;
	bool _initialized;
	OFString *_Nullable _name;
	OF_RESERVE_IVARS(OFMutex, 4)
}

/**
 * @brief Creates a new mutex.

Modified src/OFMutex.m from [8256799039] to [beea68f36f].

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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
	return [[[self alloc] init] autorelease];
}

- (instancetype)init
{
	self = [super init];

	if (of_mutex_new(&_mutex) != 0) {
		Class c = self.class;
		[self release];
		@throw [OFInitializationFailedException exceptionWithClass: c];
	}

	_initialized = true;

	return self;
}

- (void)dealloc
{
	if (_initialized) {
		int error = of_mutex_free(&_mutex);

		if (error != 0) {
			OF_ENSURE(error == EBUSY);

			@throw [OFStillLockedException exceptionWithLock: self];
		}
	}

	[_name release];

	[super dealloc];
}

- (void)lock
{
	int error = of_mutex_lock(&_mutex);

	if (error != 0)
		@throw [OFLockFailedException exceptionWithLock: self
							  errNo: error];
}

- (bool)tryLock
{
	int error = of_mutex_trylock(&_mutex);

	if (error != 0) {
		if (error == EBUSY)
			return false;
		else
			@throw [OFLockFailedException exceptionWithLock: self
								  errNo: error];
	}

	return true;
}

- (void)unlock
{
	int error = of_mutex_unlock(&_mutex);

	if (error != 0)
		@throw [OFUnlockFailedException exceptionWithLock: self
							    errNo: error];
}

- (OFString *)description







|













|















|








|














|







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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
	return [[[self alloc] init] autorelease];
}

- (instancetype)init
{
	self = [super init];

	if (OFPlainMutexNew(&_mutex) != 0) {
		Class c = self.class;
		[self release];
		@throw [OFInitializationFailedException exceptionWithClass: c];
	}

	_initialized = true;

	return self;
}

- (void)dealloc
{
	if (_initialized) {
		int error = OFPlainMutexFree(&_mutex);

		if (error != 0) {
			OF_ENSURE(error == EBUSY);

			@throw [OFStillLockedException exceptionWithLock: self];
		}
	}

	[_name release];

	[super dealloc];
}

- (void)lock
{
	int error = OFPlainMutexLock(&_mutex);

	if (error != 0)
		@throw [OFLockFailedException exceptionWithLock: self
							  errNo: error];
}

- (bool)tryLock
{
	int error = OFPlainMutexTryLock(&_mutex);

	if (error != 0) {
		if (error == EBUSY)
			return false;
		else
			@throw [OFLockFailedException exceptionWithLock: self
								  errNo: error];
	}

	return true;
}

- (void)unlock
{
	int error = OFPlainMutexUnlock(&_mutex);

	if (error != 0)
		@throw [OFUnlockFailedException exceptionWithLock: self
							    errNo: error];
}

- (OFString *)description

Modified src/OFRecursiveMutex.h from [d6ed860e64] to [7583593446].

25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
 *
 * @brief A class for creating mutual exclusions which can be entered
 *	  recursively.
 */
OF_SUBCLASSING_RESTRICTED
@interface OFRecursiveMutex: OFObject <OFLocking>
{
	of_rmutex_t _rmutex;
	bool _initialized;
	OFString *_Nullable _name;
}

/**
 * @brief Creates a new recursive mutex.
 *
 * @return A new autoreleased recursive mutex.
 */
+ (instancetype)mutex;
@end

OF_ASSUME_NONNULL_END







|













25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
 *
 * @brief A class for creating mutual exclusions which can be entered
 *	  recursively.
 */
OF_SUBCLASSING_RESTRICTED
@interface OFRecursiveMutex: OFObject <OFLocking>
{
	OFPlainRecursiveMutex _rmutex;
	bool _initialized;
	OFString *_Nullable _name;
}

/**
 * @brief Creates a new recursive mutex.
 *
 * @return A new autoreleased recursive mutex.
 */
+ (instancetype)mutex;
@end

OF_ASSUME_NONNULL_END

Modified src/OFRecursiveMutex.m from [14f9082e7e] to [f6b5e7fc87].

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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
	return [[[self alloc] init] autorelease];
}

- (instancetype)init
{
	self = [super init];

	if (of_rmutex_new(&_rmutex) != 0) {
		Class c = self.class;
		[self release];
		@throw [OFInitializationFailedException exceptionWithClass: c];
	}

	_initialized = true;

	return self;
}

- (void)dealloc
{
	if (_initialized) {
		int error = of_rmutex_free(&_rmutex);

		if (error != 0) {
			OF_ENSURE(error == EBUSY);

			@throw [OFStillLockedException exceptionWithLock: self];
		}
	}

	[_name release];

	[super dealloc];
}

- (void)lock
{
	int error = of_rmutex_lock(&_rmutex);

	if (error != 0)
		@throw [OFLockFailedException exceptionWithLock: self
							  errNo: error];
}

- (bool)tryLock
{
	int error = of_rmutex_trylock(&_rmutex);

	if (error != 0) {
		if (error == EBUSY)
			return false;
		else
			@throw [OFLockFailedException exceptionWithLock: self
								  errNo: error];
	}

	return true;
}

- (void)unlock
{
	int error = of_rmutex_unlock(&_rmutex);

	if (error != 0)
		@throw [OFUnlockFailedException exceptionWithLock: self
							    errNo: error];
}

- (OFString *)description







|













|















|








|














|







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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
	return [[[self alloc] init] autorelease];
}

- (instancetype)init
{
	self = [super init];

	if (OFPlainRecursiveMutexNew(&_rmutex) != 0) {
		Class c = self.class;
		[self release];
		@throw [OFInitializationFailedException exceptionWithClass: c];
	}

	_initialized = true;

	return self;
}

- (void)dealloc
{
	if (_initialized) {
		int error = OFPlainRecursiveMutexFree(&_rmutex);

		if (error != 0) {
			OF_ENSURE(error == EBUSY);

			@throw [OFStillLockedException exceptionWithLock: self];
		}
	}

	[_name release];

	[super dealloc];
}

- (void)lock
{
	int error = OFPlainRecursiveMutexLock(&_rmutex);

	if (error != 0)
		@throw [OFLockFailedException exceptionWithLock: self
							  errNo: error];
}

- (bool)tryLock
{
	int error = OFPlainRecursiveMutexTryLock(&_rmutex);

	if (error != 0) {
		if (error == EBUSY)
			return false;
		else
			@throw [OFLockFailedException exceptionWithLock: self
								  errNo: error];
	}

	return true;
}

- (void)unlock
{
	int error = OFPlainRecursiveMutexUnlock(&_rmutex);

	if (error != 0)
		@throw [OFUnlockFailedException exceptionWithLock: self
							    errNo: error];
}

- (OFString *)description

Modified src/condition.h from [0d9f4192a1] to [1ee99bce0d].

49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68

#ifdef __cplusplus
extern "C" {
#endif
extern int of_condition_new(of_condition_t *condition);
extern int of_condition_signal(of_condition_t *condition);
extern int of_condition_broadcast(of_condition_t *condition);
extern int of_condition_wait(of_condition_t *condition, of_mutex_t *mutex);
extern int of_condition_timed_wait(of_condition_t *condition,
    of_mutex_t *mutex, OFTimeInterval timeout);
#ifdef OF_AMIGAOS
extern int of_condition_wait_or_signal(of_condition_t *condition,
    of_mutex_t *mutex, ULONG *signalMask);
extern int of_condition_timed_wait_or_signal(of_condition_t *condition,
    of_mutex_t *mutex, OFTimeInterval timeout, ULONG *signalMask);
#endif
extern int of_condition_free(of_condition_t *condition);
#ifdef __cplusplus
}
#endif







|

|


|

|





49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68

#ifdef __cplusplus
extern "C" {
#endif
extern int of_condition_new(of_condition_t *condition);
extern int of_condition_signal(of_condition_t *condition);
extern int of_condition_broadcast(of_condition_t *condition);
extern int of_condition_wait(of_condition_t *condition, OFPlainMutex *mutex);
extern int of_condition_timed_wait(of_condition_t *condition,
    OFPlainMutex *mutex, OFTimeInterval timeout);
#ifdef OF_AMIGAOS
extern int of_condition_wait_or_signal(of_condition_t *condition,
    OFPlainMutex *mutex, ULONG *signalMask);
extern int of_condition_timed_wait_or_signal(of_condition_t *condition,
    OFPlainMutex *mutex, OFTimeInterval timeout, ULONG *signalMask);
#endif
extern int of_condition_free(of_condition_t *condition);
#ifdef __cplusplus
}
#endif

Modified src/exceptions/OFException.m from [c381d0d5f6] to [7a4b36018b].

65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
extern uintptr_t _Unwind_GetIP(struct _Unwind_Context *);
#else
extern int _Unwind_VRS_Get(struct _Unwind_Context *, int, uint32_t, int,
    void *);
#endif

#if !defined(HAVE_STRERROR_R) && defined(OF_HAVE_THREADS)
static of_mutex_t mutex;

OF_CONSTRUCTOR()
{
	OF_ENSURE(of_mutex_new(&mutex) == 0);
}

OF_DESTRUCTOR()
{
	of_mutex_free(&mutex);
}
#endif

OFString *
of_strerror(int errNo)
{
	OFString *ret;







|



|




|







65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
extern uintptr_t _Unwind_GetIP(struct _Unwind_Context *);
#else
extern int _Unwind_VRS_Get(struct _Unwind_Context *, int, uint32_t, int,
    void *);
#endif

#if !defined(HAVE_STRERROR_R) && defined(OF_HAVE_THREADS)
static OFPlainMutex mutex;

OF_CONSTRUCTOR()
{
	OF_ENSURE(OFPlainMutexNew(&mutex) == 0);
}

OF_DESTRUCTOR()
{
	OFPlainMutexFree(&mutex);
}
#endif

OFString *
of_strerror(int errNo)
{
	OFString *ret;
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
	if (strerror_r(errNo, buffer, 256) != 0)
		return @"Unknown error (strerror_r failed)";

	ret = [OFString stringWithCString: buffer
				 encoding: [OFLocale encoding]];
#else
# ifdef OF_HAVE_THREADS
	if (of_mutex_lock(&mutex) != 0)
		@throw [OFLockFailedException exception];

	@try {
# endif
		ret = [OFString
		    stringWithCString: strerror(errNo)
			     encoding: [OFLocale encoding]];
# ifdef OF_HAVE_THREADS
	} @finally {
		if (of_mutex_unlock(&mutex) != 0)
			@throw [OFUnlockFailedException exception];
	}
# endif
#endif

	return ret;
}







|









|







187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
	if (strerror_r(errNo, buffer, 256) != 0)
		return @"Unknown error (strerror_r failed)";

	ret = [OFString stringWithCString: buffer
				 encoding: [OFLocale encoding]];
#else
# ifdef OF_HAVE_THREADS
	if (OFPlainMutexLock(&mutex) != 0)
		@throw [OFLockFailedException exception];

	@try {
# endif
		ret = [OFString
		    stringWithCString: strerror(errNo)
			     encoding: [OFLocale encoding]];
# ifdef OF_HAVE_THREADS
	} @finally {
		if (OFPlainMutexUnlock(&mutex) != 0)
			@throw [OFUnlockFailedException exception];
	}
# endif
#endif

	return ret;
}

Modified src/mutex.h from [b00f51f16c] to [3c75ad2bae].

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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# error No mutexes available!
#endif

#import "macros.h"

#if defined(OF_HAVE_PTHREADS)
# include <pthread.h>
typedef pthread_mutex_t of_mutex_t;
#elif defined(OF_WINDOWS)
# include <windows.h>
typedef CRITICAL_SECTION of_mutex_t;
#elif defined(OF_AMIGAOS)
# include <exec/semaphores.h>
typedef struct SignalSemaphore of_mutex_t;
#endif

#if defined(OF_HAVE_ATOMIC_OPS)
# import "atomic.h"
typedef volatile int of_spinlock_t;
# define OF_SPINCOUNT 10
#elif defined(OF_HAVE_PTHREAD_SPINLOCKS)
typedef pthread_spinlock_t of_spinlock_t;
#else
typedef of_mutex_t of_spinlock_t;
#endif

#ifdef OF_HAVE_SCHED_YIELD
# include <sched.h>
#endif

#if defined(OF_HAVE_RECURSIVE_PTHREAD_MUTEXES) || defined(OF_WINDOWS) || \
    defined(OF_AMIGAOS)
# define of_rmutex_t of_mutex_t
#else
# import "tlskey.h"
typedef struct {
	of_mutex_t mutex;
	OFTLSKey count;
} of_rmutex_t;
#endif

#ifdef __cplusplus
extern "C" {
#endif
extern int of_mutex_new(of_mutex_t *mutex);
extern int of_mutex_lock(of_mutex_t *mutex);
extern int of_mutex_trylock(of_mutex_t *mutex);
extern int of_mutex_unlock(of_mutex_t *mutex);
extern int of_mutex_free(of_mutex_t *mutex);
extern int of_rmutex_new(of_rmutex_t *rmutex);
extern int of_rmutex_lock(of_rmutex_t *rmutex);
extern int of_rmutex_trylock(of_rmutex_t *rmutex);
extern int of_rmutex_unlock(of_rmutex_t *rmutex);
extern int of_rmutex_free(of_rmutex_t *rmutex);
#ifdef __cplusplus
}
#endif

/* Spinlocks are inlined for performance. */

static OF_INLINE void







|


|


|









|








|



|

|





|
|
|
|
|
|
|
|
|
|







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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# error No mutexes available!
#endif

#import "macros.h"

#if defined(OF_HAVE_PTHREADS)
# include <pthread.h>
typedef pthread_mutex_t OFPlainMutex;
#elif defined(OF_WINDOWS)
# include <windows.h>
typedef CRITICAL_SECTION OFPlainMutex;
#elif defined(OF_AMIGAOS)
# include <exec/semaphores.h>
typedef struct SignalSemaphore OFPlainMutex;
#endif

#if defined(OF_HAVE_ATOMIC_OPS)
# import "atomic.h"
typedef volatile int of_spinlock_t;
# define OF_SPINCOUNT 10
#elif defined(OF_HAVE_PTHREAD_SPINLOCKS)
typedef pthread_spinlock_t of_spinlock_t;
#else
typedef OFPlainMutex of_spinlock_t;
#endif

#ifdef OF_HAVE_SCHED_YIELD
# include <sched.h>
#endif

#if defined(OF_HAVE_RECURSIVE_PTHREAD_MUTEXES) || defined(OF_WINDOWS) || \
    defined(OF_AMIGAOS)
# define OFPlainRecursiveMutex OFPlainMutex
#else
# import "tlskey.h"
typedef struct {
	OFPlainMutex mutex;
	OFTLSKey count;
} OFPlainRecursiveMutex;
#endif

#ifdef __cplusplus
extern "C" {
#endif
extern int OFPlainMutexNew(OFPlainMutex *mutex);
extern int OFPlainMutexLock(OFPlainMutex *mutex);
extern int OFPlainMutexTryLock(OFPlainMutex *mutex);
extern int OFPlainMutexUnlock(OFPlainMutex *mutex);
extern int OFPlainMutexFree(OFPlainMutex *mutex);
extern int OFPlainRecursiveMutexNew(OFPlainRecursiveMutex *rmutex);
extern int OFPlainRecursiveMutexLock(OFPlainRecursiveMutex *rmutex);
extern int OFPlainRecursiveMutexTryLock(OFPlainRecursiveMutex *rmutex);
extern int OFPlainRecursiveMutexUnlock(OFPlainRecursiveMutex *rmutex);
extern int OFPlainRecursiveMutexFree(OFPlainRecursiveMutex *rmutex);
#ifdef __cplusplus
}
#endif

/* Spinlocks are inlined for performance. */

static OF_INLINE void
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
{
#if defined(OF_HAVE_ATOMIC_OPS)
	*spinlock = 0;
	return 0;
#elif defined(OF_HAVE_PTHREAD_SPINLOCKS)
	return pthread_spin_init(spinlock, 0);
#else
	return of_mutex_new(spinlock);
#endif
}

static OF_INLINE int
of_spinlock_trylock(of_spinlock_t *spinlock)
{
#if defined(OF_HAVE_ATOMIC_OPS)
	if (of_atomic_int_cmpswap(spinlock, 0, 1)) {
		of_memory_barrier_acquire();
		return 0;
	}

	return EBUSY;
#elif defined(OF_HAVE_PTHREAD_SPINLOCKS)
	return pthread_spin_trylock(spinlock);
#else
	return of_mutex_trylock(spinlock);
#endif
}

static OF_INLINE int
of_spinlock_lock(of_spinlock_t *spinlock)
{
#if defined(OF_HAVE_ATOMIC_OPS)
	size_t i;

	for (i = 0; i < OF_SPINCOUNT; i++)
		if (of_spinlock_trylock(spinlock) == 0)
			return 0;

	while (of_spinlock_trylock(spinlock) == EBUSY)
		OFYieldThread();

	return 0;
#elif defined(OF_HAVE_PTHREAD_SPINLOCKS)
	return pthread_spin_lock(spinlock);
#else
	return of_mutex_lock(spinlock);
#endif
}

static OF_INLINE int
of_spinlock_unlock(of_spinlock_t *spinlock)
{
#if defined(OF_HAVE_ATOMIC_OPS)
	bool ret = of_atomic_int_cmpswap(spinlock, 1, 0);

	of_memory_barrier_release();

	return (ret ? 0 : EINVAL);
#elif defined(OF_HAVE_PTHREAD_SPINLOCKS)
	return pthread_spin_unlock(spinlock);
#else
	return of_mutex_unlock(spinlock);
#endif
}

static OF_INLINE int
of_spinlock_free(of_spinlock_t *spinlock)
{
#if defined(OF_HAVE_ATOMIC_OPS)
	return 0;
#elif defined(OF_HAVE_PTHREAD_SPINLOCKS)
	return pthread_spin_destroy(spinlock);
#else
	return of_mutex_free(spinlock);
#endif
}







|
















|




















|















|











|


96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
{
#if defined(OF_HAVE_ATOMIC_OPS)
	*spinlock = 0;
	return 0;
#elif defined(OF_HAVE_PTHREAD_SPINLOCKS)
	return pthread_spin_init(spinlock, 0);
#else
	return OFPlainMutexNew(spinlock);
#endif
}

static OF_INLINE int
of_spinlock_trylock(of_spinlock_t *spinlock)
{
#if defined(OF_HAVE_ATOMIC_OPS)
	if (of_atomic_int_cmpswap(spinlock, 0, 1)) {
		of_memory_barrier_acquire();
		return 0;
	}

	return EBUSY;
#elif defined(OF_HAVE_PTHREAD_SPINLOCKS)
	return pthread_spin_trylock(spinlock);
#else
	return OFPlainMutexTryLock(spinlock);
#endif
}

static OF_INLINE int
of_spinlock_lock(of_spinlock_t *spinlock)
{
#if defined(OF_HAVE_ATOMIC_OPS)
	size_t i;

	for (i = 0; i < OF_SPINCOUNT; i++)
		if (of_spinlock_trylock(spinlock) == 0)
			return 0;

	while (of_spinlock_trylock(spinlock) == EBUSY)
		OFYieldThread();

	return 0;
#elif defined(OF_HAVE_PTHREAD_SPINLOCKS)
	return pthread_spin_lock(spinlock);
#else
	return OFPlainMutexLock(spinlock);
#endif
}

static OF_INLINE int
of_spinlock_unlock(of_spinlock_t *spinlock)
{
#if defined(OF_HAVE_ATOMIC_OPS)
	bool ret = of_atomic_int_cmpswap(spinlock, 1, 0);

	of_memory_barrier_release();

	return (ret ? 0 : EINVAL);
#elif defined(OF_HAVE_PTHREAD_SPINLOCKS)
	return pthread_spin_unlock(spinlock);
#else
	return OFPlainMutexUnlock(spinlock);
#endif
}

static OF_INLINE int
of_spinlock_free(of_spinlock_t *spinlock)
{
#if defined(OF_HAVE_ATOMIC_OPS)
	return 0;
#elif defined(OF_HAVE_PTHREAD_SPINLOCKS)
	return pthread_spin_destroy(spinlock);
#else
	return OFPlainMutexFree(spinlock);
#endif
}

Modified src/platform/amiga/condition.m from [dc620431f9] to [cc3230123e].

70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
		Permit();
	}

	return 0;
}

int
of_condition_wait(of_condition_t *condition, of_mutex_t *mutex)
{
	ULONG signalMask = 0;

	return of_condition_wait_or_signal(condition, mutex, &signalMask);
}

int
of_condition_wait_or_signal(of_condition_t *condition, of_mutex_t *mutex,
    ULONG *signalMask)
{
	struct of_condition_waiting_task waitingTask = {
		.task = FindTask(NULL),
		.sigBit = AllocSignal(-1)
	};
	int error = 0;
	ULONG mask;

	if (waitingTask.sigBit == -1)
		return EAGAIN;

	Forbid();

	if ((error = of_mutex_unlock(mutex)) != 0) {
		FreeSignal(waitingTask.sigBit);
		return error;
	}

	waitingTask.next = condition->waitingTasks;
	condition->waitingTasks = &waitingTask;

	mask = Wait((1ul << waitingTask.sigBit) | *signalMask);
	if (mask & (1ul << waitingTask.sigBit) || (*signalMask &= mask))
		error = of_mutex_lock(mutex);
	else
		/*
		 * This should not happen - it means something interrupted the
		 * Wait(), so the best we can do is return EINTR.
		 */
		error = EINTR;

	FreeSignal(waitingTask.sigBit);

	Permit();

	return error;
}

int
of_condition_timed_wait(of_condition_t *condition, of_mutex_t *mutex,
    OFTimeInterval timeout)
{
	ULONG signalMask = 0;

	return of_condition_timed_wait_or_signal(condition, mutex, timeout,
	    &signalMask);
}

int
of_condition_timed_wait_or_signal(of_condition_t *condition, of_mutex_t *mutex,
    OFTimeInterval timeout, ULONG *signalMask)
{
	struct of_condition_waiting_task waitingTask = {
		.task = FindTask(NULL),
		.sigBit = AllocSignal(-1)
	};
	struct MsgPort port = {
		.mp_Node = {







|







|














|









|















|









|
|







70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
		Permit();
	}

	return 0;
}

int
of_condition_wait(of_condition_t *condition, OFPlainMutex *mutex)
{
	ULONG signalMask = 0;

	return of_condition_wait_or_signal(condition, mutex, &signalMask);
}

int
of_condition_wait_or_signal(of_condition_t *condition, OFPlainMutex *mutex,
    ULONG *signalMask)
{
	struct of_condition_waiting_task waitingTask = {
		.task = FindTask(NULL),
		.sigBit = AllocSignal(-1)
	};
	int error = 0;
	ULONG mask;

	if (waitingTask.sigBit == -1)
		return EAGAIN;

	Forbid();

	if ((error = OFPlainMutexUnlock(mutex)) != 0) {
		FreeSignal(waitingTask.sigBit);
		return error;
	}

	waitingTask.next = condition->waitingTasks;
	condition->waitingTasks = &waitingTask;

	mask = Wait((1ul << waitingTask.sigBit) | *signalMask);
	if (mask & (1ul << waitingTask.sigBit) || (*signalMask &= mask))
		error = OFPlainMutexLock(mutex);
	else
		/*
		 * This should not happen - it means something interrupted the
		 * Wait(), so the best we can do is return EINTR.
		 */
		error = EINTR;

	FreeSignal(waitingTask.sigBit);

	Permit();

	return error;
}

int
of_condition_timed_wait(of_condition_t *condition, OFPlainMutex *mutex,
    OFTimeInterval timeout)
{
	ULONG signalMask = 0;

	return of_condition_timed_wait_or_signal(condition, mutex, timeout,
	    &signalMask);
}

int
of_condition_timed_wait_or_signal(of_condition_t *condition,
    OFPlainMutex *mutex, OFTimeInterval timeout, ULONG *signalMask)
{
	struct of_condition_waiting_task waitingTask = {
		.task = FindTask(NULL),
		.sigBit = AllocSignal(-1)
	};
	struct MsgPort port = {
		.mp_Node = {
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
	    (struct IORequest *)&request, 0) != 0) {
		error = EAGAIN;
		goto fail;
	}

	Forbid();

	if ((error = of_mutex_unlock(mutex)) != 0) {
		Permit();
		goto fail;
	}

	waitingTask.next = condition->waitingTasks;
	condition->waitingTasks = &waitingTask;

	SendIO((struct IORequest *)&request);

	mask = Wait((1ul << waitingTask.sigBit) | (1ul << port.mp_SigBit) |
	    *signalMask);
	if (mask & (1ul << waitingTask.sigBit) || (*signalMask &= mask))
		error = of_mutex_lock(mutex);
	else if (mask & (1ul << port.mp_SigBit))
		error = ETIMEDOUT;
	else
		/*
		 * This should not happen - it means something interrupted the
		 * Wait(), so the best we can do is return EINTR.
		 */







|












|







190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
	    (struct IORequest *)&request, 0) != 0) {
		error = EAGAIN;
		goto fail;
	}

	Forbid();

	if ((error = OFPlainMutexUnlock(mutex)) != 0) {
		Permit();
		goto fail;
	}

	waitingTask.next = condition->waitingTasks;
	condition->waitingTasks = &waitingTask;

	SendIO((struct IORequest *)&request);

	mask = Wait((1ul << waitingTask.sigBit) | (1ul << port.mp_SigBit) |
	    *signalMask);
	if (mask & (1ul << waitingTask.sigBit) || (*signalMask &= mask))
		error = OFPlainMutexLock(mutex);
	else if (mask & (1ul << port.mp_SigBit))
		error = ETIMEDOUT;
	else
		/*
		 * This should not happen - it means something interrupted the
		 * Wait(), so the best we can do is return EINTR.
		 */

Modified src/platform/amiga/mutex.m from [e7b8301e49] to [e655c5c2cf].

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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
#include <errno.h>

#import "mutex.h"

#include <proto/exec.h>

int
of_mutex_new(of_mutex_t *mutex)
{
	InitSemaphore(mutex);

	return 0;
}

int
of_mutex_lock(of_mutex_t *mutex)
{
	ObtainSemaphore(mutex);

	return 0;
}

int
of_mutex_trylock(of_mutex_t *mutex)
{
	if (!AttemptSemaphore(mutex))
		return EBUSY;

	return 0;
}

int
of_mutex_unlock(of_mutex_t *mutex)
{
	ReleaseSemaphore(mutex);

	return 0;
}

int
of_mutex_free(of_mutex_t *mutex)
{
	return 0;
}

int
of_rmutex_new(of_rmutex_t *rmutex)
{
	return of_mutex_new(rmutex);
}

int
of_rmutex_lock(of_rmutex_t *rmutex)
{
	return of_mutex_lock(rmutex);
}

int
of_rmutex_trylock(of_rmutex_t *rmutex)
{
	return of_mutex_trylock(rmutex);
}

int
of_rmutex_unlock(of_rmutex_t *rmutex)
{
	return of_mutex_unlock(rmutex);
}

int
of_rmutex_free(of_rmutex_t *rmutex)
{
	return of_mutex_free(rmutex);
}







|







|







|








|







|





|

|



|

|



|

|



|

|



|

|

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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
#include <errno.h>

#import "mutex.h"

#include <proto/exec.h>

int
OFPlainMutexNew(OFPlainMutex *mutex)
{
	InitSemaphore(mutex);

	return 0;
}

int
OFPlainMutexLock(OFPlainMutex *mutex)
{
	ObtainSemaphore(mutex);

	return 0;
}

int
OFPlainMutexTryLock(OFPlainMutex *mutex)
{
	if (!AttemptSemaphore(mutex))
		return EBUSY;

	return 0;
}

int
OFPlainMutexUnlock(OFPlainMutex *mutex)
{
	ReleaseSemaphore(mutex);

	return 0;
}

int
OFPlainMutexFree(OFPlainMutex *mutex)
{
	return 0;
}

int
OFPlainRecursiveMutexNew(OFPlainRecursiveMutex *rmutex)
{
	return OFPlainMutexNew(rmutex);
}

int
OFPlainRecursiveMutexLock(OFPlainRecursiveMutex *rmutex)
{
	return OFPlainMutexLock(rmutex);
}

int
OFPlainRecursiveMutexTryLock(OFPlainRecursiveMutex *rmutex)
{
	return OFPlainMutexTryLock(rmutex);
}

int
OFPlainRecursiveMutexUnlock(OFPlainRecursiveMutex *rmutex)
{
	return OFPlainMutexUnlock(rmutex);
}

int
OFPlainRecursiveMutexFree(OFPlainRecursiveMutex *rmutex)
{
	return OFPlainMutexFree(rmutex);
}

Modified src/platform/posix/condition.m from [7ce4083f77] to [04e776f8bc].

32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
int
of_condition_broadcast(of_condition_t *condition)
{
	return pthread_cond_broadcast(condition);
}

int
of_condition_wait(of_condition_t *condition, of_mutex_t *mutex)
{
	return pthread_cond_wait(condition, mutex);
}

int
of_condition_timed_wait(of_condition_t *condition, of_mutex_t *mutex,
    OFTimeInterval timeout)
{
	struct timespec ts;

	ts.tv_sec = (time_t)timeout;
	ts.tv_nsec = (long)((timeout - ts.tv_sec) * 1000000000);








|





|







32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
int
of_condition_broadcast(of_condition_t *condition)
{
	return pthread_cond_broadcast(condition);
}

int
of_condition_wait(of_condition_t *condition, OFPlainMutex *mutex)
{
	return pthread_cond_wait(condition, mutex);
}

int
of_condition_timed_wait(of_condition_t *condition, OFPlainMutex *mutex,
    OFTimeInterval timeout)
{
	struct timespec ts;

	ts.tv_sec = (time_t)timeout;
	ts.tv_nsec = (long)((timeout - ts.tv_sec) * 1000000000);

Modified src/platform/posix/mutex.m from [292d31cec6] to [c8763c1f31].

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
 */

#include "config.h"

#import "mutex.h"

int
of_mutex_new(of_mutex_t *mutex)
{
	return pthread_mutex_init(mutex, NULL);
}

int
of_mutex_lock(of_mutex_t *mutex)
{
	return pthread_mutex_lock(mutex);
}

int
of_mutex_trylock(of_mutex_t *mutex)
{
	return pthread_mutex_trylock(mutex);
}

int
of_mutex_unlock(of_mutex_t *mutex)
{
	return pthread_mutex_unlock(mutex);
}

int
of_mutex_free(of_mutex_t *mutex)
{
	return pthread_mutex_destroy(mutex);
}

#ifdef OF_HAVE_RECURSIVE_PTHREAD_MUTEXES
int
of_rmutex_new(of_rmutex_t *rmutex)
{
	int error;
	pthread_mutexattr_t attr;

	if ((error = pthread_mutexattr_init(&attr)) != 0)
		return error;








|





|





|





|





|






|







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
 */

#include "config.h"

#import "mutex.h"

int
OFPlainMutexNew(OFPlainMutex *mutex)
{
	return pthread_mutex_init(mutex, NULL);
}

int
OFPlainMutexLock(OFPlainMutex *mutex)
{
	return pthread_mutex_lock(mutex);
}

int
OFPlainMutexTryLock(OFPlainMutex *mutex)
{
	return pthread_mutex_trylock(mutex);
}

int
OFPlainMutexUnlock(OFPlainMutex *mutex)
{
	return pthread_mutex_unlock(mutex);
}

int
OFPlainMutexFree(OFPlainMutex *mutex)
{
	return pthread_mutex_destroy(mutex);
}

#ifdef OF_HAVE_RECURSIVE_PTHREAD_MUTEXES
int
OFPlainRecursiveMutexNew(OFPlainRecursiveMutex *rmutex)
{
	int error;
	pthread_mutexattr_t attr;

	if ((error = pthread_mutexattr_init(&attr)) != 0)
		return error;

67
68
69
70
71
72
73




74


75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111




112





















113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
	if ((error = pthread_mutexattr_destroy(&attr)) != 0)
		return error;

	return 0;
}

int




of_rmutex_lock(of_rmutex_t *rmutex)


{
	return of_mutex_lock(rmutex);
}

int
of_rmutex_trylock(of_rmutex_t *rmutex)
{
	return of_mutex_trylock(rmutex);
}

int
of_rmutex_unlock(of_rmutex_t *rmutex)
{
	return of_mutex_unlock(rmutex);
}

int
of_rmutex_free(of_rmutex_t *rmutex)
{
	return of_mutex_free(rmutex);
}
#else
int
of_rmutex_new(of_rmutex_t *rmutex)
{
	int error;

	if ((error = of_mutex_new(&rmutex->mutex)) != 0)
		return error;

	if ((error = OFTLSKeyNew(&rmutex->count)) != 0)
		return error;

	return 0;
}

int




of_rmutex_lock(of_rmutex_t *rmutex)





















{
	uintptr_t count = (uintptr_t)OFTLSKeyGet(rmutex->count);
	int error;

	if (count > 0) {
		if ((error = OFTLSKeySet(rmutex->count,
		    (void *)(count + 1))) != 0)
			return error;

		return 0;
	}

	if ((error = of_mutex_lock(&rmutex->mutex)) != 0)
		return error;

	if ((error = OFTLSKeySet(rmutex->count, (void *)1)) != 0) {
		of_mutex_unlock(&rmutex->mutex);
		return error;
	}

	return 0;
}

int
of_rmutex_trylock(of_rmutex_t *rmutex)
{
	uintptr_t count = (uintptr_t)OFTLSKeyGet(rmutex->count);
	int error;

	if (count > 0) {
		if ((error = OFTLSKeySet(rmutex->count,
		    (void *)(count + 1))) != 0)
			return error;

		return 0;
	}

	if ((error = of_mutex_trylock(&rmutex->mutex)) != 0)
		return error;

	if ((error = OFTLSKeySet(rmutex->count, (void *)1)) != 0) {
		of_mutex_unlock(&rmutex->mutex);
		return error;
	}

	return 0;
}

int
of_rmutex_unlock(of_rmutex_t *rmutex)
{
	uintptr_t count = (uintptr_t)OFTLSKeyGet(rmutex->count);
	int error;

	if (count > 1) {
		if ((error = OFTLSKeySet(rmutex->count,
		    (void *)(count - 1))) != 0)
			return error;

		return 0;
	}

	if ((error = OFTLSKeySet(rmutex->count, (void *)0)) != 0)
		return error;

	if ((error = of_mutex_unlock(&rmutex->mutex)) != 0)
		return error;

	return 0;
}

int
of_rmutex_free(of_rmutex_t *rmutex)
{
	int error;

	if ((error = of_mutex_free(&rmutex->mutex)) != 0)
		return error;

	if ((error = OFTLSKeyFree(rmutex->count)) != 0)
		return error;

	return 0;
}
#endif







>
>
>
>
|
>
>

|



|

|



<
<
<
<
|
<
<

|



|



|









>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>












|



|







<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<















|






|



|








67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91




92


93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161




162





















163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
	if ((error = pthread_mutexattr_destroy(&attr)) != 0)
		return error;

	return 0;
}

int
OFPlainRecursiveMutexLock(OFPlainRecursiveMutex *rmutex)
{
	return OFPlainMutexLock(rmutex);
}

int
OFPlainRecursiveMutexTryLock(OFPlainRecursiveMutex *rmutex)
{
	return OFPlainMutexTryLock(rmutex);
}

int
OFPlainRecursiveMutexUnlock(OFPlainRecursiveMutex *rmutex)
{
	return OFPlainMutexUnlock(rmutex);
}

int




OFPlainRecursiveMutexFree(OFPlainRecursiveMutex *rmutex)


{
	return OFPlainMutexFree(rmutex);
}
#else
int
OFPlainRecursiveMutexNew(OFPlainRecursiveMutex *rmutex)
{
	int error;

	if ((error = OFPlainMutexNew(&rmutex->mutex)) != 0)
		return error;

	if ((error = OFTLSKeyNew(&rmutex->count)) != 0)
		return error;

	return 0;
}

int
OFPlainRecursiveMutexLock(OFPlainRecursiveMutex *rmutex)
{
	uintptr_t count = (uintptr_t)OFTLSKeyGet(rmutex->count);
	int error;

	if (count > 0) {
		if ((error = OFTLSKeySet(rmutex->count,
		    (void *)(count + 1))) != 0)
			return error;

		return 0;
	}

	if ((error = OFPlainMutexLock(&rmutex->mutex)) != 0)
		return error;

	if ((error = OFTLSKeySet(rmutex->count, (void *)1)) != 0) {
		OFPlainMutexUnlock(&rmutex->mutex);
		return error;
	}

	return 0;
}

int
OFPlainRecursiveMutexTryLock(OFPlainRecursiveMutex *rmutex)
{
	uintptr_t count = (uintptr_t)OFTLSKeyGet(rmutex->count);
	int error;

	if (count > 0) {
		if ((error = OFTLSKeySet(rmutex->count,
		    (void *)(count + 1))) != 0)
			return error;

		return 0;
	}

	if ((error = OFPlainMutexTryLock(&rmutex->mutex)) != 0)
		return error;

	if ((error = OFTLSKeySet(rmutex->count, (void *)1)) != 0) {
		OFPlainMutexUnlock(&rmutex->mutex);
		return error;
	}

	return 0;
}

int




OFPlainRecursiveMutexUnlock(OFPlainRecursiveMutex *rmutex)





















{
	uintptr_t count = (uintptr_t)OFTLSKeyGet(rmutex->count);
	int error;

	if (count > 1) {
		if ((error = OFTLSKeySet(rmutex->count,
		    (void *)(count - 1))) != 0)
			return error;

		return 0;
	}

	if ((error = OFTLSKeySet(rmutex->count, (void *)0)) != 0)
		return error;

	if ((error = OFPlainMutexUnlock(&rmutex->mutex)) != 0)
		return error;

	return 0;
}

int
OFPlainRecursiveMutexFree(OFPlainRecursiveMutex *rmutex)
{
	int error;

	if ((error = OFPlainMutexFree(&rmutex->mutex)) != 0)
		return error;

	if ((error = OFTLSKeyFree(rmutex->count)) != 0)
		return error;

	return 0;
}
#endif

Modified src/platform/windows/condition.m from [595cdc3d8b] to [33e65b6da7].

63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
		}
	}

	return 0;
}

int
of_condition_wait(of_condition_t *condition, of_mutex_t *mutex)
{
	int error;
	DWORD status;

	if ((error = of_mutex_unlock(mutex)) != 0)
		return error;

	of_atomic_int_inc(&condition->count);
	status = WaitForSingleObject(condition->event, INFINITE);
	of_atomic_int_dec(&condition->count);

	switch (status) {
	case WAIT_OBJECT_0:
		return of_mutex_lock(mutex);
	case WAIT_FAILED:
		switch (GetLastError()) {
		case ERROR_INVALID_HANDLE:
			return EINVAL;
		default:
			OF_ENSURE(0);
		}
	default:
		OF_ENSURE(0);
	}
}

int
of_condition_timed_wait(of_condition_t *condition, of_mutex_t *mutex,
    OFTimeInterval timeout)
{
	int error;
	DWORD status;

	if ((error = of_mutex_unlock(mutex)) != 0)
		return error;

	of_atomic_int_inc(&condition->count);
	status = WaitForSingleObject(condition->event, timeout * 1000);
	of_atomic_int_dec(&condition->count);

	switch (status) {
	case WAIT_OBJECT_0:
		return of_mutex_lock(mutex);
	case WAIT_TIMEOUT:
		return ETIMEDOUT;
	case WAIT_FAILED:
		switch (GetLastError()) {
		case ERROR_INVALID_HANDLE:
			return EINVAL;
		default:







|




|








|













|





|








|







63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
		}
	}

	return 0;
}

int
of_condition_wait(of_condition_t *condition, OFPlainMutex *mutex)
{
	int error;
	DWORD status;

	if ((error = OFPlainMutexUnlock(mutex)) != 0)
		return error;

	of_atomic_int_inc(&condition->count);
	status = WaitForSingleObject(condition->event, INFINITE);
	of_atomic_int_dec(&condition->count);

	switch (status) {
	case WAIT_OBJECT_0:
		return OFPlainMutexLock(mutex);
	case WAIT_FAILED:
		switch (GetLastError()) {
		case ERROR_INVALID_HANDLE:
			return EINVAL;
		default:
			OF_ENSURE(0);
		}
	default:
		OF_ENSURE(0);
	}
}

int
of_condition_timed_wait(of_condition_t *condition, OFPlainMutex *mutex,
    OFTimeInterval timeout)
{
	int error;
	DWORD status;

	if ((error = OFPlainMutexUnlock(mutex)) != 0)
		return error;

	of_atomic_int_inc(&condition->count);
	status = WaitForSingleObject(condition->event, timeout * 1000);
	of_atomic_int_dec(&condition->count);

	switch (status) {
	case WAIT_OBJECT_0:
		return OFPlainMutexLock(mutex);
	case WAIT_TIMEOUT:
		return ETIMEDOUT;
	case WAIT_FAILED:
		switch (GetLastError()) {
		case ERROR_INVALID_HANDLE:
			return EINVAL;
		default:

Modified src/platform/windows/mutex.m from [ed38f771ab] to [32f709f554].

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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
#include <errno.h>

#import "mutex.h"

#include <windows.h>

int
of_mutex_new(of_mutex_t *mutex)
{
	InitializeCriticalSection(mutex);

	return 0;
}

int
of_mutex_lock(of_mutex_t *mutex)
{
	EnterCriticalSection(mutex);

	return 0;
}

int
of_mutex_trylock(of_mutex_t *mutex)
{
	if (!TryEnterCriticalSection(mutex))
		return EBUSY;

	return 0;
}

int
of_mutex_unlock(of_mutex_t *mutex)
{
	LeaveCriticalSection(mutex);

	return 0;
}

int
of_mutex_free(of_mutex_t *mutex)
{
	DeleteCriticalSection(mutex);

	return 0;
}

int
of_rmutex_new(of_rmutex_t *rmutex)
{
	return of_mutex_new(rmutex);
}

int
of_rmutex_lock(of_rmutex_t *rmutex)
{
	return of_mutex_lock(rmutex);
}

int
of_rmutex_trylock(of_rmutex_t *rmutex)
{
	return of_mutex_trylock(rmutex);
}

int
of_rmutex_unlock(of_rmutex_t *rmutex)
{
	return of_mutex_unlock(rmutex);
}

int
of_rmutex_free(of_rmutex_t *rmutex)
{
	return of_mutex_free(rmutex);
}







|







|







|








|







|







|

|



|

|



|

|



|

|



|

|

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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
#include <errno.h>

#import "mutex.h"

#include <windows.h>

int
OFPlainMutexNew(OFPlainMutex *mutex)
{
	InitializeCriticalSection(mutex);

	return 0;
}

int
OFPlainMutexLock(OFPlainMutex *mutex)
{
	EnterCriticalSection(mutex);

	return 0;
}

int
OFPlainMutexTryLock(OFPlainMutex *mutex)
{
	if (!TryEnterCriticalSection(mutex))
		return EBUSY;

	return 0;
}

int
OFPlainMutexUnlock(OFPlainMutex *mutex)
{
	LeaveCriticalSection(mutex);

	return 0;
}

int
OFPlainMutexFree(OFPlainMutex *mutex)
{
	DeleteCriticalSection(mutex);

	return 0;
}

int
OFPlainRecursiveMutexNew(OFPlainRecursiveMutex *rmutex)
{
	return OFPlainMutexNew(rmutex);
}

int
OFPlainRecursiveMutexLock(OFPlainRecursiveMutex *rmutex)
{
	return OFPlainMutexLock(rmutex);
}

int
OFPlainRecursiveMutexTryLock(OFPlainRecursiveMutex *rmutex)
{
	return OFPlainMutexTryLock(rmutex);
}

int
OFPlainRecursiveMutexUnlock(OFPlainRecursiveMutex *rmutex)
{
	return OFPlainMutexUnlock(rmutex);
}

int
OFPlainRecursiveMutexFree(OFPlainRecursiveMutex *rmutex)
{
	return OFPlainMutexFree(rmutex);
}

Modified src/runtime/synchronized.m from [fe8bbba7b5] to [0034717236].

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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137

#import "ObjFWRT.h"
#import "private.h"

#ifdef OF_HAVE_THREADS
# import "mutex.h"

static struct lock_s {
	id	      object;
	int	      count;
	of_rmutex_t   rmutex;
	struct lock_s *next;
} *locks = NULL;

static of_mutex_t mutex;

OF_CONSTRUCTOR()
{
	if (of_mutex_new(&mutex) != 0)
		OBJC_ERROR("Failed to create mutex!");
}
#endif

int
objc_sync_enter(id object)
{
	if (object == nil)
		return 0;

#ifdef OF_HAVE_THREADS
	struct lock_s *lock;

	if (of_mutex_lock(&mutex) != 0)
		OBJC_ERROR("Failed to lock mutex!");

	/* Look if we already have a lock */
	for (lock = locks; lock != NULL; lock = lock->next) {
		if (lock->object != object)
			continue;

		lock->count++;

		if (of_mutex_unlock(&mutex) != 0)
			OBJC_ERROR("Failed to unlock mutex!");

		if (of_rmutex_lock(&lock->rmutex) != 0)
			OBJC_ERROR("Failed to lock mutex!");

		return 0;
	}

	/* Create a new lock */
	if ((lock = malloc(sizeof(*lock))) == NULL)
		OBJC_ERROR("Failed to allocate memory for mutex!");

	if (of_rmutex_new(&lock->rmutex) != 0)
		OBJC_ERROR("Failed to create mutex!");

	lock->object = object;
	lock->count = 1;
	lock->next = locks;

	locks = lock;

	if (of_mutex_unlock(&mutex) != 0)
		OBJC_ERROR("Failed to unlock mutex!");

	if (of_rmutex_lock(&lock->rmutex) != 0)
		OBJC_ERROR("Failed to lock mutex!");
#endif

	return 0;
}

int
objc_sync_exit(id object)
{
	if (object == nil)
		return 0;

#ifdef OF_HAVE_THREADS
	struct lock_s *lock, *last = NULL;

	if (of_mutex_lock(&mutex) != 0)
		OBJC_ERROR("Failed to lock mutex!");

	for (lock = locks; lock != NULL; lock = lock->next) {
		if (lock->object != object) {
			last = lock;
			continue;
		}

		if (of_rmutex_unlock(&lock->rmutex) != 0)
			OBJC_ERROR("Failed to unlock mutex!");

		if (--lock->count == 0) {
			if (of_rmutex_free(&lock->rmutex) != 0)
				OBJC_ERROR("Failed to destroy mutex!");

			if (last != NULL)
				last->next = lock->next;
			if (locks == lock)
				locks = lock->next;

			free(lock);
		}

		if (of_mutex_unlock(&mutex) != 0)
			OBJC_ERROR("Failed to unlock mutex!");

		return 0;
	}

	OBJC_ERROR("objc_sync_exit() was called for an object not locked!");
#else
	return 0;
#endif
}







|
|
|
|
|


|



|











|

|









|


|









|








|


|













|

|








|



|










|










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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137

#import "ObjFWRT.h"
#import "private.h"

#ifdef OF_HAVE_THREADS
# import "mutex.h"

static struct lock {
	id object;
	int count;
	OFPlainRecursiveMutex rmutex;
	struct lock *next;
} *locks = NULL;

static OFPlainMutex mutex;

OF_CONSTRUCTOR()
{
	if (OFPlainMutexNew(&mutex) != 0)
		OBJC_ERROR("Failed to create mutex!");
}
#endif

int
objc_sync_enter(id object)
{
	if (object == nil)
		return 0;

#ifdef OF_HAVE_THREADS
	struct lock *lock;

	if (OFPlainMutexLock(&mutex) != 0)
		OBJC_ERROR("Failed to lock mutex!");

	/* Look if we already have a lock */
	for (lock = locks; lock != NULL; lock = lock->next) {
		if (lock->object != object)
			continue;

		lock->count++;

		if (OFPlainMutexUnlock(&mutex) != 0)
			OBJC_ERROR("Failed to unlock mutex!");

		if (OFPlainRecursiveMutexLock(&lock->rmutex) != 0)
			OBJC_ERROR("Failed to lock mutex!");

		return 0;
	}

	/* Create a new lock */
	if ((lock = malloc(sizeof(*lock))) == NULL)
		OBJC_ERROR("Failed to allocate memory for mutex!");

	if (OFPlainRecursiveMutexNew(&lock->rmutex) != 0)
		OBJC_ERROR("Failed to create mutex!");

	lock->object = object;
	lock->count = 1;
	lock->next = locks;

	locks = lock;

	if (OFPlainMutexUnlock(&mutex) != 0)
		OBJC_ERROR("Failed to unlock mutex!");

	if (OFPlainRecursiveMutexLock(&lock->rmutex) != 0)
		OBJC_ERROR("Failed to lock mutex!");
#endif

	return 0;
}

int
objc_sync_exit(id object)
{
	if (object == nil)
		return 0;

#ifdef OF_HAVE_THREADS
	struct lock *lock, *last = NULL;

	if (OFPlainMutexLock(&mutex) != 0)
		OBJC_ERROR("Failed to lock mutex!");

	for (lock = locks; lock != NULL; lock = lock->next) {
		if (lock->object != object) {
			last = lock;
			continue;
		}

		if (OFPlainRecursiveMutexUnlock(&lock->rmutex) != 0)
			OBJC_ERROR("Failed to unlock mutex!");

		if (--lock->count == 0) {
			if (OFPlainRecursiveMutexFree(&lock->rmutex) != 0)
				OBJC_ERROR("Failed to destroy mutex!");

			if (last != NULL)
				last->next = lock->next;
			if (locks == lock)
				locks = lock->next;

			free(lock);
		}

		if (OFPlainMutexUnlock(&mutex) != 0)
			OBJC_ERROR("Failed to unlock mutex!");

		return 0;
	}

	OBJC_ERROR("objc_sync_exit() was called for an object not locked!");
#else
	return 0;
#endif
}

Modified src/runtime/threading.m from [50e87d61c7] to [04a725fac0].

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
#include <stdlib.h>

#import "ObjFWRT.h"
#import "private.h"
#import "mutex.h"
#import "once.h"

static of_rmutex_t globalMutex;

static void
init(void)
{
	if (of_rmutex_new(&globalMutex) != 0)
		OBJC_ERROR("Failed to create global mutex!");
}

void
objc_global_mutex_lock(void)
{
	static OFOnceControl onceControl = OFOnceControlInitValue;
	OFOnce(&onceControl, init);

	if (of_rmutex_lock(&globalMutex) != 0)
		OBJC_ERROR("Failed to lock global mutex!");
}

void
objc_global_mutex_unlock(void)
{
	if (of_rmutex_unlock(&globalMutex) != 0)
		OBJC_ERROR("Failed to unlock global mutex!");
}







|




|









|






|


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
#include <stdlib.h>

#import "ObjFWRT.h"
#import "private.h"
#import "mutex.h"
#import "once.h"

static OFPlainRecursiveMutex globalMutex;

static void
init(void)
{
	if (OFPlainRecursiveMutexNew(&globalMutex) != 0)
		OBJC_ERROR("Failed to create global mutex!");
}

void
objc_global_mutex_lock(void)
{
	static OFOnceControl onceControl = OFOnceControlInitValue;
	OFOnce(&onceControl, init);

	if (OFPlainRecursiveMutexLock(&globalMutex) != 0)
		OBJC_ERROR("Failed to lock global mutex!");
}

void
objc_global_mutex_unlock(void)
{
	if (OFPlainRecursiveMutexUnlock(&globalMutex) != 0)
		OBJC_ERROR("Failed to unlock global mutex!");
}