chiark / gitweb /
New show-thing IPC
authorIan Jackson <ian@liberator.relativity.greenend.org.uk>
Thu, 4 Jun 2009 18:56:01 +0000 (19:56 +0100)
committerIan Jackson <ian@liberator.relativity.greenend.org.uk>
Thu, 4 Jun 2009 18:56:01 +0000 (19:56 +0100)
pctb/database
pctb/ocr.c
pctb/show-thing.tcl

index 83daefbae1f1177bb5d3dc1ae324e63beb969a1b..65c84ffe039f3c0b686480b7ee19f6af04f50df8 100644 (file)
@@ -34,6 +34,13 @@ fc0
 820
 820
 820
+1 1 65
+5
+7c0
+920
+920
+920
+9c0
 1 1 6e
 5
 fe0
index 43636f2d1c18861d77d890e8f49c2373a1bff627..7f3be26a0eaee8c90906129c674d56514d74ad54 100644 (file)
@@ -25,6 +25,7 @@ static int aresults, nresults;
 
 static FILE *resolver;
 static pid_t resolver_pid;
+static int resolver_done;
 
 static void ocr_readdb(void) {
   int ctx,nchrs;
@@ -91,23 +92,31 @@ static void ocr_readdb(void) {
 static void callout_unknown(int w, int h, Pixcol cols[],
                            int unk_l, int unk_r, int unk_ctx,
                            const OcrResultGlyph *sofar, int nsofar) {
-  int pfd[2], c, r,i, x,y;
+  int jobpipe[2],donepipe[2], c, r,i, x,y;
   const OcrResultGlyph *s;
   const char *p;
+  char cb;
   Pixcol pv;
   
   if (!resolver) {
-    r= pipe(pfd);  eassert(!r);
+    r= pipe(jobpipe);  eassert(!r);
+    r= pipe(donepipe);  eassert(!r);
     resolver_pid= fork();
     eassert(resolver_pid!=-1);
     if (!resolver_pid) {
-      r= dup2(pfd[0],0); eassert(!r);
-      r= close(pfd[1]); eassert(!r);
-      execlp("./show-thing.tcl", "./show-thing.tcl",(char*)0);
+      r= dup2(jobpipe[0],0); eassert(r==0);
+      r= close(jobpipe[1]); eassert(!r);
+      r= close(donepipe[0]); eassert(!r);
+      /* we know donepipe[1] is >= 4 and we have dealt with all the others
+       * so we aren't in any danger of overwriting some other fd 4: */
+      r= dup2(donepipe[1],4); eassert(r==4);
+      execlp("./show-thing.tcl", "./show-thing.tcl","--automatic",(char*)0);
       eassert(!"execlp failed");
     }
-    r= close(pfd[0]); eassert(!r);
-    resolver= fdopen(pfd[1],"w"); eassert(resolver);
+    r= close(jobpipe[0]); eassert(!r);
+    r= close(donepipe[1]); eassert(!r);
+    resolver= fdopen(jobpipe[1],"w"); eassert(resolver);
+    resolver_done= donepipe[0];
   }
   fprintf(resolver,"%d %d %d",unk_l,unk_r,unk_ctx);
   for (i=0, s=sofar; i<nsofar; i++, s++) {
@@ -138,30 +147,37 @@ static void callout_unknown(int w, int h, Pixcol cols[],
   eassert(!ferror(resolver));
   eassert(!fflush(resolver));
 
+  eassert(resolver);
+
   for (;;) {
-    eassert(resolver);
-    pid_t pid= waitpid(resolver_pid, &r, WUNTRACED);
-    if (pid==-1) { eassert(errno==EINTR); continue; }
+    r= read(resolver_done,&cb,1);
+    if (r==-1) { eassert(errno==EINTR); continue; }
+    break;
+  }
+
+  if (r==0) {
+    pid_t pid;
+    for (;;) {
+      pid= waitpid(resolver_pid, &r, 0);
+      if (pid==-1) { eassert(errno==EINTR); continue; }
+      break;
+    }
     eassert(pid==resolver_pid);
     if (WIFEXITED(r)) {
       eassert(!WEXITSTATUS(r));
       fclose(resolver);
+      close(resolver_done);
       resolver= 0;
-    } else if (WIFSTOPPED(r)) {
-      r= kill(resolver_pid,SIGCONT);
-      eassert(!r);
     } else if (WIFSIGNALED(r)) {
       eassert(!"resolver child died due to signal");
     } else {
       eassert(!"weird wait status");
     }
-    struct stat stab, fstab;
-    r= stat("database",&stab);  eassert(!r);
-    r= fstat(fileno(db),&fstab);  eassert(!r);
-    if (stab.st_ino != fstab.st_ino ||
-       stab.st_dev != fstab.st_dev)
-      break;
+  } else {
+    eassert(r==1);
+    eassert(cb==0);
   }
+
   fclose(db);
   db= 0;
   ocr_readdb();
index c0182238557b3dd5e64c5c020d5e8d4d4756393a..be07d2d50fa3f0b5c063430a26826df94238ca87 100755 (executable)
@@ -401,6 +401,7 @@ proc update_database/DELETE {l r ctx} {
     
 
 proc RETURN_RESULT {how what} {
+    global mainkind
     place forget .d.csr.csr
     pack forget .d.csr.csr.e
     helptext {{{ Processing }}}
@@ -408,13 +409,12 @@ proc RETURN_RESULT {how what} {
     update idletasks
     puts stderr "$how $what"
     eval update_database/$how $what
-    exec kill -STOP [pid]
-    fileevent stdin readable required
+    done/$mainkind
 }
 
 #---------- main progrm ----------
 
-proc test_main {} {
+proc main/test {} {
     global glyphsdone unk_l unk_r unk_context
 
     set glyphsdone {
@@ -433,6 +433,8 @@ proc test_main {} {
     draw_glyphsdone
     startup_cursor
 }
+proc done/test {} {
+}
 
 proc required {} {
     global glyphsdone unk_l unk_r unk_context
@@ -453,6 +455,20 @@ proc required {} {
     startup_cursor
 }
 
+proc main/automatic {} {
+    fconfigure stdin -blocking no
+    fileevent stdin readable required
+}
+proc done/automatic {} {
+    exec sh -c {printf \\0 >&4}
+    fileevent stdin readable required
+}
+
+switch -exact -- $argv {
+    {}           { set mainkind test }
+    --automatic  { set mainkind automatic }
+    default      { error "huh $argv ?" }
+}
+
 read_database
-fconfigure stdin -blocking no
-fileevent stdin readable required
+main/$mainkind