/* $Id: atbuf.c,v 1.7 2004/04/03 04:17:37 jmuelmen Exp $ */ #include "scheduler.h" #include "buf.h" #include "parse.h" #include "shell.h" #include "act.h" #include #include #include #include static buf_t _atbuf; inline void atbuf_init () { buf_init(&_atbuf); } void atbuf_lock () { pthread_mutex_lock(&_atbuf.mut); } void atbuf_unlock () { pthread_mutex_unlock(&_atbuf.mut); } int atbuf_buf (parse_action_t *a) { int retval; retval = buf_buf(&_atbuf, a); return retval; } inline void atbuf_dump () { printf("At buffer:\n"); buf_dump(&_atbuf); } int atbuf_process_segment (parse_action_t ***start, parse_action_t *end) { return buf_process_segment(&_atbuf, start, end, 0); } void *atbuf_process_action (void *p) /* run the statement pointed to by p */ { parse_action_t **i = (parse_action_t **)p; time_t now, run; /* remember where we are */ parse_action_t *a = *i; value_t *v; /* lock the action */ pthread_mutex_lock(&a->statement.statement.mut); /* process the predicate first */ ++i; atbuf_process_segment(&i, a->statement.statement.eop); v = a->args[0]; /* wait until the predicate has been evaluated */ pthread_mutex_lock(&v->mut); while (!v->returned) { #ifdef WINDOWS_IS_DOGSHIT if (usleep(WINDOWS_IS_DOGSHIT)) perror("Sleeping on atbuf predicate eval"); #endif pthread_cond_wait(&v->has_returned, &v->mut); } /* figure out when the at statement is supposed to run */ conv_time(&run, v); pthread_mutex_unlock(&v->mut); time(&now); pthread_mutex_unlock(&a->statement.statement.mut); if (run > now) if (sleep(run - now)) printf("Failed sleeping atbuf\n"); pthread_mutex_lock(&a->statement.statement.mut); if (a->statement.statement.cancel) return NULL; ++i; atbuf_process_segment(&i, a->statement.statement.eos); pthread_mutex_unlock(&a->statement.statement.mut); return NULL; } int atbuf_process () { static parse_action_t **i = _atbuf.actions; for (; i < _atbuf.actions + _atbuf.n_actions; ++i) { pthread_t thr; parse_action_t *a = *i; /* run a thread that waits for this action's time to come */ pthread_create(&thr, NULL, atbuf_process_action, i); while (*i != a->statement.statement.eos) ++i; } return 0; } void *atbuf (void *arg) { while (1) { /* printf("Processing atbuf\n"); */ atbuf_lock(); /* wait for the buffer to change */ while (!_atbuf.changed) { #ifdef WINDOWS_IS_DOGSHIT if (usleep(WINDOWS_IS_DOGSHIT)) perror("Sleeping on atbuf contents"); #endif /* printf("Waiting on atbuf contents\n"); */ pthread_cond_wait(&_atbuf.has_changed, &_atbuf.mut); } _atbuf.changed = 0; /* when it's changed, process it */ atbuf_process(); atbuf_unlock(); } return NULL; }