diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/main.c | 97 |
1 files changed, 76 insertions, 21 deletions
| @@ -9,40 +9,95 @@ | |||
| 9 | #include <error.h> | 9 | #include <error.h> |
| 10 | #include <threads.h> | 10 | #include <threads.h> |
| 11 | #include <unistd.h> | 11 | #include <unistd.h> |
| 12 | #include <string.h> | ||
| 12 | 13 | ||
| 13 | int testcb(void *data) { | 14 | typedef int (*thingcb)(void*); |
| 14 | if(!data) | 15 | struct thing { |
| 15 | return -1; | 16 | thingcb cb; |
| 17 | void *arg; | ||
| 18 | }; | ||
| 16 | 19 | ||
| 17 | printf("%s\n", (char*)data); | 20 | typedef struct queue { |
| 18 | return 0; | 21 | mtx_t *cqmutex; |
| 19 | } | 22 | cnd_t *cqcnd; |
| 23 | unsigned char cstatus; | ||
| 24 | |||
| 25 | int len; | ||
| 26 | int used; | ||
| 27 | |||
| 28 | struct thing **queue; | ||
| 29 | } ccqueue; | ||
| 20 | 30 | ||
| 21 | int consumer(void *cq) { | 31 | #define QUEUE_LEN 10 |
| 22 | if(!cq) | 32 | |
| 23 | return -1; | 33 | int consumer(void *queue) { |
| 34 | if(!queue) | ||
| 35 | thrd_exit(-1); | ||
| 24 | 36 | ||
| 25 | cqueue *rcq = (cqueue*)cq; | 37 | ccqueue *real = (ccqueue *)queue; |
| 26 | for(task *tsk = NULL;;) { | 38 | for(struct thing *thing = NULL;;) { |
| 27 | tsk = cqueue_waitpop(rcq); | 39 | cnd_wait(real->cqcnd, real->cqmutex); |
| 28 | if(!tsk) | 40 | if(real->cstatus) |
| 29 | thrd_exit(-1); | 41 | thrd_exit(-1); |
| 30 | 42 | ||
| 31 | task_fire(tsk); | 43 | if(real->used > 0) { |
| 44 | thing = real->queue[real->used - 1]; | ||
| 45 | real->used--; | ||
| 46 | } | ||
| 47 | |||
| 48 | if(thing != NULL) | ||
| 49 | if(thing->arg != NULL) | ||
| 50 | thing->cb(thing->arg); | ||
| 32 | } | 51 | } |
| 33 | 52 | ||
| 53 | thrd_exit(0); | ||
| 54 | } | ||
| 55 | |||
| 56 | int testcb(void *data) { | ||
| 57 | if(!data) | ||
| 58 | return -1; | ||
| 59 | |||
| 60 | printf("%s\n", (char*)data); | ||
| 34 | return 0; | 61 | return 0; |
| 35 | } | 62 | } |
| 36 | 63 | ||
| 37 | int main() { | 64 | int main() { |
| 38 | // error(1, ENOTSUP, "No main file lol"); | 65 | // error(1, ENOTSUP, "No main file lol"); |
| 39 | 66 | ||
| 40 | thrd_t thread; | 67 | // Manually implement a threadpool and consumer in a "dumb" way to make sure I'm doing the correct thing |
| 41 | cqueue *cq = cqueue_init(mtx_plain); | 68 | ccqueue *cqueue = xcalloc(1, sizeof(*cqueue)); |
| 42 | thrd_create(&thread, consumer, cq); | 69 | cqueue->cqmutex = xcalloc(1, sizeof(*cqueue->cqmutex)); mtx_init(cqueue->cqmutex, mtx_plain); |
| 43 | cqueue_addtask(cq, task_init(testcb, (void*)"This is some data")); | 70 | cqueue->cqcnd = xcalloc(1, sizeof(*cqueue->cqcnd)); cnd_init(cqueue->cqcnd); |
| 44 | sleep(10); | 71 | cqueue->cstatus = 0; |
| 45 | cqueue_free(cq); | 72 | cqueue->len = QUEUE_LEN; |
| 73 | cqueue->used = 0; | ||
| 74 | cqueue->queue = xcalloc(cqueue->len, sizeof(struct thing *)); | ||
| 75 | |||
| 76 | thrd_t *thread = xcalloc(1, sizeof(*thread)); | ||
| 77 | thrd_create(thread, consumer, (void *)cqueue); | ||
| 78 | |||
| 79 | mtx_lock(cqueue->cqmutex); | ||
| 80 | cqueue->queue[cqueue->used] = xcalloc(1, sizeof(struct thing)); | ||
| 81 | cqueue->queue[cqueue->used]->cb = testcb; | ||
| 82 | cqueue->queue[cqueue->used]->arg = "This is some data"; | ||
| 83 | cqueue->used++; | ||
| 84 | mtx_unlock(cqueue->cqmutex); | ||
| 85 | cnd_signal(cqueue->cqcnd); | ||
| 86 | |||
| 87 | sleep(1); | ||
| 88 | |||
| 89 | mtx_lock(cqueue->cqmutex); | ||
| 90 | cqueue->cstatus++; | ||
| 91 | mtx_unlock(cqueue->cqmutex); | ||
| 92 | cnd_broadcast(cqueue->cqcnd); | ||
| 93 | |||
| 94 | // Destroy and free everything | ||
| 95 | mtx_destroy(cqueue->cqmutex); cnd_destroy(cqueue->cqcnd); | ||
| 96 | free(cqueue->cqmutex); free(cqueue->cqcnd); | ||
| 97 | free(cqueue->queue); | ||
| 98 | free(cqueue); | ||
| 46 | 99 | ||
| 47 | return 0; | 100 | return 0; |
| 48 | } \ No newline at end of file | 101 | } |
| 102 | |||
| 103 | // Ok well now I'm pissed. The canceling works fine but it's not actually consuming the thing \ No newline at end of file | ||
