]> infiniteadaptability.org Git - seeder/commitdiff
...
authoralex <[email protected]>
Sat, 4 Sep 2021 19:08:00 +0000 (12:08 -0700)
committeralex <[email protected]>
Sat, 4 Sep 2021 19:08:00 +0000 (12:08 -0700)
inc/log.h
src/log.c
src/setup.c

index 912681a840b940c94416ef9ad92695066585b822..63d16b387e591661784c67865b50a9b5ea14883c 100644 (file)
--- a/inc/log.h
+++ b/inc/log.h
@@ -4,9 +4,11 @@
 #include<pthread.h>
 #include<stdarg.h>
 #include<stdio.h>
+#include<stdlib.h>
 
 extern int verbose_flag;
 extern pthread_t logging_thread;
+extern pthread_mutex_t logging_mutex;
 
 enum log_level {
        LOG_LEVEL_SILENT = 0, /* suppresses all output */
@@ -15,17 +17,35 @@ enum log_level {
        LOG_LEVEL_VERBOSE = 3  /* logging and debugging info */
 };
 
-#define log_err(...) log_enqueue(LOG_LEVEL_ERRORS,stderr,__VA_ARGS__)
-#define log_info(...) log_enqueue(LOG_LEVEL_VERBOSE,stdout,__VA_ARGS__)
-#define log_msg(...) log_enqueue(LOG_LEVEL_DEFAULT,stdout,__VA_ARGS__)
+#define log_err(...) log_message(LOG_LEVEL_ERRORS,stderr,__VA_ARGS__)
+#define log_info(...) log_message(LOG_LEVEL_VERBOSE,stdout,__VA_ARGS__)
+#define log_msg(...) log_message(LOG_LEVEL_DEFAULT,stdout,__VA_ARGS__)
+
+#define LOG_FLUSH_MESSAGE "flushing log queue...\n"
+
+#define LOG_ENTRY_MAX_LENGTH 100
+#define LOG_QUEUE_SIZE 100
 
 struct log_entry {
        enum log_level level;
        char buf[LOG_ENTRY_MAX_LENGTH];
        FILE *out_stream;
+       struct log_entry *next;
+};
+
+struct log_helper {
+       void *p;
+       struct log_entry *start;
+       struct log_entry *end;
+       size_t next;
 };
 
-void log_enqueue(enum log_level,FILE*,const char*,...);
+struct log_entry *log_dequeue();
+void log_enqueue(struct log_entry*);
+int log_entries_init();
+void log_entries_clean();
+void log_flush();
+void log_print(struct log_entry*);
 void log_message(enum log_level,FILE*,const char*,...);
 void log_poll();
 
index 74b2bdbe13362f9a18c85a40ca731eccb52b9450..9b3ee6ebe1799f9dc1402e2a0fbdaebb1529e5c8 100644 (file)
--- a/src/log.c
+++ b/src/log.c
 
 int verbose_flag = LOG_LEVEL_DEFAULT;
 
-void log_enqueue(enum log_level level, FILE *out_stream, const char *format,...) {
-       va_list args;
-       va_start(args,format);
-//     vsnprintf(buf,format,args);
-       va_end(args);
+struct log_helper helper;
+
+struct log_entry *log_dequeue() {
+       struct log_entry *p;
+
+       pthread_mutex_lock(&logging_mutex);
+
+       if(NULL==helper.start) {
+               p = NULL;
+       } else {
+               p = helper.start;
+               helper.start = p->next;
+       }
+
+       pthread_mutex_unlock(&logging_mutex);
+
+       return p;
+}
+
+void log_enqueue(struct log_entry *p) {
+       pthread_mutex_lock(&logging_mutex);
+
+       if(NULL==helper.start) {
+               helper.start = p;
+               helper.end = p;
+       } else {
+               helper.end->next = p;
+               helper.end = p;
+       }
+
+       pthread_mutex_unlock(&logging_mutex);
+}
+
+int log_entries_init() {
+       helper.start = NULL;
+       helper.end = NULL;
+       helper.next = 0;
+       
+       helper.p = malloc(sizeof(struct log_entry(*))*LOG_QUEUE_SIZE+(sizeof(struct log_entry)*LOG_QUEUE_SIZE));
+       if(NULL==helper.p) {
+               perror("malloc");
+               return -1;
+       }
+
+       return 1;
+}
+
+void log_entries_clean() {
+       free(helper.p);
+}
+
+void log_flush() {
+       log_err(LOG_FLUSH_MESSAGE);
+
+       pthread_mutex_lock(&logging_mutex);
+
+       while(helper.start!=NULL) {
+               log_print(helper.start);
+               helper.start = helper.start->next;
+       }
+       
+       helper.start = NULL;
+       helper.end = NULL;
+       helper.next = 0;
+
+       pthread_mutex_unlock(&logging_mutex);
+}
+
+void log_print(struct log_entry *p) {
+       fputs(p->out_stream,p->buf);
 }
 
 void log_message(enum log_level level, FILE *out_stream, const char *format,...) {
        if(level>verbose_flag) { return; }
 
        va_list args;
-
+       va_start(args,format);
        if(0==pthread_equal(pthread_self(),logging_thread)) {
-               log_enqueue(level,out_stream,format,...);
+               // not on logging_thread
+
+               struct log_entry *p;
+               size_t offset;
+
+               offset = LOG_QUEUE_SIZE;
+               while(offset>=LOG_QUEUE_SIZE) {
+                       pthread_mutex_lock(&logging_mutex);
+
+                       offset = helper.next;
+                       helper.next++;
+
+                       pthread_mutex_unlock(&logging_mutex);
+
+                       // out of queue entries
+                       if(offset>=LOG_QUEUE_SIZE) {
+                               log_flush();
+                       }
+               }
+
+               p = &(helper.p[offset*sizeof(struct log_entry)]);
+
+               p->level = level;
+               p->out_stream = out_stream;
+               p->next = NULL;
+               vsnprintf(p->buf,LOG_ENTRY_MAX_LENGTH,format,args);
+
+               log_enqueue(p);
        } else {
-               va_start(args,format);
                vfprintf(out_stream,format,args);
        }
 
index 41ae3fb89d94a33e7ab7bbd9a02d21e127b89c93..7e6d37c3146dced7b4e43a74291a40109434d612 100644 (file)
@@ -1,8 +1,10 @@
 #include<setup.h>
 
 pthread_t logging_thread;
+pthread_mutex_t logging_mutex = PTHREAD_MUTEX_INITIALIZER;
 
 int setup() {
+       if(log_entries_init()<0) { return -1; }
        if(pthread_create(&logging_thread,NULL,&log_poll)!=0) {
                perror("pthread_create");
                return -1;