aboutsummaryrefslogtreecommitdiffstats
path: root/src/common
diff options
context:
space:
mode:
authorRafael G. Martins <rafael@rafaelmartins.eng.br>2018-12-21 03:55:00 +0100
committerRafael G. Martins <rafael@rafaelmartins.eng.br>2018-12-21 03:55:00 +0100
commiteac073d479dfbe5ecf9c5fc7180f7b29da6d1298 (patch)
tree14db2b6f4c921e7c462b20d59a61fc2cf5446625 /src/common
parent62919eee3ef5fbad678034c21948abed523fa47e (diff)
downloadblogc-eac073d479dfbe5ecf9c5fc7180f7b29da6d1298.tar.gz
blogc-eac073d479dfbe5ecf9c5fc7180f7b29da6d1298.tar.bz2
blogc-eac073d479dfbe5ecf9c5fc7180f7b29da6d1298.zip
wip
Diffstat (limited to 'src/common')
-rw-r--r--src/common/error.c3
-rw-r--r--src/common/error.h1
-rw-r--r--src/common/thread.h23
-rw-r--r--src/common/thread_pthread.c82
4 files changed, 109 insertions, 0 deletions
diff --git a/src/common/error.c b/src/common/error.c
index 4538c01..a3a08e7 100644
--- a/src/common/error.c
+++ b/src/common/error.c
@@ -118,6 +118,9 @@ bc_error_print(bc_error_t *err, const char *prefix)
case BC_ERROR_FILE:
fprintf(stderr, "error: file: %s\n", err->msg);
break;
+ case BC_ERROR_THREAD:
+ fprintf(stderr, "error: thread: %s\n", err->msg);
+ break;
case BLOGC_ERROR_SOURCE_PARSER:
fprintf(stderr, "error: source: %s\n", err->msg);
break;
diff --git a/src/common/error.h b/src/common/error.h
index a567c6d..2aac439 100644
--- a/src/common/error.h
+++ b/src/common/error.h
@@ -17,6 +17,7 @@ typedef enum {
// errors for src/common
BC_ERROR_CONFIG_PARSER = 1,
BC_ERROR_FILE,
+ BC_ERROR_THREAD,
// errors for src/blogc
BLOGC_ERROR_SOURCE_PARSER = 100,
diff --git a/src/common/thread.h b/src/common/thread.h
new file mode 100644
index 0000000..850d375
--- /dev/null
+++ b/src/common/thread.h
@@ -0,0 +1,23 @@
+/*
+ * blogc: A blog compiler.
+ * Copyright (C) 2014-2018 Rafael G. Martins <rafael@rafaelmartins.eng.br>
+ *
+ * This program can be distributed under the terms of the BSD License.
+ * See the file LICENSE.
+ */
+
+#ifndef _THREAD_H
+#define _THREAD_H
+
+#include <stdbool.h>
+
+typedef void* (*bc_thread_func_t) (void *arg);
+
+typedef struct _bc_thread_t bc_thread_t;
+
+bc_thread_t* bc_thread_create(bc_thread_func_t func, void *arg, bool detached,
+ bc_error_t **err);
+void bc_thread_join(bc_thread_t *thread, bc_error_t **err);
+void bc_thread_free(bc_thread_t *thread);
+
+#endif /* _THREAD_H */
diff --git a/src/common/thread_pthread.c b/src/common/thread_pthread.c
new file mode 100644
index 0000000..a85a0c7
--- /dev/null
+++ b/src/common/thread_pthread.c
@@ -0,0 +1,82 @@
+/*
+ * blogc: A blog compiler.
+ * Copyright (C) 2014-2018 Rafael G. Martins <rafael@rafaelmartins.eng.br>
+ *
+ * This program can be distributed under the terms of the BSD License.
+ * See the file LICENSE.
+ */
+
+#include <stdbool.h>
+#include <string.h>
+#include <pthread.h>
+#include <stdlib.h>
+#include "error.h"
+#include "utils.h"
+#include "thread.h"
+
+struct _bc_thread_t {
+ pthread_t thread;
+};
+
+
+bc_thread_t*
+bc_thread_create(bc_thread_func_t func, void *arg, bool detached, bc_error_t **err)
+{
+ if (err == NULL || *err != NULL)
+ return NULL;
+
+ int r;
+
+ pthread_attr_t attr;
+ pthread_attr_t *attrp = NULL;
+
+ if (detached) {
+
+ if (0 != (r = pthread_attr_init(&attr))) {
+ *err = bc_error_new_printf(BC_ERROR_THREAD,
+ "Failed to initialize thread attributes: %s", strerror(r));
+ return NULL;
+ }
+
+ if (0 != (r = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED))) {
+ *err = bc_error_new_printf(BC_ERROR_THREAD,
+ "Failed to mark thread as detached: %s", strerror(r));
+ return NULL;
+ }
+
+ attrp = &attr;
+ }
+
+ bc_thread_t *rv = bc_malloc(sizeof(bc_thread_t));
+
+ if (0 != (r = pthread_create(&(rv->thread), attrp, func, arg))) {
+ *err = bc_error_new_printf(BC_ERROR_THREAD,
+ "Failed to create thread: %s", strerror(r));
+ free(rv);
+ return NULL;
+ }
+
+ return rv;
+}
+
+
+void
+bc_thread_join(bc_thread_t *thread, bc_error_t **err)
+{
+ if (thread == NULL || err == NULL || *err != NULL)
+ return;
+
+ int r;
+
+ if (0 != (r = pthread_join(thread->thread, NULL))) {
+ *err = bc_error_new_printf(BC_ERROR_THREAD,
+ "Failed to join thread: %s", strerror(r));
+ }
+}
+
+
+void
+bc_thread_free(bc_thread_t *thread)
+{
+ free(thread);
+}