irctk

libircclient binding for scripts
git clone https://a3nm.net/git/irctk/
Log | Files | Refs | README

commit af23be5fbf336ebe8164668bdedbb48c1a224749
parent 9b5d8f3e633985d631f5b9c31e30bb9e16c6c374
Author: Antoine Amarilli <a3nm@a3nm.net>
Date:   Mon, 25 Jun 2012 15:48:55 +0200

ad hoc test suite now passes

Diffstat:
irctk.c | 115+++++++++++++++++++++++++++++++++++++++++++++++++------------------------------
1 file changed, 72 insertions(+), 43 deletions(-)

diff --git a/irctk.c b/irctk.c @@ -453,7 +453,8 @@ void debug_args() typedef struct line { char *line; char *full_line; - struct line* next_dep; + int next_dep_fifoidx; + int next_dep_lineidx; char is_head; char is_sendable; } line; @@ -605,6 +606,7 @@ int empty_fifo_set(fifo_set *s) { // } void realloc_chans(fifo_set *s) { + debug("realloc chans"); s->allocated *= 2; s->chans = realloc(s->chans, s->allocated*sizeof(char*)); s->was_pushed = realloc(s->was_pushed, s->allocated*sizeof(char*)); @@ -640,29 +642,34 @@ int index_of_chan(fifo_set *s, char *chan) { } -line *push_one(fifo_set *s, char *fl, char *dest, char *l, line *last_ptr) { +void push_one(fifo_set *s, char *fl, char *dest, char *l, + int next_dep_fifoidx, int next_dep_lineidx, + int *fifoidx, int *lineidx) { int c = index_of_chan(s, dest); - debug("push_one %s %p ioc %d", fl, last_ptr, c); + debug("push_one \"%s\" %d %d ioc %d", l, next_dep_fifoidx, next_dep_lineidx, c); fifo *f = &(s->fifos[c]); - line *result = &f->queue[f->tl]; if (s->was_pushed[c]) - return last_ptr; // already pushed + return; // already pushed s->was_pushed[c] = 1; f->queue[f->tl].line = l; f->queue[f->tl].full_line = fl; - f->queue[f->tl].next_dep = last_ptr; + f->queue[f->tl].next_dep_fifoidx = next_dep_fifoidx; + f->queue[f->tl].next_dep_lineidx = next_dep_lineidx; f->queue[f->tl].is_head = 0; f->queue[f->tl].is_sendable = 0; + *fifoidx = c; + *lineidx = f->tl; f->tl++; f->tl %= LINE_BUFFER; - return result; } -void set_last_ptr(fifo_set *s, char *chan, line *ptr) { +void set_last_idxes(fifo_set *s, char *chan, int fifoidx, int lineidx) { int c = index_of_chan(s, chan); fifo *f = &(s->fifos[c]); - debug("set_last_ptr %p for %s ioc %d", ptr, f->queue[f->tl - 1 + LINE_BUFFER % LINE_BUFFER].full_line, c); - f->queue[f->tl - 1 + LINE_BUFFER % LINE_BUFFER].next_dep = ptr; + debug("set_last_ptr %d %d for \"%s\" ioc %d", fifoidx, lineidx, + f->queue[f->tl - 1 + LINE_BUFFER % LINE_BUFFER].full_line, c); + f->queue[f->tl - 1 + LINE_BUFFER % LINE_BUFFER].next_dep_fifoidx = fifoidx; + f->queue[f->tl - 1 + LINE_BUFFER % LINE_BUFFER].next_dep_lineidx = lineidx; } void reset_chan_marks(fifo_set *s) { @@ -672,7 +679,7 @@ void reset_chan_marks(fifo_set *s) { } void push_fifo_set(fifo_set *s, char *fl, char *dests, char *l) { - debug("push_fifo_set %s", fl); + debug("push_fifo_set \"%s\"", fl); int was_empty; pthread_mutex_lock(&s->ctrl.mutex); while (full_fifo_set(s)) @@ -682,7 +689,8 @@ void push_fifo_set(fifo_set *s, char *fl, char *dests, char *l) { int i = 0; int cont = 1; char *last_dest, *first_dest; - line *last_ptr = 0, *first_ptr = 0; + int first_fifoidx = -1, first_lineidx = -1; + int fifoidx = 0, lineidx = 0, nfifoidx = 0, nlineidx = 0; last_dest = dests; @@ -696,30 +704,36 @@ void push_fifo_set(fifo_set *s, char *fl, char *dests, char *l) { cont = 0; if (i) dests[i] = 0; + debug("will push one \"%s\"", l); // only put the full line for *one* occurrence - last_ptr = push_one(s, !first_ptr?fl:NULL, last_dest, l, last_ptr); - assert(!cont); - if (!first_ptr) { - first_ptr = last_ptr; + push_one(s, first_fifoidx < 0?fl:NULL, last_dest, l, fifoidx, lineidx, &nfifoidx, &nlineidx); + fifoidx = nfifoidx; + lineidx = nlineidx; + if (first_fifoidx < 0) { + first_fifoidx = fifoidx; + first_lineidx = lineidx; first_dest = last_dest; - debug("first_ptr is %p full line %s, first_dest is %s", first_ptr, - first_ptr->full_line, first_dest); + // debug("first_ptr is %p full line %s, first_dest is %s", first_ptr, + // first_ptr->full_line, first_dest); } last_dest = dests + i + 1; } i++; } - debug("first_ptr is %p full line %s, first_dest is %s", first_ptr, - first_ptr->full_line, first_dest); - set_last_ptr(s, first_dest, first_ptr); + //debug("DDD %s", s->fifos[0].queue[0].line); + debug("finished at i:%d", i); + + // debug("first_ptr is %p full line %s, first_dest is %s", first_ptr, + // first_ptr->full_line, first_dest); + set_last_idxes(s, first_dest, first_fifoidx, first_lineidx); if (was_empty) { debug("signal for empty"); pthread_cond_signal(&s->ctrl.empty); } pthread_mutex_unlock(&s->ctrl.mutex); -} +} void mark_head(fifo *f) { f->queue[f->hd].is_head = 1; f->queue[f->hd].is_sendable = 0; @@ -731,32 +745,35 @@ void mark_heads(fifo_set *s) { mark_head(&s->fifos[i]); } -int mark_sendable_line(line *l) { +int mark_sendable_line(fifo_set *s, line *l) { if (!l->is_head) return 0; if (l->is_sendable) return 1; l->is_sendable = 1; - // TODO TODO TODO lift this when we have real deps - debug("i am (%p) %s depending on (%p) %s", l, l->line, l->next_dep, l->next_dep->line); - assert(l->next_dep == l); - return mark_sendable_line(l->next_dep); + debug("i am (%p) %s depending on (%d %d)", l, l->line, l->next_dep_fifoidx, + l->next_dep_lineidx); + //assert(l->next_dep == l); + line* ptr = &(s->fifos[l->next_dep_fifoidx].queue[l->next_dep_lineidx]); + return mark_sendable_line(s, ptr); } -int mark_sendable(fifo *f) { - return mark_sendable_line(&f->queue[f->hd]); +int mark_sendable(fifo_set *s, fifo *f) { + if (empty(f)) + return 1; + return mark_sendable_line(s, &f->queue[f->hd]); } -void unmark_sendable_line(line *l) { +void unmark_sendable_line(fifo_set *s, line *l) { if (!l->is_sendable) return; l->is_sendable = 0; - unmark_sendable_line(l->next_dep); + line* ptr = &(s->fifos[l->next_dep_fifoidx].queue[l->next_dep_lineidx]); + unmark_sendable_line(s, ptr); } -void unmark_sendable(fifo *f) { - unmark_sendable_line(&f->queue[f->hd]); +void unmark_sendable(fifo_set *s, fifo *f) { + unmark_sendable_line(s, &f->queue[f->hd]); } void pop_if_sendable(fifo_set *s, int c, int *n_result, action *result) { fifo *f = &s->fifos[c]; - // don't push sentinel if (f->queue[f->hd].is_sendable && f->queue[f->hd].line) { result[*n_result].line = f->queue[f->hd].line; result[*n_result].full_line = f->queue[f->hd].full_line; @@ -764,6 +781,12 @@ void pop_if_sendable(fifo_set *s, int c, int *n_result, action *result) { (*n_result)++; f->hd++; f->hd %= LINE_BUFFER; + } else { + // don't pop sentinel + //debug("don't pop: channel %d position %d was_sendable? %d, line %p", c, f->hd, + // f->queue[f->hd].is_sendable, + // f->queue[f->hd].line); + debug("don't pop channel %d", c); } } @@ -783,8 +806,8 @@ int pop_fifo_set(fifo_set *s, action **result) { for (i=0; i<s->n; i++) { debug("doing fifo for chan %s", s->chans[i]); debug("fifo hd %d tl %d", s->fifos[i].hd, s->fifos[i].tl); - if (!mark_sendable(&s->fifos[i])) - unmark_sendable(&s->fifos[i]); + if (!mark_sendable(s, &s->fifos[i])) + unmark_sendable(s, &s->fifos[i]); } // freeing result is responsibility of callee *result = malloc(s->n * sizeof(line)); @@ -793,6 +816,7 @@ int pop_fifo_set(fifo_set *s, action **result) { pop_if_sendable(s, i, &n_result, *result); if (!n_result) { // only thing left is sentinel, return sentinel + debug("only thing to return is sentinel"); n_result = 1; result[0]->line = NULL; result[0]->full_line = NULL; @@ -1423,20 +1447,25 @@ int test_fifo_set() { strcpy(chan3, "chan3"); strcpy(chan13, "chan1,chan3"); - push_fifo_set(&fifos, msga1, chan1, NULL); - push_fifo_set(&fifos, msga2, chan2, NULL); - push_fifo_set(&fifos, msga3, chan3, NULL); - push_fifo_set(&fifos, msgb1, chan1, NULL); - //push_fifo_set(&fifos, msgc13, chan13, NULL); + push_fifo_set(&fifos, NULL, chan1, msga1); + push_fifo_set(&fifos, NULL, chan2, msga2); + push_fifo_set(&fifos, NULL, chan3, msga3); + push_fifo_set(&fifos, NULL, chan1, msgb1); + push_fifo_set(&fifos, NULL, chan13, msgc13); push_fifo_set(&fifos, NULL, "", NULL); while (cont) { n_results = pop_fifo_set(&fifos, &results); + printf("got %d results\n", n_results); + if (!n_results) + break; for (i=0; i<n_results; i++) { if (!results[i].line) { cont = 0; + printf("read sentinel\n"); + } else { + printf("read: %s\n", results[i].line); } - printf("%s\n", results[i].line); } } printf("finished\n"); @@ -1454,7 +1483,7 @@ int main (int argc, char **argv) // initialize the fifo init_fifo_set(&fifos); - return test_fifo_set(); + //return test_fifo_set(); // start trying to connet with the initial retry interval return start(args.retry_after);