diff options
| author | @syxhe <https://t.me/syxhe> | 2025-06-09 15:03:19 -0500 |
|---|---|---|
| committer | @syxhe <https://t.me/syxhe> | 2025-06-09 15:03:19 -0500 |
| commit | 534a492f2c0bcceac52a287b03dc1ff5eb0b0763 (patch) | |
| tree | 0869f59e77d5b127b84e2a22015148ce9a8a3c98 | |
| parent | 08fb644c7d101551edfe8fc2608e0ac501b3df9f (diff) | |
Trim more fat, add some doxygen markup to the threadpool functions
| -rw-r--r-- | src/encryption.c | 39 | ||||
| -rw-r--r-- | src/scanner.c | 37 | ||||
| -rw-r--r-- | src/scanner.h | 5 | ||||
| -rw-r--r-- | src/shared.h | 5 | ||||
| -rw-r--r-- | src/threadpool.c | 4 | ||||
| -rw-r--r-- | src/threadpool.h | 131 |
6 files changed, 160 insertions, 61 deletions
diff --git a/src/encryption.c b/src/encryption.c index b6832ed..89448e8 100644 --- a/src/encryption.c +++ b/src/encryption.c | |||
| @@ -286,6 +286,45 @@ void* xsodium_malloc(size_t size) { | |||
| 286 | } | 286 | } |
| 287 | 287 | ||
| 288 | 288 | ||
| 289 | |||
| 290 | /* | ||
| 291 | |||
| 292 | #include "threadpool.h" | ||
| 293 | |||
| 294 | // #include <stdlib.h> | ||
| 295 | // #include <dirent.h> | ||
| 296 | // #include <string.h> | ||
| 297 | // #include <errno.h> | ||
| 298 | // #include <error.h> | ||
| 299 | |||
| 300 | // dlinkedlist * scandirlist(const char * const dir, int (*selector)(const struct dirent *), int (*cmp)(const struct dirent **, const struct dirent **)) { | ||
| 301 | // if(!dir || selector == NULL || cmp == NULL) ERRRET(EINVAL, NULL); | ||
| 302 | |||
| 303 | // struct dirent **namelist = NULL; | ||
| 304 | // dlinkedlist *list = NULL; | ||
| 305 | // int numentries = -1; | ||
| 306 | |||
| 307 | // if((numentries = scandir(dir, &namelist, selector, cmp)) < 0) | ||
| 308 | // ERRRET(errno, NULL); | ||
| 309 | |||
| 310 | // list = dlinkedlist_init(); | ||
| 311 | // for(int i = 0; i < numentries; i++) | ||
| 312 | // if(dlinkedlist_append(list, (void *)(namelist[i]), free) < 0) { | ||
| 313 | // dlinkedlist_free(list); | ||
| 314 | // for(int j = i; j < numentries; j++) | ||
| 315 | // free(namelist[j]); | ||
| 316 | |||
| 317 | // free(namelist); | ||
| 318 | // ERRRET(errno, NULL); | ||
| 319 | // } | ||
| 320 | // free(namelist); | ||
| 321 | |||
| 322 | // return list; | ||
| 323 | // } | ||
| 324 | |||
| 325 | // TODO: Rewrite this to use the threadpool. Each newly scanned file should be pushed onto the threadpool as an encryption task | ||
| 326 | */ | ||
| 327 | |||
| 289 | /* | 328 | /* |
| 290 | int main(void) { | 329 | int main(void) { |
| 291 | // Example code for creating a temp file, writing to it, then linking it back into the fs | 330 | // Example code for creating a temp file, writing to it, then linking it back into the fs |
diff --git a/src/scanner.c b/src/scanner.c deleted file mode 100644 index 2ffbea4..0000000 --- a/src/scanner.c +++ /dev/null | |||
| @@ -1,37 +0,0 @@ | |||
| 1 | #define _GNU_SOURCE | ||
| 2 | #include "shared.h" | ||
| 3 | |||
| 4 | #include "scanner.h" | ||
| 5 | |||
| 6 | #include <stdlib.h> | ||
| 7 | #include <dirent.h> | ||
| 8 | #include <string.h> | ||
| 9 | #include <errno.h> | ||
| 10 | #include <error.h> | ||
| 11 | |||
| 12 | // dlinkedlist * scandirlist(const char * const dir, int (*selector)(const struct dirent *), int (*cmp)(const struct dirent **, const struct dirent **)) { | ||
| 13 | // if(!dir || selector == NULL || cmp == NULL) ERRRET(EINVAL, NULL); | ||
| 14 | |||
| 15 | // struct dirent **namelist = NULL; | ||
| 16 | // dlinkedlist *list = NULL; | ||
| 17 | // int numentries = -1; | ||
| 18 | |||
| 19 | // if((numentries = scandir(dir, &namelist, selector, cmp)) < 0) | ||
| 20 | // ERRRET(errno, NULL); | ||
| 21 | |||
| 22 | // list = dlinkedlist_init(); | ||
| 23 | // for(int i = 0; i < numentries; i++) | ||
| 24 | // if(dlinkedlist_append(list, (void *)(namelist[i]), free) < 0) { | ||
| 25 | // dlinkedlist_free(list); | ||
| 26 | // for(int j = i; j < numentries; j++) | ||
| 27 | // free(namelist[j]); | ||
| 28 | |||
| 29 | // free(namelist); | ||
| 30 | // ERRRET(errno, NULL); | ||
| 31 | // } | ||
| 32 | // free(namelist); | ||
| 33 | |||
| 34 | // return list; | ||
| 35 | // } | ||
| 36 | |||
| 37 | // TODO: Rewrite this to use the threadpool. Each newly scanned file should be pushed onto the threadpool as an encryption task \ No newline at end of file | ||
diff --git a/src/scanner.h b/src/scanner.h deleted file mode 100644 index b9f2f9a..0000000 --- a/src/scanner.h +++ /dev/null | |||
| @@ -1,5 +0,0 @@ | |||
| 1 | #ifndef __VXGG_REWRITE___SCANNER_H___7164133769617___ | ||
| 2 | #define __VXGG_REWRITE___SCANNER_H___7164133769617___ | ||
| 3 | |||
| 4 | |||
| 5 | #endif \ No newline at end of file | ||
diff --git a/src/shared.h b/src/shared.h index efb95ad..3ff7b2d 100644 --- a/src/shared.h +++ b/src/shared.h | |||
| @@ -3,11 +3,11 @@ | |||
| 3 | 3 | ||
| 4 | #include <stddef.h> | 4 | #include <stddef.h> |
| 5 | 5 | ||
| 6 | #define STATIC_ARRAY_LEN(arr) (sizeof((arr))/sizeof((arr)[0])) | ||
| 7 | |||
| 8 | typedef int (*gcallback)(void*); // Generic callback signature | 6 | typedef int (*gcallback)(void*); // Generic callback signature |
| 9 | typedef void (*fcallback)(void*); // free()-like callback signature | 7 | typedef void (*fcallback)(void*); // free()-like callback signature |
| 10 | 8 | ||
| 9 | #define STATIC_ARRAY_LEN(arr) (sizeof((arr))/sizeof((arr)[0])) | ||
| 10 | |||
| 11 | #define ERRRET(errval, retval) do {\ | 11 | #define ERRRET(errval, retval) do {\ |
| 12 | errno = (errval);\ | 12 | errno = (errval);\ |
| 13 | return (retval);\ | 13 | return (retval);\ |
| @@ -37,6 +37,7 @@ typedef void (*fcallback)(void*); // free()-like callback signature | |||
| 37 | 37 | ||
| 38 | // Error macro that gcc will not complain about | 38 | // Error macro that gcc will not complain about |
| 39 | #define ERROR(status, errnum, format, ...) do {error((status), (errnum), (format)__VA_ARGS__); exit((status));} while (0) | 39 | #define ERROR(status, errnum, format, ...) do {error((status), (errnum), (format)__VA_ARGS__); exit((status));} while (0) |
| 40 | // Spit out a warning using `error` | ||
| 40 | #define WARN(errnum, format, ...) do {error(0, (errnum), (format)__VA_ARGS__);} while (0) | 41 | #define WARN(errnum, format, ...) do {error(0, (errnum), (format)__VA_ARGS__);} while (0) |
| 41 | 42 | ||
| 42 | // Read the entire contents of a file descriptor into a malloc()'ed buffer | 43 | // Read the entire contents of a file descriptor into a malloc()'ed buffer |
diff --git a/src/threadpool.c b/src/threadpool.c index bd52c75..681428e 100644 --- a/src/threadpool.c +++ b/src/threadpool.c | |||
| @@ -369,8 +369,10 @@ static int __CTQ_CONSUMER(void *ctq) { | |||
| 369 | task_free(ctask); | 369 | task_free(ctask); |
| 370 | } | 370 | } |
| 371 | 371 | ||
| 372 | thrd_exit(1); // non-zero indicates error, -1 indicates invalid argument | 372 | thrd_exit(1); |
| 373 | } | 373 | } |
| 374 | // TODO: Make this function return 0 or -1 depending on whether the overall ctq has been canceled or not. Canceling shouldn't | ||
| 375 | // be treated as an error | ||
| 374 | 376 | ||
| 375 | int ctqueue_start(ctqueue *ctq) { | 377 | int ctqueue_start(ctqueue *ctq) { |
| 376 | if(!ctq) ERRRET(EINVAL, -1); | 378 | if(!ctq) ERRRET(EINVAL, -1); |
diff --git a/src/threadpool.h b/src/threadpool.h index 7fda6f5..1d9a537 100644 --- a/src/threadpool.h +++ b/src/threadpool.h | |||
| @@ -8,43 +8,142 @@ typedef struct task task; | |||
| 8 | typedef struct taskqueue taskqueue; | 8 | typedef struct taskqueue taskqueue; |
| 9 | typedef struct ctqueue ctqueue; | 9 | typedef struct ctqueue ctqueue; |
| 10 | 10 | ||
| 11 | // Create a new task. Sets `errno` and returns `NULL` on error | 11 | /** |
| 12 | * @brief Create a task | ||
| 13 | * | ||
| 14 | * @param callback Callback function the given data should be ran with. Must be non-null | ||
| 15 | * @param freecb Callback function for freeing the given data. May be null | ||
| 16 | * @param data Data to be passed to the callback. May be null | ||
| 17 | * @return task* Returns a task object with set parameters. Returns `null` and sets errno on error | ||
| 18 | */ | ||
| 12 | task * task_init(gcallback callback, fcallback freecb, void *data); | 19 | task * task_init(gcallback callback, fcallback freecb, void *data); |
| 13 | // Free a task. Passes the `.data` member to specified fcallback as a function parameter. Does not return a value or set `errno` | 20 | |
| 21 | /** | ||
| 22 | * @brief Free a task | ||
| 23 | * | ||
| 24 | * @param tsk A task object to free. Frees data associated with task via `freecb` value specified in its creation. May be null | ||
| 25 | */ | ||
| 14 | void task_free(void *tsk); | 26 | void task_free(void *tsk); |
| 15 | // Fire a task. Passes the `.data` member to specified gcallback as a function parameter. Returns value of gcallback, or sets `errno` and returns `-1` on error | 27 | |
| 28 | /** | ||
| 29 | * @brief Fire a task. Passes the `data` member to the specified `callback` | ||
| 30 | * | ||
| 31 | * @param tsk A task to be fired. Must be non-null | ||
| 32 | * @return int Returns value of the fired callback. Returns -1 and sets errno on error | ||
| 33 | */ | ||
| 16 | int task_fire(task *tsk); | 34 | int task_fire(task *tsk); |
| 17 | // Fire and free a task simultaneously. Calls specified gcallback and fcallback on associated data. Returns value of gcallback, or sets `errno` and returns `-1` on error | 35 | |
| 36 | /** | ||
| 37 | * @brief Fire and destroy a task simultaneously. Calls specified callback and free-callback on associated data | ||
| 38 | * | ||
| 39 | * @param tsk Task to be fired and destroyed. Must be non-null | ||
| 40 | * @return int Returns value of the callback. Returns -1 and sets errno on error | ||
| 41 | */ | ||
| 18 | int task_fired(task *tsk); | 42 | int task_fired(task *tsk); |
| 19 | 43 | ||
| 20 | 44 | ||
| 21 | 45 | ||
| 22 | // Create a FIFO queue of task objects. Returns a new taskqueue on success, sets `errno` and returns `NULL` on error | 46 | /** |
| 47 | * @brief Create a FIFO queue of tasks | ||
| 48 | * | ||
| 49 | * @return taskqueue* Returns a new taskqueue object. Returns `null` and sets errno on error | ||
| 50 | */ | ||
| 23 | taskqueue * taskqueue_init(void); | 51 | taskqueue * taskqueue_init(void); |
| 24 | // Free a taskqueue. Does not return a value or set `errno` | 52 | |
| 53 | /** | ||
| 54 | * @brief Free a taskqueue | ||
| 55 | * | ||
| 56 | * @param tq A taskqueue to be freed. May be null | ||
| 57 | */ | ||
| 25 | void taskqueue_free(void *tq); | 58 | void taskqueue_free(void *tq); |
| 26 | // Push a task onto the queue. Returns 0 on success, sets `errno` and returns `-1` on error | 59 | |
| 60 | /** | ||
| 61 | * @brief Push a task onto a taskqueue | ||
| 62 | * | ||
| 63 | * @param tq The taskqueue to be modified. Must be non-null | ||
| 64 | * @param tsk The task to push. Must be non-null | ||
| 65 | * @return int Returns 0 on success, sets errno and returns -1 on error | ||
| 66 | */ | ||
| 27 | int taskqueue_push(taskqueue *tq, task *tsk); | 67 | int taskqueue_push(taskqueue *tq, task *tsk); |
| 28 | // Pop a task from the queue. Returns a task on success, sets `errno` and returns `NULL` on error | 68 | |
| 69 | /** | ||
| 70 | * @brief Pop a task from a taskqueue | ||
| 71 | * | ||
| 72 | * @param tq A taskqueue to grab a task from. Must be non-null | ||
| 73 | * @return task* Returns a task on success, sets errno and returns `null` on error | ||
| 74 | */ | ||
| 29 | task * taskqueue_pop(taskqueue *tq); | 75 | task * taskqueue_pop(taskqueue *tq); |
| 30 | // Push a task to the front of the queue (append, task becomes first in line to be popped). Returns 0 on success, sets `errno` and returns `-1` on error | 76 | |
| 77 | /** | ||
| 78 | * @brief Append a task to the front of a taskqueue | ||
| 79 | * | ||
| 80 | * @param tq The taskqueue to be modified. Must be non-null | ||
| 81 | * @param tsk The task to be appended. Must be non-null | ||
| 82 | * @return int Returns 0 on success, sets errno and returns `null` on error | ||
| 83 | */ | ||
| 31 | int taskqueue_pushfront(taskqueue *tq, task *tsk); | 84 | int taskqueue_pushfront(taskqueue *tq, task *tsk); |
| 32 | // Pop a task from the back of the queue (pop the most recently (normally) pushed item). Returns a task on success, sets `errno` and returns `NULL` on error | 85 | |
| 86 | /** | ||
| 87 | * @brief Pop a task from the back (most recently pushed task) of a taskqueue | ||
| 88 | * | ||
| 89 | * @param tq A taskqueue to pop from. Must be non-null | ||
| 90 | * @return task* Returns a task on success, sets errno and returns `null` on error | ||
| 91 | */ | ||
| 33 | task * taskqueue_popback(taskqueue *tq); | 92 | task * taskqueue_popback(taskqueue *tq); |
| 34 | 93 | ||
| 35 | 94 | ||
| 36 | 95 | ||
| 37 | // Create a concurrent taskqueue with `size` allocated threads | 96 | /** |
| 97 | * @brief Create a concurrent taskqueue with `size` allocated threads | ||
| 98 | * | ||
| 99 | * @param size Number of threads in the threadpool. Must be greater than zero | ||
| 100 | * @return ctqueue* Returns a new ctqueue, sets errno and returns `null` on error | ||
| 101 | */ | ||
| 38 | ctqueue * ctqueue_init(int size); | 102 | ctqueue * ctqueue_init(int size); |
| 39 | // Cancel a currently running ctq | 103 | |
| 104 | /** | ||
| 105 | * @brief Cancel all tasks being processed in a currently running concurrent taskqueue | ||
| 106 | * | ||
| 107 | * @param ctq The concurrent taskqueue to be canceled. Must be non-null | ||
| 108 | * @return int Returns 0 on success, sets errno and returns -1 on error | ||
| 109 | */ | ||
| 40 | int ctqueue_cancel(ctqueue *ctq); | 110 | int ctqueue_cancel(ctqueue *ctq); |
| 41 | // Free a ctq (cancels any remaining operations) | 111 | |
| 112 | /** | ||
| 113 | * @brief Free a concurrent taskqueue | ||
| 114 | * @attention This cancels all currently running threads via `ctqueue_cancel` | ||
| 115 | * | ||
| 116 | * @param ctq The concurrent taskqueue to free. May be null | ||
| 117 | */ | ||
| 42 | void ctqueue_free(void *ctq); | 118 | void ctqueue_free(void *ctq); |
| 43 | // Push a new task to the queue, waiting via mutex to do so | 119 | |
| 120 | /** | ||
| 121 | * @brief Push a task onto a concurrent taskqueue | ||
| 122 | * @attention May block for an indefinite amount of time to push the task | ||
| 123 | * | ||
| 124 | * @param ctq The concurrent taskqueue to modify. Must be non-null | ||
| 125 | * @param tsk The task to push. Must be non-null | ||
| 126 | * @return Returns `thrd_success` on success, returns `thrd_error` or `thrd_nomem` on error | ||
| 127 | */ | ||
| 44 | int ctqueue_waitpush(ctqueue *ctq, task *tsk); | 128 | int ctqueue_waitpush(ctqueue *ctq, task *tsk); |
| 45 | // Pop a task from the queue, waiting via mutex to do so | 129 | |
| 130 | |||
| 131 | /** | ||
| 132 | * @brief Pop a task from the concurrent taskqueue | ||
| 133 | * @attention May block for an indefinite amount of time to pop the task | ||
| 134 | * | ||
| 135 | * @param ctq The concurrent taskqueue to pop from. Must be non-null | ||
| 136 | * @return Returns a task on success, sets errno and returns `null` on error | ||
| 137 | */ | ||
| 46 | task * ctqueue_waitpop(ctqueue *ctq); | 138 | task * ctqueue_waitpop(ctqueue *ctq); |
| 47 | // Spawn the allocated threads for a ctq | 139 | |
| 140 | /** | ||
| 141 | * @brief Start the threads allocated to a concurrent taskqueue | ||
| 142 | * @attention Threads will not consume pushed tasks until this function is ran | ||
| 143 | * | ||
| 144 | * @param ctq A concurrent taskqueue to start. Must be non-null | ||
| 145 | * @return int Returns 0 on success, sets errno and returns -1 on error | ||
| 146 | */ | ||
| 48 | int ctqueue_start(ctqueue *ctq); | 147 | int ctqueue_start(ctqueue *ctq); |
| 49 | 148 | ||
| 50 | #endif \ No newline at end of file | 149 | #endif \ No newline at end of file |
