Skip to content

Commit 9c70497

Browse files
Merge pull request #6 from dreamer-coding/main
Update Threads API
2 parents b36d755 + 891005d commit 9c70497

File tree

19 files changed

+2154
-1158
lines changed

19 files changed

+2154
-1158
lines changed

README.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@
2929
To get started, ensure you have the following installed:
3030

3131
- **Meson Build System**: If you don’t have Meson `1.8.0` or newer installed, follow the installation instructions on the official [Meson website](https://mesonbuild.com/Getting-meson.html).
32-
- **Conan Package Manager**: If you prefer using Conan, ensure it is installed by following the instructions on the official [Conan website](https://docs.conan.io/en/latest/installation.html).
3332

3433
### Adding Dependency
3534

code/logic/cond.c

Lines changed: 70 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -49,19 +49,21 @@ int fossil_threads_cond_init(fossil_threads_cond_t *c) {
4949

5050
#if defined(_WIN32)
5151
CONDITION_VARIABLE *cv = (CONDITION_VARIABLE*)malloc(sizeof(CONDITION_VARIABLE));
52-
if (!cv) return FOSSIL_THREADS_COND_EINTERNAL;
52+
if (!cv) return FOSSIL_THREADS_COND_ENOMEM;
5353
InitializeConditionVariable(cv);
5454
c->handle = cv;
5555
#else
5656
pthread_cond_t *pc = (pthread_cond_t*)malloc(sizeof(pthread_cond_t));
57-
if (!pc) return FOSSIL_THREADS_COND_EINTERNAL;
57+
if (!pc) return FOSSIL_THREADS_COND_ENOMEM;
5858
if (pthread_cond_init(pc, NULL) != 0) {
5959
free(pc);
6060
return FOSSIL_THREADS_COND_EINTERNAL;
6161
}
6262
c->handle = pc;
6363
#endif
6464
c->valid = 1;
65+
c->is_broadcast = 0;
66+
c->waiters = 0;
6567
return FOSSIL_THREADS_COND_OK;
6668
}
6769

@@ -86,19 +88,32 @@ void fossil_threads_cond_dispose(fossil_threads_cond_t *c) {
8688
int fossil_threads_cond_wait(fossil_threads_cond_t *c, fossil_threads_mutex_t *m) {
8789
if (!c || !m || !c->valid || !m->valid) return FOSSIL_THREADS_COND_EINVAL;
8890

91+
c->waiters++;
8992
#if defined(_WIN32)
9093
if (!SleepConditionVariableCS(
9194
(CONDITION_VARIABLE*)c->handle,
9295
(CRITICAL_SECTION*)m->handle,
9396
INFINITE))
9497
{
98+
c->waiters--;
9599
return FOSSIL_THREADS_COND_EINTERNAL;
96100
}
101+
c->waiters--;
97102
return FOSSIL_THREADS_COND_OK;
98103
#else
99104
int rc = pthread_cond_wait((pthread_cond_t*)c->handle,
100105
(pthread_mutex_t*)m->handle);
101-
return rc == 0 ? FOSSIL_THREADS_COND_OK : rc;
106+
c->waiters--;
107+
if (rc == 0) return FOSSIL_THREADS_COND_OK;
108+
if (rc == EINVAL) return FOSSIL_THREADS_COND_EINVAL;
109+
if (rc == EAGAIN) return FOSSIL_THREADS_COND_EAGAIN;
110+
if (rc == ENOMEM) return FOSSIL_THREADS_COND_ENOMEM;
111+
if (rc == EPERM) return FOSSIL_THREADS_COND_EPERM;
112+
if (rc == EBUSY) return FOSSIL_THREADS_COND_EBUSY;
113+
if (rc == EDEADLK) return FOSSIL_THREADS_COND_EDEADLK;
114+
if (rc == ENOENT) return FOSSIL_THREADS_COND_ENOENT;
115+
if (rc == ENOSYS) return FOSSIL_THREADS_COND_ENOSYS;
116+
return FOSSIL_THREADS_COND_EINTERNAL;
102117
#endif
103118
}
104119

@@ -107,12 +122,14 @@ int fossil_threads_cond_timedwait(fossil_threads_cond_t *c,
107122
unsigned int ms) {
108123
if (!c || !m || !c->valid || !m->valid) return FOSSIL_THREADS_COND_EINVAL;
109124

125+
c->waiters++;
110126
#if defined(_WIN32)
111127
BOOL ok = SleepConditionVariableCS(
112128
(CONDITION_VARIABLE*)c->handle,
113129
(CRITICAL_SECTION*)m->handle,
114130
ms
115131
);
132+
c->waiters--;
116133
if (ok) return FOSSIL_THREADS_COND_OK;
117134
if (GetLastError() == ERROR_TIMEOUT) return FOSSIL_THREADS_COND_ETIMEDOUT;
118135
return FOSSIL_THREADS_COND_EINTERNAL;
@@ -130,30 +147,77 @@ int fossil_threads_cond_timedwait(fossil_threads_cond_t *c,
130147
int rc = pthread_cond_timedwait((pthread_cond_t*)c->handle,
131148
(pthread_mutex_t*)m->handle,
132149
&ts);
150+
c->waiters--;
133151
if (rc == 0) return FOSSIL_THREADS_COND_OK;
134152
if (rc == ETIMEDOUT) return FOSSIL_THREADS_COND_ETIMEDOUT;
135-
return rc;
153+
if (rc == EINVAL) return FOSSIL_THREADS_COND_EINVAL;
154+
if (rc == EAGAIN) return FOSSIL_THREADS_COND_EAGAIN;
155+
if (rc == ENOMEM) return FOSSIL_THREADS_COND_ENOMEM;
156+
if (rc == EPERM) return FOSSIL_THREADS_COND_EPERM;
157+
if (rc == EBUSY) return FOSSIL_THREADS_COND_EBUSY;
158+
if (rc == EDEADLK) return FOSSIL_THREADS_COND_EDEADLK;
159+
if (rc == ENOENT) return FOSSIL_THREADS_COND_ENOENT;
160+
if (rc == ENOSYS) return FOSSIL_THREADS_COND_ENOSYS;
161+
return FOSSIL_THREADS_COND_EINTERNAL;
136162
#endif
137163
}
138164

139165
int fossil_threads_cond_signal(fossil_threads_cond_t *c) {
140166
if (!c || !c->valid) return FOSSIL_THREADS_COND_EINVAL;
141167

168+
c->is_broadcast = 0;
142169
#if defined(_WIN32)
143170
WakeConditionVariable((CONDITION_VARIABLE*)c->handle);
144171
return FOSSIL_THREADS_COND_OK;
145172
#else
146-
return pthread_cond_signal((pthread_cond_t*)c->handle);
173+
int rc = pthread_cond_signal((pthread_cond_t*)c->handle);
174+
if (rc == 0) return FOSSIL_THREADS_COND_OK;
175+
if (rc == EINVAL) return FOSSIL_THREADS_COND_EINVAL;
176+
if (rc == ENOMEM) return FOSSIL_THREADS_COND_ENOMEM;
177+
if (rc == EBUSY) return FOSSIL_THREADS_COND_EBUSY;
178+
if (rc == EPERM) return FOSSIL_THREADS_COND_EPERM;
179+
if (rc == EDEADLK) return FOSSIL_THREADS_COND_EDEADLK;
180+
if (rc == ENOENT) return FOSSIL_THREADS_COND_ENOENT;
181+
if (rc == EAGAIN) return FOSSIL_THREADS_COND_EAGAIN;
182+
if (rc == ENOSYS) return FOSSIL_THREADS_COND_ENOSYS;
183+
return FOSSIL_THREADS_COND_EINTERNAL;
147184
#endif
148185
}
149186

150187
int fossil_threads_cond_broadcast(fossil_threads_cond_t *c) {
151188
if (!c || !c->valid) return FOSSIL_THREADS_COND_EINVAL;
152189

190+
c->is_broadcast = 1;
153191
#if defined(_WIN32)
154192
WakeAllConditionVariable((CONDITION_VARIABLE*)c->handle);
155193
return FOSSIL_THREADS_COND_OK;
156194
#else
157-
return pthread_cond_broadcast((pthread_cond_t*)c->handle);
195+
int rc = pthread_cond_broadcast((pthread_cond_t*)c->handle);
196+
if (rc == 0) return FOSSIL_THREADS_COND_OK;
197+
if (rc == EINVAL) return FOSSIL_THREADS_COND_EINVAL;
198+
if (rc == ENOMEM) return FOSSIL_THREADS_COND_ENOMEM;
199+
if (rc == EBUSY) return FOSSIL_THREADS_COND_EBUSY;
200+
if (rc == EPERM) return FOSSIL_THREADS_COND_EPERM;
201+
if (rc == EDEADLK) return FOSSIL_THREADS_COND_EDEADLK;
202+
if (rc == ENOENT) return FOSSIL_THREADS_COND_ENOENT;
203+
if (rc == EAGAIN) return FOSSIL_THREADS_COND_EAGAIN;
204+
if (rc == ENOSYS) return FOSSIL_THREADS_COND_ENOSYS;
205+
return FOSSIL_THREADS_COND_EINTERNAL;
158206
#endif
159207
}
208+
209+
int fossil_threads_cond_is_valid(const fossil_threads_cond_t *c) {
210+
if (!c) return 0;
211+
return c->valid ? 1 : 0;
212+
}
213+
214+
int fossil_threads_cond_waiter_count(const fossil_threads_cond_t *c) {
215+
if (!c || !c->valid) return -1;
216+
return c->waiters;
217+
}
218+
219+
int fossil_threads_cond_reset(fossil_threads_cond_t *c) {
220+
if (!c) return FOSSIL_THREADS_COND_EINVAL;
221+
fossil_threads_cond_dispose(c);
222+
return fossil_threads_cond_init(c);
223+
}

code/logic/fossil/threads/cond.h

Lines changed: 71 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,10 @@ extern "C"
4343
/* ---------- Types ---------- */
4444

4545
typedef struct fossil_threads_cond {
46-
void *handle; /* CONDITION_VARIABLE* on Win, pthread_cond_t* on POSIX */
46+
void *handle; /* CONDITION_VARIABLE* on Win, pthread_cond_t* on POSIX */
4747
int valid;
48+
int is_broadcast; /* 1 if last signal was broadcast, 0 otherwise */
49+
int waiters; /* Number of threads currently waiting */
4850
} fossil_threads_cond_t;
4951

5052
/* ---------- Lifecycle ---------- */
@@ -130,12 +132,47 @@ FOSSIL_THREADS_API int fossil_threads_cond_signal(fossil_threads_cond_t *c);
130132
*/
131133
FOSSIL_THREADS_API int fossil_threads_cond_broadcast(fossil_threads_cond_t *c);
132134

135+
/**
136+
* @brief Check if the condition variable is valid.
137+
*
138+
* Returns nonzero if the condition variable is initialized and valid, zero otherwise.
139+
*
140+
* @param c Pointer to the condition variable.
141+
* @return 1 if valid, 0 if not.
142+
*/
143+
FOSSIL_THREADS_API int fossil_threads_cond_is_valid(const fossil_threads_cond_t *c);
144+
145+
/**
146+
* @brief Get the number of threads currently waiting on the condition variable.
147+
*
148+
* @param c Pointer to the condition variable.
149+
* @return Number of waiting threads, or negative value on error.
150+
*/
151+
FOSSIL_THREADS_API int fossil_threads_cond_waiter_count(const fossil_threads_cond_t *c);
152+
153+
/**
154+
* @brief Reset the condition variable to its initial state.
155+
*
156+
* This function disposes and re-initializes the condition variable.
157+
*
158+
* @param c Pointer to the condition variable.
159+
* @return FOSSIL_THREADS_COND_OK on success, or error code on failure.
160+
*/
161+
FOSSIL_THREADS_API int fossil_threads_cond_reset(fossil_threads_cond_t *c);
162+
133163
/* Error codes */
134164
enum {
135-
FOSSIL_THREADS_COND_OK = 0,
136-
FOSSIL_THREADS_COND_EINVAL = 22,
137-
FOSSIL_THREADS_COND_ETIMEDOUT = 110,
138-
FOSSIL_THREADS_COND_EINTERNAL = 199
165+
FOSSIL_THREADS_COND_OK = 0,
166+
FOSSIL_THREADS_COND_EINVAL = 22, /* Invalid argument */
167+
FOSSIL_THREADS_COND_ETIMEDOUT = 110, /* Timeout occurred */
168+
FOSSIL_THREADS_COND_EINTERNAL = 199, /* Internal error */
169+
FOSSIL_THREADS_COND_ENOMEM = 12, /* Out of memory */
170+
FOSSIL_THREADS_COND_EBUSY = 16, /* Resource busy */
171+
FOSSIL_THREADS_COND_EPERM = 1, /* Operation not permitted */
172+
FOSSIL_THREADS_COND_EDEADLK = 35, /* Deadlock detected */
173+
FOSSIL_THREADS_COND_ENOENT = 2, /* No such file or directory (resource) */
174+
FOSSIL_THREADS_COND_EAGAIN = 11, /* Try again (resource temporarily unavailable) */
175+
FOSSIL_THREADS_COND_ENOSYS = 38 /* Function not implemented */
139176
};
140177

141178
#ifdef __cplusplus
@@ -247,6 +284,35 @@ namespace threads {
247284
*/
248285
fossil_threads_cond_t* native_handle() { return &cond_; }
249286

287+
/**
288+
* @brief Checks if the condition variable is valid.
289+
*
290+
* @return true if valid, false otherwise.
291+
*/
292+
bool is_valid() const {
293+
return fossil_threads_cond_is_valid(&cond_) != 0;
294+
}
295+
296+
/**
297+
* @brief Returns the number of threads currently waiting on the condition variable.
298+
*
299+
* @return Number of waiting threads, or negative value on error.
300+
*/
301+
int waiter_count() const {
302+
return fossil_threads_cond_waiter_count(&cond_);
303+
}
304+
305+
/**
306+
* @brief Resets the condition variable to its initial state.
307+
*
308+
* Disposes and re-initializes the condition variable.
309+
*
310+
* @return FOSSIL_THREADS_COND_OK on success, or error code on failure.
311+
*/
312+
int reset() {
313+
return fossil_threads_cond_reset(&cond_);
314+
}
315+
250316
private:
251317
fossil_threads_cond_t cond_; /**< The underlying condition variable structure. */
252318
};

code/logic/fossil/threads/framework.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@
2727

2828
#include "thread.h"
2929
#include "mutex.h"
30-
#include "ghost.h"
3130
#include "cond.h"
3231

3332
#endif /* FOSSIL_THREADS_FRAMEWORK_H */

0 commit comments

Comments
 (0)