]> git.itanic.dy.fi Git - log-plotter/commitdiff
Convert data reading into event based system
authorTimo Kokkonen <timo.t.kokkonen@iki.fi>
Thu, 31 Oct 2013 19:22:45 +0000 (21:22 +0200)
committerTimo Kokkonen <timo.t.kokkonen@iki.fi>
Thu, 31 Oct 2013 19:22:45 +0000 (21:22 +0200)
As of preparing for the future, convert the data reading into an even
based system. The main loop has got the loop that holds the state of
the logging process. All other modules then register itself into the
event system where they get called back whenever data gets feed in
into their file descriptors.

Signed-off-by: Timo Kokkonen <timo.t.kokkonen@iki.fi>
Makefile
data.c
data.h
event.c [new file with mode: 0644]
event.h [new file with mode: 0644]
main.c
utils.h

index f77068675a1fa62f759dd273dfd807a21ec566f9..68d2e64763139885e54eba3fa139164a96cd0554 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -2,7 +2,7 @@ CC=gcc
 LD=ld
 CFLAGS=-Wall -O2 -g -fPIC
 
-LOG-PLOTTER_OBJS = baud.o main.o options.o trace.o data.o config.o
+LOG-PLOTTER_OBJS = baud.o main.o options.o trace.o data.o config.o event.o
 
 ALL_OBJS = $(LOG-PLOTTER_OBJS)
 ALL_DEBS = $(patsubst %.o,.%.o.d,$(ALL_OBJS))
diff --git a/data.c b/data.c
index fa370729b0c8a242b4efa053cc569a9dcfa4f632..81a8345743d4552109fd2950161d9a461d090c69 100644 (file)
--- a/data.c
+++ b/data.c
 
 #include "data.h"
 #include "trace.h"
+#include "event.h"
 #include "utils.h"
-
+#include "event.h"
+
+struct dataparser_struct {
+       struct eventhandler_entry evhandler;
+       int infd;
+       int outfd;
+       int offset;
+       time_t start_time;
+       char buf[256];
+};
 
 static int separate_entries(char *buf, char *entries[], int max_entries)
 {
@@ -238,107 +248,102 @@ static int read_log_line(int infd, char *buf, size_t bufsize, int *offset)
        return 0;
 }
 
-int read_data(int infd, int outfd)
+static int read_data(struct eventhandler_entry *h)
 {
-       struct epoll_event ev;
-       time_t start_time = 0, cur_time;
-       int epoll_fd;
+       struct dataparser_struct *dt;
+       time_t cur_time;
        int ret;
-       char buf[256];
-       int offset = 0;
+       struct charger_data data;
+       char str[320];
+       int len;
 
-       epoll_fd = epoll_create(1);
-       if (epoll_fd < 0) {
-               pr_err("Failed to create epoll socket: %m\n");
-               return -1;
-       }
+       dt = container_of(h, struct dataparser_struct, evhandler);
 
-       ev.events = EPOLLIN;
-       ev.data.fd = infd;
-       if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, infd, &ev) == -1) {
-               pr_err("epoll_ctl: %m\n");
-               return 1;
-       }
+       ret = read_log_line(dt->infd, dt->buf, sizeof(dt->buf), &dt->offset);
+       pr_debug("Line now %d: %s\n", dt->offset, dt->buf);
+       if (ret <= 0)
+               return ret;
 
-       while (1) {
-               struct charger_data data;
-               char str[320];
-               int len;
+       if (ret == 0)
+               pr_err("%s %s: EOF\n", __FILE__, __func__);
 
-               ret = epoll_wait(epoll_fd, &ev, 1, -1);
-               if (ret == 0)
-                       continue;
-
-               if (ret < 0) {
-                       pr_err("epoll: %m\n");
-                       return -1;
-               }
+       if (strlen(dt->buf) < 5) {
+               pr_debug("discarding truncated log entry\n");
+               dt->offset = 0;
+               return 0;
+       }
 
-               ret = read_log_line(infd, buf, sizeof(buf), &offset);
-               if (ret < 0)
-                       return ret;
+       if (!dt->start_time)
+               dt->start_time = time(NULL);
 
-               if (ret == 0)
-                       continue;
+       cur_time = time(NULL);
 
-               if (strlen(buf) < 5) {
-                       pr_debug("discarding truncated log entry\n");
-                       offset = 0;
-                       continue;
-               }
+       parse_logline(dt->buf, &data);
 
-               if (!start_time)
-                       start_time = time(NULL);
+       /* Fill in possibly missing timestamp */
+       if (isnan(data.timestamp) || data.timestamp == 0)
+               data.timestamp = cur_time - dt->start_time;
 
-               cur_time = time(NULL);
+       print_status_line(&data);
 
-               parse_logline(buf, &data);
+       dump_data(&data);
 
-               /* Fill in possibly missing timestamp */
-               if (isnan(data.timestamp) || data.timestamp == 0);
-                       data.timestamp = cur_time - start_time;
+       if (!dt->outfd)
+               return 0;
 
-               print_status_line(&data);
+       len = snprintf(str, sizeof(str),
+               "%d;%d;%.1f;"
+               "%.3f;%.3f;%.3f;"
+               "%.3f;%.3f;%.3f;%.3f;%.3f;%.3f;%.3f;%.3f;%.3f;%.3f;"
+               "%.f;%.1f;%.1f\n", /* mAh, and temp */
+               data.channel,
+               data.state,
+               data.timestamp,
 
-               dump_data(&data);
+               data.input_voltage,
+               data.charging_voltage,
+               data.charging_current,
 
-               if (!outfd)
-                       continue;
+               data.cell_voltage[0],
+               data.cell_voltage[1],
+               data.cell_voltage[2],
+               data.cell_voltage[3],
+               data.cell_voltage[4],
+               data.cell_voltage[5],
+               data.cell_voltage[6],
+               data.cell_voltage[7],
+               data.cell_voltage[8],
+               data.cell_voltage[9],
+               data.int_temp,
+               data.ext_temp,
+               data.total_charge);
 
-               len = snprintf(str, sizeof(str),
-                       "%d;%d;%.1f;"
-                       "%.3f;%.3f;%.3f;"
-                       "%.3f;%.3f;%.3f;%.3f;%.3f;%.3f;%.3f;%.3f;%.3f;%.3f;"
-                       "%.f;%.1f;%.1f\n", /* mAh, and temp */
-                       data.channel,
-                       data.state,
-                       data.timestamp,
-
-                       data.input_voltage,
-                       data.charging_voltage,
-                       data.charging_current,
-
-                       data.cell_voltage[0],
-                       data.cell_voltage[1],
-                       data.cell_voltage[2],
-                       data.cell_voltage[3],
-                       data.cell_voltage[4],
-                       data.cell_voltage[5],
-                       data.cell_voltage[6],
-                       data.cell_voltage[7],
-                       data.cell_voltage[8],
-                       data.cell_voltage[9],
-                       data.int_temp,
-                       data.ext_temp,
-                       data.total_charge);
-
-               ret = write(outfd, str, len);
-               if (ret < 0) {
-                       pr_err("write: %m\n");
-                       break;
-               }
+       ret = write(dt->outfd, str, len);
+       if (ret < 0) {
+               pr_err("write: %m\n");
+               return -1;;
        }
 
        return 0;
 }
 
+static struct dataparser_struct dataparser = {
+       .evhandler.name = "OpenLog Parser",
+       .evhandler.events = EPOLLIN,
+       .evhandler.handle_event = read_data,
+};
+
+int init_data_parser(int infd, int outfd)
+{
+       int ret;
+
+       dataparser.evhandler.fd = infd;
+       dataparser.infd = infd;
+       dataparser.outfd = outfd;
+
+       ret = register_event_handler(&dataparser.evhandler);
+       if (ret < 0)
+               return 1;
+
+       return 0;
+}
diff --git a/data.h b/data.h
index 459ee66c023b58990c074411cfab0ae7039d7d65..90934a1b203b839ff0de0a157fff16401a905cb5 100644 (file)
--- a/data.h
+++ b/data.h
@@ -17,6 +17,6 @@ struct charger_data {
        double ext_temp;
 };
 
-int read_data(int infd, int outfd);
+int init_data_parser(int infd, int outfd);
 
 #endif
diff --git a/event.c b/event.c
new file mode 100644 (file)
index 0000000..b3cbaf2
--- /dev/null
+++ b/event.c
@@ -0,0 +1,98 @@
+#include <errno.h>
+#include <sys/epoll.h>
+
+#include "event.h"
+#include "trace.h"
+
+static int epoll_fd = -1;
+
+static int init_event_handler(void)
+{
+       epoll_fd = epoll_create(1);
+       if (epoll_fd < 0) {
+               pr_err("Failed to create epoll socket: %m\n");
+               return -1;
+       }
+
+       return 0;
+}
+
+int register_event_handler(struct eventhandler_entry *handler)
+{
+       struct epoll_event ev;
+       int ret = 0;
+
+       if (epoll_fd < 0)
+               ret = init_event_handler();
+
+       if (ret < 0)
+               return ret;
+
+       if (handler->fd < 0) {
+               pr_err("Invalid file descriptor of %d for handler %s\n",
+                       handler->fd, handler->name);
+               return -1;
+       }
+
+       if (!handler->handle_event) {
+               pr_err("Handler %s missing callback function\n", handler->name);
+               return -1;
+       }
+
+       pr_debug("Registering handler for \"%s\", fd=%d\n",
+               handler->name, handler->fd);
+
+       ev.data.fd = handler->fd;
+       ev.data.ptr = handler;
+       ev.events = handler->events;
+       ret = epoll_ctl(epoll_fd, EPOLL_CTL_ADD, handler->fd, &ev);
+       if (ret) {
+               pr_err("Failed to add epoll_fd: %m\n");
+               return -1;
+       }
+
+       return 0;
+}
+
+int poll_events(int timeout_ms)
+{
+       struct epoll_event event;
+       struct eventhandler_entry *handler;
+       int ret;
+
+       ret = epoll_wait(epoll_fd, &event, 1, timeout_ms);
+
+       if (ret == -1) {
+               if (errno != EINTR) {
+                       pr_err("epoll_wait: %m\n");
+                       return -1;
+               }
+
+               /*
+                * If epoll_wait() was interrupted, better start
+                * everything again from the beginning
+                */
+               return 0;
+       }
+
+       if (ret == 0) {
+               pr_info("Timed out\n");
+               goto out;
+       }
+
+       handler = event.data.ptr;
+
+       if (!handler || !handler->handle_event) {
+               pr_err("Corrupted event handler for fd %d\n",
+                       event.data.fd);
+               goto out;
+       }
+
+       pr_debug("Running handler %s to handle events from fd %d\n",
+               handler->name, handler->fd);
+       handler->handle_event(handler);
+
+out:
+       return ret;
+}
+
diff --git a/event.h b/event.h
new file mode 100644 (file)
index 0000000..91d0705
--- /dev/null
+++ b/event.h
@@ -0,0 +1,15 @@
+#ifndef _EVENT_H
+#define _EVENT_H
+
+struct eventhandler_entry {
+       char *name;
+       int fd;
+       int events;
+       int (*handle_event)(struct eventhandler_entry *h);
+};
+
+int inint_event_handler(void);
+int register_event_handler(struct eventhandler_entry *h);
+int poll_events(int timeout_ms);
+
+#endif
diff --git a/main.c b/main.c
index 05e3390968d01a9f3c0801509b04b2406dffe2a3..1057d09ad71b145d0c4a06cd0c83f5ed41391c55 100644 (file)
--- a/main.c
+++ b/main.c
@@ -8,6 +8,7 @@
 #include "baud.h"
 #include "trace.h"
 #include "data.h"
+#include "event.h"
 
 int main(int argc, char *argv[])
 {
@@ -49,7 +50,12 @@ int main(int argc, char *argv[])
                }
        }
 
-       read_data(fd, out_fd);
+
+       init_data_parser(fd, out_fd);
+
+       while (1) {
+               poll_events(10000);
+       }
 
 out:
        close(fd);
diff --git a/utils.h b/utils.h
index 8b5152ef8c4e6158f70b60822a8efe6e07ea9e72..102dc65339fe06e9feb2410754eb393474b0b57f 100644 (file)
--- a/utils.h
+++ b/utils.h
@@ -3,4 +3,14 @@
 
 #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
 
+#ifndef offsetof
+#define offsetof(type, member)  __builtin_offsetof (type, member)
+#endif
+
+#define container_of(ptr, type, member) \
+       ({                                                              \
+               const typeof( ((type *)0)->member ) *__mptr = (ptr);    \
+               (type *)( (char *)__mptr - offsetof(type,member) );     \
+       })
+
 #endif