ObjFW  Check-in [20bfedd0b7]

Overview
Comment:of_condition_t -> OFPlainCondition
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | new-naming-convention
Files: files | file ages | folders
SHA3-256: 20bfedd0b717bd40063dfce8bdc7a6925204a67a40386f522a38074851789fa5
User & Date: js on 2021-04-17 16:36:00
Other Links: branch diff | manifest | tags
Context
2021-04-17
16:40
of_pbkdf2_parameters_t -> OFPBKDF2Parameters check-in: a2941ce6a1 user: js tags: new-naming-convention
16:36
of_condition_t -> OFPlainCondition check-in: 20bfedd0b7 user: js tags: new-naming-convention
16:29
of_spinlock_t -> OFSpinlock check-in: fabf53041a user: js tags: new-naming-convention
Changes

Modified src/OFCondition.h from [24d692e490] to [c4d6666d7d].

25
26
27
28
29
30
31
32

33
34
35
36
37
38
39
25
26
27
28
29
30
31

32
33
34
35
36
37
38
39







-
+







 * @class OFCondition OFCondition.h ObjFW/OFCondition.h
 *
 * @brief A class implementing a condition variable for thread synchronization.
 */
OF_SUBCLASSING_RESTRICTED
@interface OFCondition: OFMutex
{
	of_condition_t _condition;
	OFPlainCondition _condition;
	bool _conditionInitialized;
}

/**
 * @brief Creates a new condition.
 *
 * @return A new, autoreleased OFCondition

Modified src/OFCondition.m from [4b58a9908d] to [df9866904b].

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







-
+













-
+














-
+










-
+











-
+
+
















-
+







	return [[[self alloc] init] autorelease];
}

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

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

	_conditionInitialized = true;

	return self;
}

- (void)dealloc
{
	if (_conditionInitialized) {
		int error = of_condition_free(&_condition);
		int error = OFPlainConditionFree(&_condition);

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

			@throw [OFConditionStillWaitingException
			    exceptionWithCondition: self];
		}
	}

	[super dealloc];
}

- (void)wait
{
	int error = of_condition_wait(&_condition, &_mutex);
	int error = OFPlainConditionWait(&_condition, &_mutex);

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

#ifdef OF_AMIGAOS
- (void)waitForConditionOrExecSignal: (ULONG *)signalMask
{
	int error = of_condition_wait_or_signal(&_condition, &_mutex,
	int error = OFPlainConditionWaitOrExecSignal(&_condition, &_mutex,
	    signalMask);

	if (error != 0)
		@throw [OFConditionWaitFailedException
		    exceptionWithCondition: self
				     errNo: error];
}
#endif

- (bool)waitForTimeInterval: (OFTimeInterval)timeInterval
{
	int error = of_condition_timed_wait(&_condition, &_mutex, timeInterval);
	int error = OFPlainConditionTimedWait(&_condition, &_mutex,
	    timeInterval);

	if (error == ETIMEDOUT)
		return false;

	if (error != 0)
		@throw [OFConditionWaitFailedException
		    exceptionWithCondition: self
				     errNo: error];

	return true;
}

#ifdef OF_AMIGAOS
- (bool)waitForTimeInterval: (OFTimeInterval)timeInterval
	       orExecSignal: (ULONG *)signalMask
{
	int error = of_condition_timed_wait_or_signal(&_condition, &_mutex,
	int error = OFPlainConditionTimedWaitExecOrSignal(&_condition, &_mutex,
	    timeInterval, signalMask);

	if (error == ETIMEDOUT)
		return false;

	if (error != 0)
		@throw [OFConditionWaitFailedException
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
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







-
+









-
+







	return [self waitForTimeInterval: date.timeIntervalSinceNow
			    orExecSignal: signalMask];
}
#endif

- (void)signal
{
	int error = of_condition_signal(&_condition);
	int error = OFPlainConditionSignal(&_condition);

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

- (void)broadcast
{
	int error = of_condition_broadcast(&_condition);
	int error = OFPlainConditionBroadcast(&_condition);

	if (error != 0)
		@throw [OFConditionBroadcastFailedException
		    exceptionWithCondition: self
				     errNo: error];
}
@end

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

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







-
+





-
+



-
+


-
+

-
+





-
-
-
-
-
+
+
+
+
+
+


-
+

-
+


-
+



/* For OFTimeInterval */
#import "OFObject.h"

#import "mutex.h"

#if defined(OF_HAVE_PTHREADS)
# include <pthread.h>
typedef pthread_cond_t of_condition_t;
typedef pthread_cond_t OFPlainCondition;
#elif defined(OF_WINDOWS)
# include <windows.h>
typedef struct {
	HANDLE event;
	volatile int count;
} of_condition_t;
} OFPlainCondition;
#elif defined(OF_AMIGAOS)
# include <exec/tasks.h>
typedef struct {
	struct of_condition_waiting_task {
	struct OFPlainConditionWaitingTask {
		struct Task *task;
		unsigned char sigBit;
		struct of_condition_waiting_task *next;
		struct OFPlainConditionWaitingTask *next;
	} *waitingTasks;
} of_condition_t;
} OFPlainCondition;
#endif

#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,
extern int OFPlainConditionNew(OFPlainCondition *condition);
extern int OFPlainConditionSignal(OFPlainCondition *condition);
extern int OFPlainConditionBroadcast(OFPlainCondition *condition);
extern int OFPlainConditionWait(OFPlainCondition *condition,
    OFPlainMutex *mutex);
extern int OFPlainConditionTimedWait(OFPlainCondition *condition,
    OFPlainMutex *mutex, OFTimeInterval timeout);
#ifdef OF_AMIGAOS
extern int of_condition_wait_or_signal(of_condition_t *condition,
extern int OFPlainConditionWaitOrExecSignal(OFPlainCondition *condition,
    OFPlainMutex *mutex, ULONG *signalMask);
extern int of_condition_timed_wait_or_signal(of_condition_t *condition,
extern int OFPlainConditionTimedWaitOrExecSignal(OFPlainCondition *condition,
    OFPlainMutex *mutex, OFTimeInterval timeout, ULONG *signalMask);
#endif
extern int of_condition_free(of_condition_t *condition);
extern int OFPlainConditionFree(OFPlainCondition *condition);
#ifdef __cplusplus
}
#endif

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

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







-
+







-
+


















-
+




















-
+



-
+



-
-
+
+

-
+







#include <proto/exec.h>
#include <devices/timer.h>
#ifndef OF_AMIGAOS4
# include <clib/alib_protos.h>
#endif

int
of_condition_new(of_condition_t *condition)
OFPlainConditionNew(OFPlainCondition *condition)
{
	condition->waitingTasks = NULL;

	return 0;
}

int
of_condition_signal(of_condition_t *condition)
OFPlainConditionSignal(OFPlainCondition *condition)
{
	Forbid();
	@try {
		if (condition->waitingTasks == NULL)
			return 0;

		Signal(condition->waitingTasks->task,
		    (1ul << condition->waitingTasks->sigBit));

		condition->waitingTasks = condition->waitingTasks->next;
	} @finally {
		Permit();
	}

	return 0;
}

int
of_condition_broadcast(of_condition_t *condition)
OFPlainConditionBroadcast(OFPlainCondition *condition)
{
	Forbid();
	@try {
		if (condition->waitingTasks == NULL)
			return 0;

		while (condition->waitingTasks != NULL) {
			Signal(condition->waitingTasks->task,
			    (1ul << condition->waitingTasks->sigBit));

			condition->waitingTasks = condition->waitingTasks->next;
		}
	} @finally {
		Permit();
	}

	return 0;
}

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

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

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

	if (waitingTask.sigBit == -1)
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
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







-
+




-
+




-
+


-
+








	Permit();

	return error;
}

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

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

int
of_condition_timed_wait_or_signal(of_condition_t *condition,
OFPlainConditionTimedWaitOrExecSignal(OFPlainCondition *condition,
    OFPlainMutex *mutex, OFTimeInterval timeout, ULONG *signalMask)
{
	struct of_condition_waiting_task waitingTask = {
	struct OFPlainConditionWaitingTask waitingTask = {
		.task = FindTask(NULL),
		.sigBit = AllocSignal(-1)
	};
	struct MsgPort port = {
		.mp_Node = {
			.ln_Type = NT_MSGPORT
		},
233
234
235
236
237
238
239
240

241
242
243
244
245
246
247
248
249
250
251
233
234
235
236
237
238
239

240
241
242
243
244
245
246
247
248
249
250
251







-
+











	if (port.mp_SigBit != -1)
		FreeSignal(port.mp_SigBit);

	return error;
}

int
of_condition_free(of_condition_t *condition)
OFPlainConditionFree(OFPlainCondition *condition)
{
	Forbid();
	@try {
		if (condition->waitingTasks != NULL)
			return EBUSY;
	} @finally {
		Permit();
	}

	return 0;
}

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

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







-
+





-
+





-
+





-
+





-
+











-
+



 */

#include "config.h"

#import "condition.h"

int
of_condition_new(of_condition_t *condition)
OFPlainConditionNew(OFPlainCondition *condition)
{
	return pthread_cond_init(condition, NULL);
}

int
of_condition_signal(of_condition_t *condition)
OFPlainConditionSignal(OFPlainCondition *condition)
{
	return pthread_cond_signal(condition);
}

int
of_condition_broadcast(of_condition_t *condition)
OFPlainConditionBroadcast(OFPlainCondition *condition)
{
	return pthread_cond_broadcast(condition);
}

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

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

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

	return pthread_cond_timedwait(condition, mutex, &ts);
}

int
of_condition_free(of_condition_t *condition)
OFPlainConditionFree(OFPlainCondition *condition)
{
	return pthread_cond_destroy(condition);
}

Modified src/platform/windows/condition.m from [33e65b6da7] to [5e19c9c3c0].

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







-
+










-
+














-
+


















-
+







#include <errno.h>

#import "condition.h"

#include <windows.h>

int
of_condition_new(of_condition_t *condition)
OFPlainConditionNew(OFPlainCondition *condition)
{
	condition->count = 0;

	if ((condition->event = CreateEvent(NULL, FALSE, 0, NULL)) == NULL)
		return EAGAIN;

	return 0;
}

int
of_condition_signal(of_condition_t *condition)
OFPlainConditionSignal(OFPlainCondition *condition)
{
	if (!SetEvent(condition->event)) {
		switch (GetLastError()) {
		case ERROR_INVALID_HANDLE:
			return EINVAL;
		default:
			OF_ENSURE(0);
		}
	}

	return 0;
}

int
of_condition_broadcast(of_condition_t *condition)
OFPlainConditionBroadcast(OFPlainCondition *condition)
{
	int count = condition->count;

	for (int i = 0; i < count; i++) {
		if (!SetEvent(condition->event)) {
			switch (GetLastError()) {
			case ERROR_INVALID_HANDLE:
				return EINVAL;
			default:
				OF_ENSURE(0);
			}
		}
	}

	return 0;
}

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

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

91
92
93
94
95
96
97
98

99
100
101
102
103
104
105
91
92
93
94
95
96
97

98
99
100
101
102
103
104
105







-
+







		}
	default:
		OF_ENSURE(0);
	}
}

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

	if ((error = OFPlainMutexUnlock(mutex)) != 0)
		return error;
122
123
124
125
126
127
128
129

130
131
132
133
134
135
122
123
124
125
126
127
128

129
130
131
132
133
134
135







-
+






		}
	default:
		OF_ENSURE(0);
	}
}

int
of_condition_free(of_condition_t *condition)
OFPlainConditionFree(OFPlainCondition *condition)
{
	if (condition->count != 0)
		return EBUSY;

	return (CloseHandle(condition->event) ? 0 : EINVAL);
}