+struct depend {
+ /* We can have more than one */
+ struct list_node list;
+ unsigned int file;
+ unsigned int op;
+};
+
+struct depend_xmit {
+ unsigned int dst_op;
+ unsigned int src_file, src_op;
+};
+
+static void remove_matching_dep(struct list_head *deps,
+ unsigned int file, unsigned int op)
+{
+ struct depend *dep;
+
+ list_for_each(deps, dep, list) {
+ if (dep->file == file && dep->op == op) {
+ list_del(&dep->list);
+ return;
+ }
+ }
+ errx(1, "Failed to find depend on file %u line %u\n", file, op+1);
+}
+
+static void check_deps(const char *filename, struct op op[], unsigned int num)
+{
+#ifdef DEBUG_DEPS
+ unsigned int i;
+
+ for (i = 1; i < num; i++)
+ if (!list_empty(&op[i].pre))
+ fail(filename, i+1, "Still has dependencies");
+#endif
+}
+
+static void dump_pre(char *filename[], unsigned int file,
+ struct op op[], unsigned int i)
+{
+ struct depend *dep;
+
+ printf("%s:%u still waiting for:\n", filename[file], i+1);
+ list_for_each(&op[i].pre, dep, list)
+ printf(" %s:%u\n", filename[dep->file], dep->op+1);
+ check_deps(filename[file], op, i);
+}
+
+static void do_pre(char *filename[], unsigned int file, int pre_fd,
+ struct op op[], unsigned int i)
+{
+ while (!list_empty(&op[i].pre)) {
+ struct depend_xmit dep;
+
+#if DEBUG_DEPS
+ printf("%s:%u:waiting for pre\n", filename[file], i+1);
+ fflush(stdout);
+#endif
+ alarm(10);
+ while (read(pre_fd, &dep, sizeof(dep)) != sizeof(dep)) {
+ if (errno == EINTR) {
+ dump_pre(filename, file, op, i);
+ exit(1);
+ } else
+ errx(1, "Reading from pipe");
+ }
+ alarm(0);
+
+#if DEBUG_DEPS
+ printf("%s:%u:got pre %u from %s:%u\n", filename[file], i+1,
+ dep.dst_op+1, filename[dep.src_file], dep.src_op+1);
+ fflush(stdout);
+#endif
+ /* This could be any op, not just this one. */
+ remove_matching_dep(&op[dep.dst_op].pre,
+ dep.src_file, dep.src_op);
+ }
+}
+
+static void do_post(char *filename[], unsigned int file,
+ const struct op op[], unsigned int i)
+{
+ struct depend *dep;
+
+ list_for_each(&op[i].post, dep, list) {
+ struct depend_xmit dx;
+
+ dx.src_file = file;
+ dx.src_op = i;
+ dx.dst_op = dep->op;
+#if DEBUG_DEPS
+ printf("%s:%u:sending to file %s:%u\n", filename[file], i+1,
+ filename[dep->file], dep->op+1);
+#endif
+ if (write(pipes[dep->file].fd[1], &dx, sizeof(dx))
+ != sizeof(dx))
+ err(1, "%s:%u failed to tell file %s",
+ filename[file], i+1, filename[dep->file]);
+ }
+}
+