Use sanei_thread in snapscan backend

merge-requests/1/head
Oliver Schwartz 2004-04-08 21:53:10 +00:00
rodzic a2f4f13f7a
commit 472d9ab2f5
6 zmienionych plików z 156 dodań i 84 usunięć

Wyświetl plik

@ -1,3 +1,11 @@
2004-04-08 Oliver Schwartz <Oliver.Schwartz@gmx.de>
* backend/snapscan.c backend/snapscan-sources.c
backend/snapscan.h backend/Makefile.in:
Use sanei_thread functions instead of forking
* backend/snapscan-options.c: Change title and description
for OPT_HIGHQUALITY to use existing i18n translations
2004-04-06 Gerard Klaver <gerard at gkall dot hobby dot nl>
* backend/test.c changed some option group headers to advanced option
@ -33,7 +41,8 @@
2004-04-02 Oliver Schwartz <Oliver.Schwartz@gmx.de>
* snapscan.c snapscan-options.c snapscan-scsi.c:
* backend/snapscan.c backend/snapscan-options.c
backend/snapscan-scsi.c:
Various bugfixes for gamma correction (Thanks to Robert Tsien)
* po/sane-backends.de.po: Fix translation for "gamma table"

Wyświetl plik

@ -390,6 +390,7 @@ libsane-snapscan.la: ../sanei/sanei_config2.lo
libsane-snapscan.la: ../sanei/sanei_constrain_value.lo
libsane-snapscan.la: ../sanei/sanei_scsi.lo
libsane-snapscan.la: ../sanei/sanei_usb.lo
libsane-snapscan.la: ../sanei/sanei_thread.lo
libsane-sp15c.la: ../sanei/sanei_config2.lo
libsane-sp15c.la: ../sanei/sanei_constrain_value.lo
libsane-sp15c.la: ../sanei/sanei_scsi.lo

Wyświetl plik

@ -307,8 +307,8 @@ static void init_options (SnapScan_Scanner * ps)
ps->preview = DEFAULT_PREVIEW;
po[OPT_HIGHQUALITY].name = "high-quality";
po[OPT_HIGHQUALITY].title = SANE_I18N("High quality");
po[OPT_HIGHQUALITY].desc = SANE_I18N("Scan in (slower) high quality mode");
po[OPT_HIGHQUALITY].title = SANE_I18N("Quality scan");
po[OPT_HIGHQUALITY].desc = SANE_I18N("Highest quality but lower speed");
po[OPT_HIGHQUALITY].type = SANE_TYPE_BOOL;
po[OPT_HIGHQUALITY].unit = SANE_UNIT_NONE;
po[OPT_HIGHQUALITY].size = sizeof (SANE_Word);
@ -1488,6 +1488,9 @@ SANE_Status sane_control_option (SANE_Handle h,
/*
* $Log$
* Revision 1.16 2004/04/08 21:53:10 oliver-guest
* Use sanei_thread in snapscan backend
*
* Revision 1.15 2004/04/02 20:19:23 oliver-guest
* Various bugfixes for gamma corretion (thanks to Robert Tsien)
*

Wyświetl plik

@ -175,7 +175,8 @@ static SANE_Status SCSISource_get (Source *pself,
DBG (DL_CALL_TRACE, "%s\n", me);
while (remaining > 0
&& pself->remaining(pself) > 0
&& status == SANE_STATUS_GOOD)
&& status == SANE_STATUS_GOOD
&& !cancelRead)
{
SANE_Int ndata = ps->scsi_buf_max - ps->scsi_buf_pos;
DBG (DL_DATA_TRACE, "%s: ndata %d; remaining %d\n", me, ndata, remaining);
@ -547,7 +548,8 @@ static SANE_Status Expander_get (Source *pself, SANE_Byte *pbuf, SANE_Int *plen)
while (remaining > 0
&&
pself->remaining(pself) > 0)
pself->remaining(pself) > 0 &&
!cancelRead)
{
if (ps->ch_pos == ps->ch_ndata)
{
@ -711,7 +713,7 @@ static SANE_Status RGBRouter_get (Source *pself,
SANE_Int org_len = *plen;
char *me = "RGBRouter_get";
while (remaining > 0 && pself->remaining(pself) > 0)
while (remaining > 0 && pself->remaining(pself) > 0 && !cancelRead)
{
DBG(DL_DATA_TRACE, "%s: remaining=%d, pself->remaining=%d, round_req=%d, cb_size=%d\n",
me, remaining, pself->remaining(pself), ps->round_req, ps->cb_size);
@ -736,7 +738,7 @@ static SANE_Status RGBRouter_get (Source *pself,
}
ps->round_read += run_req;
}
while (ps->round_req > ps->round_read);
while ((ps->round_req > ps->round_read) && !cancelRead);
/* route RGB */
ps->cb_start = (ps->cb_start + ps->round_read)%ps->cb_size;
@ -965,6 +967,9 @@ static SANE_Status create_source_chain (SnapScan_Scanner *pss,
/*
* $Log$
* Revision 1.7 2004/04/08 21:53:10 oliver-guest
* Use sanei_thread in snapscan backend
*
* Revision 1.6 2001/12/17 22:51:49 oliverschwartz
* Update to snapscan-20011212 (snapscan 1.4.3)
*

Wyświetl plik

@ -71,6 +71,7 @@
#include "../include/sane/sanei.h"
#include "../include/sane/sanei_scsi.h"
#include "../include/sane/sanei_usb.h"
#include "../include/sane/sanei_thread.h"
#ifndef PATH_MAX
#define PATH_MAX 1024
@ -191,6 +192,7 @@ static inline int calibration_line_length(SnapScan_Scanner *pss)
static SnapScan_Device *first_device = NULL; /* device list head */
static SANE_Int n_devices = 0; /* the device count */
static SANE_Char *default_firmware_filename;
static SANE_Bool cancelRead;
/* list returned from sane_get_devices() */
static const SANE_Device **get_devices_list = NULL;
@ -669,6 +671,7 @@ SANE_Status sane_init (SANE_Int *version_code,
n_devices = 0;
sanei_usb_init();
sanei_thread_init();
/* build a device structure */
fp = sanei_config_open (SNAPSCAN_CONFIG_FILE);
@ -1073,14 +1076,6 @@ SANE_Status sane_get_parameters (SANE_Handle h,
/* scan data reader routine for child process */
static void handler (int signo)
{
signal (signo, handler);
DBG (DL_MINOR_INFO, "child process: received signal %ld\n", (long) signo);
close (STDOUT_FILENO);
_exit(0);
}
#define READER_WRITE_SIZE 4096
static void reader (SnapScan_Scanner *pss)
@ -1096,28 +1091,27 @@ static void reader (SnapScan_Scanner *pss)
if (wbuf == NULL)
{
DBG (DL_MAJOR_ERROR, "%s: failed to allocate write buffer.\n", me);
_exit(1);
return;
}
while (pss->psrc->remaining(pss->psrc) > 0)
while ((pss->preadersrc->remaining(pss->preadersrc) > 0) && !cancelRead)
{
SANE_Int ndata = READER_WRITE_SIZE;
status = pss->psrc->get(pss->psrc, wbuf, &ndata);
status = pss->preadersrc->get(pss->preadersrc, wbuf, &ndata);
if (status != SANE_STATUS_GOOD)
{
DBG (DL_MAJOR_ERROR,
"%s: %s on read.\n",
me,
sane_strstatus (status));
close (STDOUT_FILENO);
_exit (1);
return;
}
{
SANE_Byte *buf = wbuf;
DBG (DL_DATA_TRACE, "READ %d BYTES\n", ndata);
DBG (DL_DATA_TRACE, "READ %d BYTES (%d)\n", ndata, cancelRead);
while (ndata > 0)
{
int written = write (STDOUT_FILENO, buf, ndata);
int written = write (pss->rpipe[1], buf, ndata);
DBG (DL_DATA_TRACE, "WROTE %d BYTES\n", written);
if (written == -1)
{
@ -1136,6 +1130,75 @@ static void reader (SnapScan_Scanner *pss)
}
}
/** signal handler to kill the child process
*/
static RETSIGTYPE usb_reader_process_sigterm_handler( int signo )
{
DBG( DL_INFO, "(SIG) reader_process: terminated by signal %d\n", signo );
cancelRead = SANE_TRUE;
}
static RETSIGTYPE sigalarm_handler( int signo )
{
signo=signo;
DBG( DL_INFO, "ALARM!!!\n" );
}
/** executed as a child process
* read the data from the driver and send them to the parent process
*/
static int reader_process( void *args )
{
SANE_Status status;
struct SIGACTION act;
sigset_t ignore_set;
SnapScan_Scanner *pss = (SnapScan_Scanner *) args;
if( sanei_thread_is_forked()) {
DBG( DL_MINOR_INFO, "reader_process started (forked)\n" );
/* child process - close read side, make stdout the write side of the pipe */
close( pss->rpipe[0] );
pss->rpipe[0] = -1;
} else {
DBG( DL_MINOR_INFO, "reader_process started (as thread)\n" );
}
sigfillset ( &ignore_set );
sigdelset ( &ignore_set, SIGUSR1 );
sigprocmask( SIG_SETMASK, &ignore_set, 0 );
memset ( &act, 0, sizeof (act));
sigaction( SIGTERM, &act, 0 );
cancelRead = SANE_FALSE;
/* install the signal handler */
sigemptyset(&(act.sa_mask));
act.sa_flags = 0;
act.sa_handler = usb_reader_process_sigterm_handler;
sigaction( SIGUSR1, &act, 0 );
status = create_base_source (pss, SCSI_SRC, &(pss->preadersrc));
if (status == SANE_STATUS_GOOD)
{
reader (pss);
}
else
{
DBG (DL_MAJOR_ERROR,
"Reader process: failed to create SCSISource.\n");
}
pss->preadersrc->done(pss->preadersrc);
free(pss->preadersrc);
pss->preadersrc = 0;
close( pss->rpipe[1] );
pss->rpipe[1] = -1;
DBG( DL_MINOR_INFO, "reader_process: finished reading data\n" );
return SANE_STATUS_GOOD;
}
static SANE_Status start_reader (SnapScan_Scanner *pss)
{
SANE_Status status = SANE_STATUS_GOOD;
@ -1143,71 +1206,38 @@ static SANE_Status start_reader (SnapScan_Scanner *pss)
DBG (DL_CALL_TRACE, "%s\n", me);
/* We can implement nonblocking mode by forking a separate reader
process. It doesn't seem that we can poll the scsi descriptor. */
pss->nonblocking = SANE_FALSE;
pss->rpipe[0] = pss->rpipe[1] = -1;
pss->child = -1;
if (pss->pdev->model == PRISA610
||
pss->pdev->model == ACER300F
||
pss->pdev->model == SNAPSCAN310
||
pss->pdev->model == PRISA310
||
pss->pdev->model == SNAPSCANE20
||
pss->pdev->model == SNAPSCANE50
||
pss->pdev->model == SNAPSCAN1236)
{
status = SANE_STATUS_UNSUPPORTED;
}
else if (pipe (pss->rpipe) != -1)
if (pipe (pss->rpipe) != -1)
{
pss->orig_rpipe_flags = fcntl (pss->rpipe[0], F_GETFL, 0);
switch (pss->child = fork ())
pss->child = sanei_thread_begin(reader_process, (void *) pss);
cancelRead = SANE_FALSE;
if (pss->child < 0)
{
case -1:
/* we'll have to read in blocking mode */
DBG (DL_MAJOR_ERROR,
"%s: can't fork; must read in blocking mode.\n",
"%s: Error while calling sanei_thread_begin; must read in blocking mode.\n",
me);
close (pss->rpipe[0]);
close (pss->rpipe[1]);
status = SANE_STATUS_UNSUPPORTED;
break;
case 0:
/* child; close read side, make stdout the write side of the pipe */
signal (SIGTERM, handler);
dup2 (pss->rpipe[1], STDOUT_FILENO);
close (pss->rpipe[0]);
status = create_base_source (pss, SCSI_SRC, &(pss->psrc));
if (status == SANE_STATUS_GOOD)
{
reader (pss);
}
else
{
DBG (DL_MAJOR_ERROR,
"Reader process: failed to create SCSISource.\n");
}
/* regular exit may cause a SIGPIPE */
DBG (DL_MINOR_INFO, "Reader process terminating.\n");
_exit (0);
break; /* not reached */
default:
}
if (sanei_thread_is_forked())
{
/* parent; close write side */
close (pss->rpipe[1]);
pss->nonblocking = SANE_TRUE;
break;
pss->rpipe[1] = -1;
}
pss->nonblocking = SANE_TRUE;
}
return status;
}
static SANE_Status send_gamma_table (SnapScan_Scanner *pss, u_char dtc, u_char dtcq)
{
static char me[] = "send_gamma_table";
@ -1623,8 +1653,8 @@ SANE_Status sane_read (SANE_Handle h,
{
if (pss->child > 0)
{
int status;
wait (&status); /* ensure no zombies */
sanei_thread_waitpid (pss->child, 0); /* ensure no zombies */
pss->child = -1;
}
release_unit (pss);
close_scanner (pss);
@ -1668,6 +1698,8 @@ void sane_cancel (SANE_Handle h)
{
char *me = "sane_snapscan_cancel";
SnapScan_Scanner *pss = (SnapScan_Scanner *) h;
struct SIGACTION act;
pid_t res;
DBG (DL_CALL_TRACE, "%s\n", me);
switch (pss->state)
@ -1681,21 +1713,39 @@ void sane_cancel (SANE_Handle h)
/* signal the reader, if any */
if (pss->child > 0)
{
int result;
if ((result = kill (pss->child, SIGTERM)) < 0)
DBG( DL_INFO, ">>>>>>>> killing reader_process <<<<<<<<\n" );
cancelRead = SANE_TRUE;
sigemptyset(&(act.sa_mask));
act.sa_flags = 0;
act.sa_handler = sigalarm_handler;
sigaction( SIGALRM, &act, 0 );
if (sanei_thread_is_forked())
{
DBG (DL_VERBOSE,
"%s: error: kill returns %ld\n",
me,
(long) result);
/* use SIGUSR1 to set cancelRead in child process */
sanei_thread_sendsig( pss->child, SIGUSR1 );
}
else
{
int status;
DBG (DL_VERBOSE, "%s: waiting on child reader.\n", me);
wait (&status);
DBG (DL_VERBOSE, "%s: child has terminated.\n", me);
/* give'em 10 seconds 'til done...*/
alarm(10);
res = sanei_thread_waitpid( pss->child, 0 );
alarm(0);
if( res != pss->child ) {
DBG( DL_MAJOR_ERROR,"sanei_thread_waitpid() failed !\n");
/* do it the hard way...*/
#ifdef USE_PTHREAD
sanei_thread_kill( pss->child );
#else
sanei_thread_sendsig( pss->child, SIGKILL );
#endif
}
pss->child = -1;
DBG( DL_INFO,"reader_process killed\n");
}
release_unit (pss);
close_scanner (pss);
@ -1768,8 +1818,8 @@ SANE_Status sane_get_select_fd (SANE_Handle h, SANE_Int * fd)
/*
* $Log$
* Revision 1.38 2004/04/02 20:19:24 oliver-guest
* Various bugfixes for gamma corretion (thanks to Robert Tsien)
* Revision 1.39 2004/04/08 21:53:10 oliver-guest
* Use sanei_thread in snapscan backend
*
* Revision 1.37 2003/11/27 23:11:32 oliver-guest
* Send gamma table twice for Epson Perfection 1670

Wyświetl plik

@ -340,6 +340,7 @@ struct snapscan_scanner
SANE_Byte chroma_offset[3]; /* chroma offsets */
SANE_Int chroma;
Source *psrc; /* data source */
Source *preadersrc; /* data source for reader thread */
SANE_Option_Descriptor options[NUM_OPTS]; /* the option descriptors */
Option_Value val[NUM_OPTS]; /* the options themselves... */
SANE_Int res; /* resolution */
@ -378,6 +379,9 @@ struct snapscan_scanner
/*
* $Log$
* Revision 1.28 2004/04/08 21:53:10 oliver-guest
* Use sanei_thread in snapscan backend
*
* Revision 1.27 2004/03/22 00:00:40 oliver-guest
* Added detection for Epson 660 by USB ID since new models use new ID strings
*