]> rtime.felk.cvut.cz Git - coffee/mt-apps.git/commitdiff
queue input events
authorJiří Matěják <jiri.matejak@fel.cvut.cz>
Fri, 18 May 2018 01:08:14 +0000 (03:08 +0200)
committerJiří Matěják <jiri.matejak@fel.cvut.cz>
Fri, 18 May 2018 01:08:14 +0000 (03:08 +0200)
mt_server.c
mt_server.h

index d6a3904493917afa0155442592aeb31f95b47cf4..7575fedfca15ce0853374af2d1f619fad5c14b00 100644 (file)
@@ -5,6 +5,66 @@
 #include "mt_server.h"
 #include "signal_exit.h"
 
+char *new_line()
+{
+    char *line = (char *)malloc((LWS_PRE + INPUT_LINE_LENGTH)*sizeof(char));
+    if (!line) {
+        perror("malloc");
+    }
+    return line + LWS_PRE;
+}
+
+char *copy_line(char *line) {
+    char *copy = new_line();
+    if (!copy) {
+        return NULL;
+    }
+    strcpy(copy, line);
+}
+
+void free_line(char *line)
+{
+    free(line - LWS_PRE);
+}
+
+list *list_init(char *line)
+{
+    list *res = (list *)malloc(sizeof(list));
+    if (!res) {
+        perror("malloc");
+        return res;
+    }
+    res->line = line;;
+    res->next = NULL;
+    return res;
+}
+
+int list_add(list **in, char *line)
+{
+    list *new = list_init(line);
+    if (!new) {
+        return -1;
+    }
+    (*in)->next = new;
+    *in = new;
+    return 0;
+}
+
+void list_remove(list **in)
+{
+    list *tmp = *in;
+    *in = (*in)->next;
+    free_line(tmp->line);
+    free(tmp);
+}
+
+void list_deinit(list *in)
+{
+    while (in) {
+        list_remove(&in);
+    }
+}
+
 static const struct lws_http_mount mount = {
     /* .mount_next */            NULL,         /* linked-list "next" */
     /* .mountpoint */            HTTP_MOUNTPOINT,
@@ -75,7 +135,8 @@ static int callback_merica_terminal(struct lws *wsi,
 
     int n, m;
 
-    char *line = (char *)prot->user;
+    list **lines = (list **)&(prot->user);
+    char *line;
 
     switch (reason) {
         case LWS_CALLBACK_PROTOCOL_INIT:
@@ -98,8 +159,14 @@ static int callback_merica_terminal(struct lws *wsi,
             break;
 
         case LWS_CALLBACK_SERVER_WRITEABLE:
+            line = (*lines)->line;
             n = strlen(line);
             m = lws_write(wsi, (unsigned char *)line, n, LWS_WRITE_TEXT);
+            if ((*lines)->next != NULL) {
+                list_remove(lines);
+                lws_callback_on_writable_all_protocol(lws_get_context(wsi),
+                                                      &protocols[PROTOCOL_MERICA_TERMINAL]);
+            }
             if (m < n) {
                 fprintf(stderr, "ERROR %d writing to di socket\n", n);
                 return -1;
@@ -108,7 +175,7 @@ static int callback_merica_terminal(struct lws *wsi,
 
         case LWS_CALLBACK_RECEIVE:
             if (strcmp((const char *)in, "reset") == 0) {
-                strcpy(line, JSON_EMPTY);
+                strcpy((*lines)->line, JSON_EMPTY);
                 lws_callback_on_writable_all_protocol(lws_get_context(wsi),
                                                       &protocols[PROTOCOL_MERICA_TERMINAL]);
             } else if (strcmp((const char *)in, "close") == 0) {
@@ -136,9 +203,17 @@ static void fd_cb(EV_P_ ev_io *w_, int revents)
 
     if (*pos == '\n' || (w->pos - w->text) == INPUT_LINE_LENGTH) {
         *pos = 0;
-        w->pos = w->text;
-        lws_callback_on_writable_all_protocol(w->context,
-                                              &protocols[PROTOCOL_MERICA_TERMINAL]);
+        if (list_add(&(w->lines), w->text) == 0) {
+            char *line = new_line();
+            if (line) {
+                w->text = line;
+                w->pos = w->text;
+                lws_callback_on_writable_all_protocol(w->context,
+                    &protocols[PROTOCOL_MERICA_TERMINAL]);
+                return;
+            }
+        }
+        fprintf(stderr, "cannot malloc new line\n");
     }
 }
 
@@ -163,15 +238,23 @@ int mt_server_init(mt_server_t *self, struct ev_loop *loop, int fd)
 
     ev_io_ws *w = &(self->fd_watcher);
     w->context = context;
-    w->text = (char *)malloc((LWS_PRE + INPUT_LINE_LENGTH)*sizeof(char));
-    if (!w->text) {
-        perror("malloc");
+    char *line = copy_line(JSON_EMPTY);
+    if (!line) {
+        return -1;
+    }
+    w->lines = list_init(line);
+    if (!w->lines) {
+        free_line(line);
+        return -1;
+    }
+    protocols[PROTOCOL_MERICA_TERMINAL].user = (void *)w->lines;
+    line = new_line();
+    if (!line) {
+        list_deinit(w->lines);
         return -1;
     }
-    w->text += LWS_PRE;
-    strcpy(w->text, JSON_EMPTY);
+    w->text = line;
     w->pos = w->text;
-    protocols[PROTOCOL_MERICA_TERMINAL].user = (void *)w->text;
     ev_io_init(&(w->w), fd_cb, fd, EV_READ);
     ev_io_start(loop, (ev_io *)w);
 
@@ -180,8 +263,7 @@ int mt_server_init(mt_server_t *self, struct ev_loop *loop, int fd)
 
 void mt_server_deinit(mt_server_t *self)
 {
-    free(self->fd_watcher.text - LWS_PRE);
-    protocols[PROTOCOL_MERICA_TERMINAL].user = NULL;
+    list_deinit((list *)protocols[PROTOCOL_MERICA_TERMINAL].user);
     lws_context_destroy(self->context);
 }
 
index bf7c6e27dc553e88f77240c7ec5e6202372e274c..f08dfbd5ccaf823f01174cbb887e30337fee765d 100644 (file)
 
 #define JSON_EMPTY "{\"type\":\"empty\"}" // default message
 
+typedef struct list {
+    char *line;
+    struct list *next;
+} list;
+
 typedef struct ev_io_ws {
     ev_io w;                     // input watcher
     struct lws_context *context;
+    list *lines;
     char *text;                  // input buffer pointer
     char *pos;                   // input buffer current position pointer
 } ev_io_ws;