/* $Id: parse.c,v 1.9 2004/03/23 04:50:13 jmuelmen Exp $ */ #include #include #include #include #include #include "parse.h" #include "scheduler.h" /* create a parse action */ parse_action_t *parse_action_create (void (*func) (value_t *, value_t **, int), value_t **argv, int argc) { int i; parse_action_t *p = malloc(sizeof(parse_action_t)); p->type = func_s; p->statement.func = func; for (i = 0; i < argc; p->args[i] = argv[i++]); p->n_args = argc; /* initialize the return */ value_init(&p->ret); return p; } /* process a parse action */ void parse_action_process (parse_action_t *a) { int i; value_t ret; /* check for no-op-ness */ if (!a->statement.func) { pthread_mutex_lock(&a->ret.mut); a->ret.returned = 1; pthread_mutex_unlock(&a->ret.mut); pthread_cond_signal(&a->ret.has_returned); return; } /* lock the return value */ pthread_mutex_lock(&a->ret.mut); /* printf("Locking arguments... "); */ /* fflush(stdout); */ /* lock the arguments */ for (i = 0; i < a->n_args; ++i) { pthread_mutex_lock(&a->args[i]->mut); /* if the argument hasn't returned yet, we have to wait */ while (!a->args[i]->returned) { #ifdef WINDOWS_IS_DOGSHIT if (usleep(WINDOWS_IS_DOGSHIT)) perror("Sleeping on argument eval"); #endif pthread_cond_wait(&a->args[i]->has_returned, &a->args[i]->mut); } } /* printf("arguments locked.\n"); */ /* fflush(stdout); */ /* printf("Locking return value... "); */ /* printf("return value locked.\n"); */ /* evaluate the action */ a->statement.func(&a->ret, a->args, a->n_args); a->ret.returned = 1; /* unlock the arguments */ i = 0; while (i < a->n_args) { pthread_mutex_unlock(&a->args[i]->mut); ++i; } /* unlock the return value */ pthread_mutex_unlock(&a->ret.mut); /* signal that we've returned */ pthread_cond_signal(&a->ret.has_returned); }