[sane-devel] Re: SANE, Darwin, Umax Vista-S6E problems

Julien BLACHE jb@jblache.org
Fri, 26 Dec 2003 20:43:56 +0100


--=-=-=

Randolph Fritz <randolph@panix.com> wrote:

Hi,

>> > So, then.  Let's try narrowing this down.  Does anyone have a Umax
>> > Vista-S6E working with SANE on any version of Mac OS 10.2?
>> 
>> That's unlikely. The UMAX backend still uses fork ().
>
> The code is already there for OS/2--I removed the conditional.  But it
> still fails in the same way--stops a bit of the way into a preview
> scan with a timeout.

Err, it's not /that/ simple. If somebody can give a try to the
attached patch, please tell me how it goes.

(I do not have such a scanner, and I'm not the backend maintainer, I
wrote the patch because a friend needed it, but it's not been tested
yet...)

JB.

-- 
Julien BLACHE                                   <http://www.jblache.org> 
<jb@jblache.org>                                  GPG KeyID 0xF5D65169


--=-=-=
Content-Type: text/x-patch
Content-Disposition: attachment; filename=umax.c-sanei_thread.patch
Content-Description: umax.c sanei_thread patch

--- umax.c.orig	2003-12-26 11:35:58.000000000 +0100
+++ umax.c	2003-12-26 12:12:44.000000000 +0100
@@ -49,7 +49,7 @@
 
 /* --------------------------------------------------------------------------------------------------------- */
 
-#define BUILD 40
+#define BUILD 41
 
 /* --------------------------------------------------------------------------------------------------------- */
 
@@ -133,9 +133,7 @@
 #include "sane/sanei_backend.h"
 #include "sane/sanei_config.h"
 
-#ifdef HAVE_OS2_H
 # include "../include/sane/sanei_thread.h"
-#endif
 
 #ifdef UMAX_ENABLE_USB
 # include "sane/sanei_usb.h"
@@ -4645,6 +4643,9 @@
 
 static SANE_Status do_cancel(Umax_Scanner *scanner)
 {
+  int pid;
+  int status;
+
   DBG(DBG_sane_proc,"do_cancel\n");
 
   scanner->scanning = SANE_FALSE;
@@ -4652,8 +4653,22 @@
   if (scanner->reader_pid > 0)
   {
     DBG(DBG_sane_info,"killing reader_process\n");
-    kill(scanner->reader_pid, SIGTERM);
-    waitpid(scanner->reader_pid, 0, 0);
+    sanei_thread_kill(scanner->reader_pid);
+    pid = sanei_thread_waitpid(scanner->reader_pid, &status);
+
+    if (pid < 0)
+      {
+	DBG(DBG_sane_info,
+	    "do_cancel: sanei_thread_waitpid failed, already terminated ? (%s)\n",
+	    strerror(errno));
+      }
+    else
+      {
+	DBG(DBG_sane_info,
+	    "do_cancel: reader_process terminated with status: %s\n",
+	    sane_strstatus(status));
+      }
+
     scanner->reader_pid = 0;
     DBG(DBG_sane_info,"reader_process killed\n");
 
@@ -4924,15 +4939,25 @@
 /* ------------------------------------------------------------ READER PROCESS ----------------------------- */
 
 
-static int reader_process(Umax_Scanner *scanner)			      /* executed as a child process */
+static int reader_process(void *data)			      /* executed as a child process */
 {
  FILE *fp;
  int status;
  unsigned int data_length;
  struct SIGACTION act;
  unsigned int i;
+ Umax_Scanner *scanner = (Umax_Scanner *)data;
 
-  DBG(DBG_sane_proc,"reader_process started\n");
+ if (sanei_thread_is_forked())
+   {
+     DBG(DBG_sane_proc,"reader_process started (forked)\n");
+     close (scanner->pipe_read_fd);
+     scanner->pipe_read_fd = -1;
+   }
+ else
+   {
+     DBG(DBG_sane_proc,"reader_process started (as thread)\n");
+   }
 
   scanner->device->scsi_maxqueue = scanner->device->request_scsi_maxqueue;
 
@@ -5956,6 +5981,7 @@
   first_handle = NULL;
 
   DBG_INIT();
+  sanei_thread_init();
 
   DBG(DBG_sane_init,"sane_init\n");
   DBG(DBG_error,"This is sane-umax version %d.%d build %d\n", V_MAJOR, V_MINOR, BUILD);
@@ -7950,31 +7976,23 @@
   scanner->pipe_read_fd  = fds[0]; 
   scanner->pipe_write_fd = fds[1];
 
-#ifndef HAVE_OS2_H
-  scanner->reader_pid = fork();					     /* create reader routine as new process */
-
-  if (scanner->reader_pid == 0)
-  {									/* reader_pid = 0 ===> child process */
-    sigset_t ignore_set;
-    struct SIGACTION act;
-
-    close(fds[0]); /* forked child process: close read end of pipe, reader_process only needs the write end */
-
-    sigfillset(&ignore_set);
-    sigdelset(&ignore_set, SIGTERM);
-    sigprocmask(SIG_SETMASK, &ignore_set, 0);
+  scanner->reader_pid = sanei_thread_begin (reader_process, (void *) scanner);
 
-    memset(&act, 0, sizeof (act));
-    sigaction (SIGTERM, &act, 0);
-
-    _exit(reader_process(scanner));   /* don't use exit() since that would run the atexit() handlers */
-  }
+  if (scanner->reader_pid < 0)
+    {
+      DBG(DBG_error, "ERROR: sanei_thread_begin failed (%s)\n",
+	  strerror(errno));
+      scanner->scanning = SANE_FALSE;
+      umax_give_scanner(scanner->device); /* reposition and release scanner */
+      umax_scsi_close(scanner->device);
+      return SANE_STATUS_NO_MEM;
+    }
 
-  close(fds[1]); /* when we use fork then we have to close the write end of the pipe here */
-#else /*  OS2 */
-  /* create reader routine as thread */
-  scanner->reader_pid = sanei_thread_begin(reader_process, (void *) scanner);
-#endif
+  if (sanei_thread_is_forked())
+    {
+      close(scanner->pipe_read_fd);
+      scanner->pipe_read_fd = -1;
+    }
 
  return SANE_STATUS_GOOD;
 }

--=-=-=--