view src/test.cpp @ 98:91c27c00048f

tokenizer errors now go thru syslog to be visible during config file reloads in normal operation
author carl
date Thu, 22 Sep 2005 21:57:08 -0700
parents 2752e512fd32
children ecb40aa3eaa5
line wrap: on
line source

/*

Copyright (c) 2004 Carl Byington - 510 Software Group, released under
the GPL version 2 or any later version at your choice available at
http://www.fsf.org/licenses/gpl.txt

*/

#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <set>

static char* test_version="$Id$";

using namespace std;

struct ltstr {
    bool operator()(char* s1, char* s2) const {
        return strcmp(s1, s2) < 0;
    }
};

typedef set<char *, ltstr>                string_set;

static string_set all_strings;      // owns all the strings, only modified by the config loader thread

struct stats {
    bool    stop;
    bool    running;
    int     counter;
    int     errors;
    stats();
};
stats::stats() {
    stop    = false;
    running = false;
    counter = 0;
    errors  = 0;
}

////////////////////////////////////////////////
// helper to discard the strings held by a string_set
//
static void discard(string_set &s);
static void discard(string_set &s) {
    for (string_set::iterator i=s.begin(); i!=s.end(); i++) {
        free(*i);
    }
    s.clear();
}

////////////////////////////////////////////////
// helper to register a string in a string set
//
static char* register_string(string_set &s, char *name);
static char* register_string(string_set &s, char *name) {
    string_set::iterator i = s.find(name);
    if (i != s.end()) return *i;
    char *x = strdup(name);
    s.insert(x);
    return x;
}


////////////////////////////////////////////////
// thread tester
//
static void* tester(void *arg);
static void* tester(void *arg) {
    stats &st = *((stats *)arg);
    st.running = true;
    while (!st.stop) {
        const int LIMIT = 1000;
        string_set *mine = new string_set;
        string_set &me = *mine;
        for (int i=0; i<LIMIT; i++) {
            char buf[100];
            snprintf(buf, sizeof(buf), "this is string %d", i);
            register_string(me, buf);
        }
        for (int i=0; i<LIMIT; i+=5) {
            char buf[100];
            snprintf(buf, sizeof(buf), "this is string %d", i);
            string_set::iterator j = me.find(buf);
            if (j == me.end()) st.errors++;
        }
        discard(me);
        delete mine;
        st.counter++;
    }
    st.running = false;
    return NULL;
}

int main(int argc, char**argv)
{
    stats st1;
    stats st2;
    pthread_t tid;
    if (pthread_create(&tid, 0, tester, &st1))
        fprintf(stdout, "failed to create test thread");
    if (pthread_detach(tid))
        fprintf(stdout, "failed to detach test thread");
    if (pthread_create(&tid, 0, tester, &st2))
        fprintf(stdout, "failed to create test thread");
    if (pthread_detach(tid))
        fprintf(stdout, "failed to detach test thread");

    fprintf(stdout, "tests are running\n");
    sleep(60);
    st1.stop = true;
    st2.stop = true;
    while (st1.running || st2.running) {
        sleep(1);
    }

    fprintf(stdout, "counter 1 = %d\n", st1.counter);
    fprintf(stdout, "counter 2 = %d\n", st2.counter);
    fprintf(stdout, "errors 1 = %d\n", st1.errors);
    fprintf(stdout, "errors 2 = %d\n", st2.errors);
    return 0;
}