Fix ordering in perl subscription_list
[blerg.git] / common / stringring.c
index c788db8..7784e1b 100644 (file)
@@ -2,6 +2,7 @@
  * BSD-style license.  Please see the COPYING file for details.
  */
 
+#include <sys/file.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <sys/mman.h>
 #include <unistd.h>
 #include <stdint.h>
 #include <stdlib.h>
+#include <stdio.h>
 #include <string.h>
 #include <time.h>
 #include <stringring.h>
 
 #define STRINGRING_DATA_CHECK() \
-       if (sh == NULL)         \
+       if (sr == NULL)         \
                return 0;       \
        if (data == NULL)       \
                return 0;       \
                return 0;
 
 
-struct stringring_handle * stringring_open(const char *filename) {
-       struct stringring_handle *sh;
+struct stringring * stringring_open(const char *filename) {
+       struct stringring *sr;
        struct stat st;
        int initialize = 0;
 
-       sh = malloc(sizeof(struct stringring_handle));
-       if (sh == NULL) {
+       sr = malloc(sizeof(struct stringring));
+       if (sr == NULL) {
                perror("stringring_handle malloc");
                return NULL;
        }
 
-       sh->fd = open(filename, O_RDWR | O_CREAT, 0600);
-       flock(sh->fd, LOCK_EX);
-       if (sh->fd == -1) {
+       sr->fd = open(filename, O_RDWR | O_CREAT, 0600);
+       flock(sr->fd, LOCK_EX);
+       if (sr->fd == -1) {
                perror("stringring open");
                goto stringring_open__open_failed;
        }
 
-       fstat(sh->fd, &st);
-       if (st.st_size < sizeof(struct stringring)) {
-               ftruncate(sh->fd, sizeof(struct stringring));
+       fstat(sr->fd, &st);
+       if (st.st_size < sizeof(struct stringring_block)) {
+               ftruncate(sr->fd, sizeof(struct stringring_block));
                initialize = 1;
        }
-       sh->sr = mmap(NULL, sizeof(struct stringring), PROT_READ | PROT_WRITE, MAP_SHARED, sh->fd, 0);
-       if (sh->sr == MAP_FAILED) {
+       sr->sb = mmap(NULL, sizeof(struct stringring_block), PROT_READ | PROT_WRITE, MAP_SHARED, sr->fd, 0);
+       if (sr->sb == MAP_FAILED) {
                perror("stringring mmap");
                goto stringring_open__map_failed;
        }
 
        if (initialize) {
-               stringring_clear(sh);
+               stringring_clear(sr);
        }
-       flock(sh->fd, LOCK_UN);
+       flock(sr->fd, LOCK_UN);
 
-       return sh;
+       return sr;
 
 stringring_open__map_failed:
-       flock(sh->fd, LOCK_UN);
-       fclose(sh->fd);
+       flock(sr->fd, LOCK_UN);
+       close(sr->fd);
 stringring_open__open_failed:
-       free(sh);
+       free(sr);
        return NULL;
 }
 
-void stringring_close(struct stringring_handle *sh) {
-       if (sh == NULL)
+void stringring_close(struct stringring *sr) {
+       if (sr == NULL)
                return;
 
-       if (sh->sr != NULL)
-               munmap(sh->sr, sizeof(struct stringring));
+       if (sr->sb != NULL)
+               munmap(sr->sb, sizeof(struct stringring_block));
 
-       if (sh->fd > -1)
-               close(sh->fd);
+       if (sr->fd > -1)
+               close(sr->fd);
 
-       free(sh);
+       free(sr);
 }
 
-int stringring_add(struct stringring_handle *sh, const char *data) {
+int stringring_add(struct stringring *sr, const char *data) {
        STRINGRING_DATA_CHECK();
 
-       flock(sh->fd, LOCK_EX);
-       if (sh->sr->counter == 0) {
-               sh->sr->counter = STRINGRING_N_ENTRIES - 1;
+       flock(sr->fd, LOCK_EX);
+       if (sr->sb->counter == 0) {
+               sr->sb->counter = STRINGRING_N_ENTRIES - 1;
        } else {
-               sh->sr->counter--;
+               sr->sb->counter--;
        }
 
        int data_len = strlen(data);
-       sh->sr->entries[sh->sr->counter].timestamp = time(NULL);
-       strncpy(sh->sr->entries[sh->sr->counter].data, data, STRINGRING_DATA_SIZE);
+       sr->sb->entries[sr->sb->counter].timestamp = time(NULL);
+       strncpy((char *)sr->sb->entries[sr->sb->counter].data, data, STRINGRING_DATA_SIZE);
        if (data_len < STRINGRING_DATA_SIZE) {
                /* zero out the rest of the data */
-               memset(sh->sr->entries[sh->sr->counter].data + data_len, 0, STRINGRING_DATA_SIZE - data_len);
+               memset(sr->sb->entries[sr->sb->counter].data + data_len, 0, STRINGRING_DATA_SIZE - data_len);
        }
-       flock(sh->fd, LOCK_UN);
+       flock(sr->fd, LOCK_UN);
 
        return 1;
 }
 
-int stringring_find_unlocked(struct stringring_handle *sh, const char *data, uint64_t cutoff) {
+int stringring_find_unlocked(struct stringring *sr, const char *data, uint64_t cutoff) {
        int n, i;
 
-       i = sh->sr->counter;
+       i = sr->sb->counter;
        for (n = 0; n < STRINGRING_N_ENTRIES; n++) {
-               if (sh->sr->entries[i].timestamp > 0 &&
-                   sh->sr->entries[i].timestamp > cutoff &&
-                   strncmp(sh->sr->entries[i].data, data, STRINGRING_DATA_SIZE) == 0) {
+               if (sr->sb->entries[i].timestamp > 0 &&
+                   sr->sb->entries[i].timestamp > cutoff &&
+                   strncmp((char *)sr->sb->entries[i].data, data, STRINGRING_DATA_SIZE) == 0) {
                        return i;
                }
                i = (i + 1) % STRINGRING_N_ENTRIES;
@@ -117,58 +119,73 @@ int stringring_find_unlocked(struct stringring_handle *sh, const char *data, uin
        return -1;
 }
 
-int stringring_find(struct stringring_handle *sh, const char *data, unsigned int max_age) {
+int stringring_find(struct stringring *sr, const char *data, unsigned int max_age) {
        int ret;
        uint64_t cutoff = (max_age > 0 ? time(NULL) - max_age : 0);
 
-       flock(sh->fd, LOCK_SH);
-       ret = stringring_find_unlocked(sh, data, cutoff);
-       flock(sh->fd, LOCK_UN);
+       flock(sr->fd, LOCK_SH);
+       ret = stringring_find_unlocked(sr, data, cutoff);
+       flock(sr->fd, LOCK_UN);
 
        return ret;
 }
 
-int stringring_remove_index_unlocked(struct stringring_handle *sh, int idx) {
-       if (sh == NULL)
+int stringring_remove_index_unlocked(struct stringring *sr, int idx) {
+       if (sr == NULL)
                return 0;
        if (idx < 0 || idx >= STRINGRING_N_ENTRIES)
                return 0;
 
-       sh->sr->entries[idx].timestamp = 0;
-       memset(sh->sr->entries[idx].data, 0, STRINGRING_DATA_SIZE);
+       sr->sb->entries[idx].timestamp = 0;
+       memset(sr->sb->entries[idx].data, 0, STRINGRING_DATA_SIZE);
 
        return 1;
 }
 
-int stringring_remove_index(struct stringring_handle *sh, int idx) {
+int stringring_remove_index(struct stringring *sr, int idx) {
        int ret;
 
-       flock(sh->fd, LOCK_EX);
-       ret = stringring_remove_index_unlocked(sh, idx);
-       flock(sh->fd, LOCK_UN);
+       flock(sr->fd, LOCK_EX);
+       ret = stringring_remove_index_unlocked(sr, idx);
+       flock(sr->fd, LOCK_UN);
 
        return ret;
 }
 
-int stringring_remove(struct stringring_handle *sh, const char *data) {
+int stringring_touch(struct stringring *sr, const char *data) {
+       STRINGRING_DATA_CHECK();
+       int ret, idx;
+
+       flock(sr->fd, LOCK_EX);
+       idx = stringring_find_unlocked(sr, data, 0);
+       ret = idx >= 0;
+       if (ret) {
+               sr->sb->entries[idx].timestamp = time(NULL);
+       }
+       flock(sr->fd, LOCK_UN);
+
+       return ret;
+}
+
+int stringring_remove(struct stringring *sr, const char *data) {
        STRINGRING_DATA_CHECK();
        int ret;
 
-       flock(sh->fd, LOCK_EX);
-       ret = stringring_remove_index_unlocked(sh,
-                       stringring_find_unlocked(sh, data, 0));
-       flock(sh->fd, LOCK_UN);
+       flock(sr->fd, LOCK_EX);
+       ret = stringring_remove_index_unlocked(sr,
+                       stringring_find_unlocked(sr, data, 0));
+       flock(sr->fd, LOCK_UN);
 
        return ret;
 }
 
-int stringring_clear(struct stringring_handle *sh) {
-       if (sh == NULL)
+int stringring_clear(struct stringring *sr) {
+       if (sr == NULL)
                return 0;
 
-       flock(sh->fd, LOCK_EX);
-       memset(sh->sr, 0, sizeof(struct stringring));
-       flock(sh->fd, LOCK_UN);
+       flock(sr->fd, LOCK_EX);
+       memset(sr->sb, 0, sizeof(struct stringring_block));
+       flock(sr->fd, LOCK_UN);
 
        return 1;
 }