feat: add threadpool and started pooling executors

This commit is contained in:
2024-08-03 13:08:46 +02:00
parent e35dbdb1f3
commit dcc25f88a7
15 changed files with 544 additions and 85 deletions

View File

@ -4,11 +4,8 @@
#include "optional.h"
typedef struct {
// prototyping
optional_str file;
optional_str file2;
// actual
optional_str config_file;
int executors;
int verbosity;
bool help;
bool version;
@ -20,7 +17,7 @@ typedef struct {
cli_options new_options();
// Delete a cli_options struct instance.
void free_options(cli_options v);
void destroy_options(cli_options v);
// Print the help message.
void print_help(FILE * out, char* prog_name);

View File

@ -1,11 +1,12 @@
#ifndef SCI_NOTIFY_H
#define SCI_NOTIFY_H
#include "pipeline.h"
#include <sys/inotify.h>
typedef void(*notify_callback)(struct inotify_event* const);
typedef void(*notify_callback)(pipeline_event* const);
// Start listening for changes to the provided file.
// Note that the `struct inotify_event*` provided is a managed pointer.
void listen_for_changes(const char* filename, notify_callback callback);
void listen_for_changes(const pipeline_conf* config, notify_callback callback);
#endif

25
include/pipeline.h Normal file
View File

@ -0,0 +1,25 @@
#ifndef SCI_PIPELINE_H
#define SCI_PIPELINE_H
#include "optional.h"
#include <pthread.h>
#include <sys/inotify.h>
typedef struct {
char* name;
char* url;
char* trigger;
char* command;
} pipeline_conf;
typedef optional_type(pipeline_conf*) optional_pipeline_conf;
typedef struct {
const struct inotify_event* event;
const char* command;
} pipeline_event;
// create a new pipeline_conf struct instance based on a configuration line.
optional_pipeline_conf pipeline_create(const char* config_line);
void pipeline_register(pthread_t thread);
void pipeline_loop();
#endif

33
include/threadlist.h Normal file
View File

@ -0,0 +1,33 @@
#ifndef SCI_THREADLIST_H
#define SCI_THREADLIST_H
#include <pthread.h>
// doubly linked list implementation for managing threads
typedef struct pthread_list_node {
pthread_t thread;
struct pthread_list_node* previous;
struct pthread_list_node* next;
} pthread_list_node;
// Create a new root node.
pthread_list_node* create_thread_node(pthread_t thread);
// Add a new node to the end of the list.
// Returns the new node.
pthread_list_node* add_thread(pthread_t thread, pthread_list_node* root);
pthread_list_node* add_thread_node(pthread_list_node* root, pthread_list_node* node);
// Remove a node from the list.
// This will not call pthread_join, so make sure that the thread is joined before calling.
void remove_thread_node(pthread_list_node* node);
// Completely clear the thread list.
// This will call pthread_join on all nodes.
// The list is completely invalid after this call and should be discarded.
// Note:
// - `root` has already been free'd.
// - this function is not thread-safe.
void clear_thread_list(pthread_list_node* root);
#endif

42
include/threadpool.h Normal file
View File

@ -0,0 +1,42 @@
#ifndef SCI_THREADPOOL_H
#define SCI_THREADPOOL_H
#include <stdbool.h>
#include <stddef.h>
#include <pthread.h>
// Very inspired by: https://nachtimwald.com/2019/04/12/thread-pool-in-c/
// a work function
typedef void (*thread_func)(void *arg);
// linked list for work functions
typedef struct threadpool_work {
thread_func func;
void* arg;
struct threadpool_work* next;
} threadpool_work;
// thread pool object
typedef struct {
threadpool_work* work_first;
threadpool_work* work_last;
pthread_mutex_t work_mutex;
pthread_cond_t work_cond;
pthread_cond_t working_cond;
size_t working_count;
size_t thread_count;
bool stop;
} threadpool;
// create a new threadpool instance with `num` amount of worker threads
threadpool* threadpool_create(size_t num);
// destroy a threadpool instance
void threadpool_destroy(threadpool* pool);
// add work to the threadpool
bool threadpool_add_work(threadpool* pool, thread_func func, void* arg);
// wait for the remaining work in the threadpool to complete
void threadpool_wait(threadpool* pool);
#endif

View File

@ -13,5 +13,13 @@
assert(fd != -1); \
} \
} while (0)
#define ARRAY_SIZE(a) (sizeof((a)) / sizeof((a)[0]))
// remove whitespace characters on both ends of the string.
// Retuirns a new string that you must free.
char* trim(const char* const str);
typedef void(*line_handler)(const char*);
void per_line(const char* file, line_handler handler);
#endif