From 04e3bcc652d43887064e3a7b32b16c38b3f47dd5 Mon Sep 17 00:00:00 2001 From: David Herrmann Date: Sun, 16 Sep 2012 09:23:35 +0200 Subject: [PATCH] shl: move kmscon_ring_* to shl The ring implementation is only used in one place so move it into SHL to avoid linking it into all other libraries and applications. Signed-off-by: David Herrmann --- Makefile.am | 3 + src/pty.c | 16 ++--- src/shl_ring.h | 170 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/static_misc.c | 130 ----------------------------------------- src/static_misc.h | 12 ---- 5 files changed, 181 insertions(+), 150 deletions(-) create mode 100644 src/shl_ring.h diff --git a/Makefile.am b/Makefile.am index 068d2aa..1be31b1 100644 --- a/Makefile.am +++ b/Makefile.am @@ -87,6 +87,8 @@ SHL_HASHTABLE = \ src/shl_hashtable.h \ external/htable.h \ external/htable.c +SHL_RING = \ + src/shl_ring.h # # libeloop @@ -257,6 +259,7 @@ libkmscon_core_la_SOURCES = \ $(SHL_DLIST) \ $(SHL_ARRAY) \ $(SHL_HASHTABLE) \ + $(SHL_RING) \ src/main.h \ src/conf.c src/conf.h \ src/ui.c src/ui.h \ diff --git a/src/pty.c b/src/pty.c index acc7296..b092579 100644 --- a/src/pty.c +++ b/src/pty.c @@ -38,8 +38,8 @@ #include "eloop.h" #include "log.h" #include "main.h" -#include "static_misc.h" #include "pty.h" +#include "shl_ring.h" #define LOG_SUBSYSTEM "pty" @@ -52,7 +52,7 @@ struct kmscon_pty { int fd; pid_t child; struct ev_fd *efd; - struct kmscon_ring *msgbuf; + struct shl_ring *msgbuf; char io_buf[KMSCON_NREAD]; kmscon_pty_input_cb input_cb; @@ -79,7 +79,7 @@ int kmscon_pty_new(struct kmscon_pty **out, struct ev_eloop *loop, pty->input_cb = input_cb; pty->data = data; - ret = kmscon_ring_new(&pty->msgbuf); + ret = shl_ring_new(&pty->msgbuf); if (ret) goto err_free; @@ -108,7 +108,7 @@ void kmscon_pty_unref(struct kmscon_pty *pty) log_debug("free pty object"); kmscon_pty_close(pty); - kmscon_ring_free(pty->msgbuf); + shl_ring_free(pty->msgbuf); ev_eloop_unref(pty->eloop); free(pty); } @@ -268,10 +268,10 @@ static int send_buf(struct kmscon_pty *pty) size_t len; int ret; - while ((buf = kmscon_ring_peek(pty->msgbuf, &len))) { + while ((buf = shl_ring_peek(pty->msgbuf, &len))) { ret = write(pty->fd, buf, len); if (ret > 0) { - kmscon_ring_drop(pty->msgbuf, ret); + shl_ring_drop(pty->msgbuf, ret); continue; } @@ -408,7 +408,7 @@ int kmscon_pty_write(struct kmscon_pty *pty, const char *u8, size_t len) if (!pty || !pty_is_open(pty) || !u8 || !len) return -EINVAL; - if (!kmscon_ring_is_empty(pty->msgbuf)) + if (!shl_ring_is_empty(pty->msgbuf)) goto buf; ret = write(pty->fd, u8, len); @@ -427,7 +427,7 @@ int kmscon_pty_write(struct kmscon_pty *pty, const char *u8, size_t len) ev_fd_update(pty->efd, EV_READABLE | EV_WRITEABLE); buf: - ret = kmscon_ring_write(pty->msgbuf, u8, len); + ret = shl_ring_write(pty->msgbuf, u8, len); if (ret) log_warn("cannot allocate buffer; dropping output"); diff --git a/src/shl_ring.h b/src/shl_ring.h new file mode 100644 index 0000000..d668ab6 --- /dev/null +++ b/src/shl_ring.h @@ -0,0 +1,170 @@ +/* + * shl - Dynamic Array + * + * Copyright (c) 2011-2012 David Herrmann + * Copyright (c) 2011 University of Tuebingen + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files + * (the "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/* + * A circular memory ring implementation + */ + +#ifndef SHL_RING_H +#define SHL_RING_H + +#include +#include +#include +#include + +#define SHL_RING_SIZE 512 + +struct shl_ring_entry { + struct shl_ring_entry *next; + size_t len; + char buf[]; +}; + +struct shl_ring { + struct shl_ring_entry *first; + struct shl_ring_entry *last; +}; + +static inline int shl_ring_new(struct shl_ring **out) +{ + struct shl_ring *ring; + + if (!out) + return -EINVAL; + + ring = malloc(sizeof(*ring)); + if (!ring) + return -ENOMEM; + + memset(ring, 0, sizeof(*ring)); + + *out = ring; + return 0; +} + +static inline void shl_ring_free(struct shl_ring *ring) +{ + struct shl_ring_entry *tmp; + + if (!ring) + return; + + while (ring->first) { + tmp = ring->first; + ring->first = tmp->next; + free(tmp); + } + free(ring); +} + +static inline bool shl_ring_is_empty(struct shl_ring *ring) +{ + if (!ring) + return true; + + return ring->first == NULL; +} + +static inline int shl_ring_write(struct shl_ring *ring, const char *val, + size_t len) +{ + struct shl_ring_entry *ent; + size_t space, cp; + + if (!ring || !val || !len) + return -EINVAL; + +next: + ent = ring->last; + if (!ent || ent->len >= SHL_RING_SIZE) { + ent = malloc(sizeof(*ent) + SHL_RING_SIZE); + if (!ent) + return -ENOMEM; + + ent->len = 0; + ent->next = NULL; + if (ring->last) + ring->last->next = ent; + else + ring->first = ent; + ring->last = ent; + } + + space = SHL_RING_SIZE - ent->len; + if (len >= space) + cp = space; + else + cp = len; + + memcpy(&ent->buf[ent->len], val, cp); + ent->len += cp; + + val = &val[cp]; + len -= cp; + if (len > 0) + goto next; + + return 0; +} + +static inline const char *shl_ring_peek(struct shl_ring *ring, size_t *len) +{ + if (!ring || !ring->first) + return NULL; + + *len = ring->first->len; + return ring->first->buf; +} + +static inline void shl_ring_drop(struct shl_ring *ring, size_t len) +{ + struct shl_ring_entry *ent; + + if (!ring || !len) + return; + +next: + ent = ring->first; + if (!ent) + return; + + if (len >= ent->len) { + len -= ent->len; + ring->first = ent->next; + free(ent); + if (!ring->first) + ring->last = NULL; + + if (len) + goto next; + } else { + memmove(ent->buf, &ent->buf[len], ent->len - len); + ent->len -= len; + } +} + +#endif /* SHL_RING_H */ diff --git a/src/static_misc.c b/src/static_misc.c index f696b3f..928e81b 100644 --- a/src/static_misc.c +++ b/src/static_misc.c @@ -39,136 +39,6 @@ #include "htable.h" #include "static_misc.h" -#define RING_SIZE 512 - -struct ring_entry { - struct ring_entry *next; - size_t len; - char buf[]; -}; - -struct kmscon_ring { - struct ring_entry *first; - struct ring_entry *last; -}; - -int kmscon_ring_new(struct kmscon_ring **out) -{ - struct kmscon_ring *ring; - - if (!out) - return -EINVAL; - - ring = malloc(sizeof(*ring)); - if (!ring) - return -ENOMEM; - - memset(ring, 0, sizeof(*ring)); - - *out = ring; - return 0; -} - -void kmscon_ring_free(struct kmscon_ring *ring) -{ - struct ring_entry *tmp; - - if (!ring) - return; - - while (ring->first) { - tmp = ring->first; - ring->first = tmp->next; - free(tmp); - } - free(ring); -} - -bool kmscon_ring_is_empty(struct kmscon_ring *ring) -{ - if (!ring) - return true; - - return ring->first == NULL; -} - -int kmscon_ring_write(struct kmscon_ring *ring, const char *val, size_t len) -{ - struct ring_entry *ent; - size_t space, cp; - - if (!ring || !val || !len) - return -EINVAL; - -next: - ent = ring->last; - if (!ent || ent->len >= RING_SIZE) { - ent = malloc(sizeof(*ent) + RING_SIZE); - if (!ent) - return -ENOMEM; - - ent->len = 0; - ent->next = NULL; - if (ring->last) - ring->last->next = ent; - else - ring->first = ent; - ring->last = ent; - } - - space = RING_SIZE - ent->len; - if (len >= space) - cp = space; - else - cp = len; - - memcpy(&ent->buf[ent->len], val, cp); - ent->len += cp; - - val = &val[cp]; - len -= cp; - if (len > 0) - goto next; - - return 0; -} - -const char *kmscon_ring_peek(struct kmscon_ring *ring, size_t *len) -{ - if (!ring || !ring->first) - return NULL; - - *len = ring->first->len; - return ring->first->buf; -} - -void kmscon_ring_drop(struct kmscon_ring *ring, size_t len) -{ - struct ring_entry *ent; - - if (!ring || !len) - return; - -next: - ent = ring->first; - if (!ent) - return; - - if (len >= ent->len) { - len -= ent->len; - ring->first = ent->next; - free(ent); - if (!ring->first) - ring->last = NULL; - - if (len) - goto next; - } else { - memmove(ent->buf, &ent->buf[len], ent->len - len); - ent->len -= len; - } -} - struct kmscon_timer { struct timespec start; uint64_t elapsed; diff --git a/src/static_misc.h b/src/static_misc.h index ab6d3a0..9332a87 100644 --- a/src/static_misc.h +++ b/src/static_misc.h @@ -38,18 +38,6 @@ #include #include "static_hook.h" -/* ring buffer for arbitrary byte-streams */ - -struct kmscon_ring; - -int kmscon_ring_new(struct kmscon_ring **out); -void kmscon_ring_free(struct kmscon_ring *ring); -bool kmscon_ring_is_empty(struct kmscon_ring *ring); - -int kmscon_ring_write(struct kmscon_ring *ring, const char *val, size_t len); -const char *kmscon_ring_peek(struct kmscon_ring *ring, size_t *len); -void kmscon_ring_drop(struct kmscon_ring *ring, size_t len); - /* time measurement */ struct kmscon_timer; -- 2.7.4