diff --git a/backend/agfafocus.c b/backend/agfafocus.c index 1255b35bf..0b59d2da4 100644 --- a/backend/agfafocus.c +++ b/backend/agfafocus.c @@ -954,7 +954,7 @@ do_cancel (AgfaFocus_Scanner * s) /* ensure child knows it's time to stop: */ sanei_thread_kill (s->reader_pid); sanei_thread_waitpid (s->reader_pid, &exit_status); - s->reader_pid = -1; + sanei_thread_invalidate(s->reader_pid); } if (s->fd >= 0) diff --git a/backend/artec_eplus48u.c b/backend/artec_eplus48u.c index f31bf5cc3..0e81b068b 100644 --- a/backend/artec_eplus48u.c +++ b/backend/artec_eplus48u.c @@ -3505,7 +3505,7 @@ do_cancel (Artec48U_Scanner * s, SANE_Bool closepipe) { XDBG ((1, "sanei_thread_waitpid() failed !\n")); } - s->reader_pid = -1; + sanei_thread_invalidate (s->reader_pid); XDBG ((1, "reader_process killed\n")); } if (SANE_TRUE == closepipe) @@ -4337,7 +4337,7 @@ sane_read (SANE_Handle handle, SANE_Byte * data, if (s->eof == SANE_TRUE) { sanei_thread_waitpid (s->reader_pid, 0); - s->reader_pid = -1; + sanei_thread_invalidate (s->reader_pid); artec48u_scanner_stop_scan (s); artec48u_carriage_home (s->dev); return close_pipe (s); diff --git a/backend/avision.c b/backend/avision.c index 3e9871546..faf71babe 100644 --- a/backend/avision.c +++ b/backend/avision.c @@ -6207,7 +6207,7 @@ do_eof (Avision_Scanner *s) /* join our processes - without a wait() you will produce zombies (defunct children) */ sanei_thread_waitpid (s->reader_pid, &exit_status); - s->reader_pid = -1; + sanei_thread_invalidate (s->reader_pid); DBG (3, "do_eof: returning %d\n", exit_status); return (SANE_Status)exit_status; @@ -6229,7 +6229,7 @@ do_cancel (Avision_Scanner* s) /* ensure child knows it's time to stop: */ sanei_thread_kill (s->reader_pid); sanei_thread_waitpid (s->reader_pid, &exit_status); - s->reader_pid = -1; + sanei_thread_invalidate (s->reader_pid); } return SANE_STATUS_CANCELLED; @@ -7844,7 +7844,7 @@ sane_open (SANE_String_Const devicename, SANE_Handle *handle) s->av_con.scsi_fd = -1; s->av_con.usb_dn = -1; - s->reader_pid = -1; + sanei_thread_initialize (s->reader_pid); s->read_fds = -1; s->hw = dev; diff --git a/backend/coolscan.c b/backend/coolscan.c index dd17d67de..4904afcd9 100644 --- a/backend/coolscan.c +++ b/backend/coolscan.c @@ -2037,7 +2037,7 @@ do_cancel (Coolscan_t * scanner) sanei_thread_kill (scanner->reader_pid); while (sanei_thread_waitpid(scanner->reader_pid, &exit_status) != scanner->reader_pid ); - scanner->reader_pid = -1; + sanei_thread_invalidate (scanner->reader_pid); } if (scanner->sfd >= 0) @@ -4155,7 +4155,7 @@ sane_cancel (SANE_Handle handle) { sanei_thread_kill ( s->reader_pid ); sanei_thread_waitpid( s->reader_pid, NULL ); - s->reader_pid = -1; + sanei_thread_invalidate (s->reader_pid); } swap_res (s); s->scanning = SANE_FALSE; diff --git a/backend/hp3500.c b/backend/hp3500.c index 7733796a2..97b96f18a 100644 --- a/backend/hp3500.c +++ b/backend/hp3500.c @@ -1134,7 +1134,7 @@ do_cancel (struct hp3500_data *scanner) sanei_thread_waitpid (scanner->reader_pid, &exit_status); } - scanner->reader_pid = -1; + sanei_thread_invalidate (scanner->reader_pid); } if (scanner->pipe_r >= 0) { diff --git a/backend/microtek2.c b/backend/microtek2.c index e650f4762..f7c63d62c 100644 --- a/backend/microtek2.c +++ b/backend/microtek2.c @@ -554,7 +554,7 @@ sane_open(SANE_String_Const name, SANE_Handle *handle) ms->cancelled = SANE_FALSE; ms->current_pass = 0; ms->sfd = -1; - ms->pid = -1; + sanei_thread_initialize(ms->pid); ms->fp = NULL; ms->gamma_table = NULL; ms->buf.src_buf = ms->buf.src_buffer[0] = ms->buf.src_buffer[1] = NULL; @@ -1353,7 +1353,7 @@ cleanup_scanner(Microtek2_Scanner *ms) if ( ms->sfd != -1 ) sanei_scsi_close(ms->sfd); ms->sfd = -1; - ms->pid = -1; + sanei_thread_invalidate(ms->pid); ms->fp = NULL; ms->current_pass = 0; ms->scanning = SANE_FALSE; diff --git a/backend/mustek.c b/backend/mustek.c index 230ad0c58..5435d5fd2 100644 --- a/backend/mustek.c +++ b/backend/mustek.c @@ -3008,7 +3008,7 @@ do_stop (Mustek_Scanner * s) status = exit_status; } - s->reader_pid = -1; + sanei_thread_invalidate (s->reader_pid); } if (s->fd >= 0) diff --git a/backend/pie.c b/backend/pie.c index 76cbb47b7..0e56a5af7 100644 --- a/backend/pie.c +++ b/backend/pie.c @@ -2901,7 +2901,7 @@ do_cancel (Pie_Scanner * scanner) DBG (DBG_sane_info, "killing reader_process\n"); sanei_thread_kill (scanner->reader_pid); sanei_thread_waitpid (scanner->reader_pid, 0); - scanner->reader_pid = -1; + sanei_thread_invalidate (scanner->reader_pid); DBG (DBG_sane_info, "reader_process killed\n"); } diff --git a/backend/pixma.c b/backend/pixma.c index 7527da461..9f6927604 100644 --- a/backend/pixma.c +++ b/backend/pixma.c @@ -1105,7 +1105,7 @@ terminate_reader_task (pixma_sane_t * ss, int *exit_code) /* pixma_cancel (ss->s); What is this for ? Makes end-of-scan buggy => removing */ } result = sanei_thread_waitpid (pid, &status); - ss->reader_taskid = -1; + sanei_thread_invalidate (ss->reader_taskid); if (ss->sp.source != PIXMA_SOURCE_ADF && ss->sp.source != PIXMA_SOURCE_ADFDUP) ss->idle = SANE_TRUE; @@ -1376,7 +1376,7 @@ sane_open (SANE_String_Const name, SANE_Handle * h) return SANE_STATUS_NO_MEM; ss->next = first_scanner; first_scanner = ss; - ss->reader_taskid = -1; + sanei_thread_initialize (ss->reader_taskid); ss->wpipe = -1; ss->rpipe = -1; ss->idle = SANE_TRUE; diff --git a/backend/plustek.c b/backend/plustek.c index 9b830e759..21e984564 100644 --- a/backend/plustek.c +++ b/backend/plustek.c @@ -604,7 +604,7 @@ do_cancel( Plustek_Scanner *scanner, SANE_Bool closepipe ) #endif } - scanner->reader_pid = -1; + sanei_thread_invalidate( scanner->reader_pid ); DBG( _DBG_PROC,"reader_process killed\n"); #ifndef HAVE_SETITIMER usb_StartLampTimer( scanner->hw ); @@ -2706,7 +2706,7 @@ sane_read( SANE_Handle handle, SANE_Byte *data, if( s->bytes_read == (unsigned long)(s->params.lines * s->params.bytes_per_line)) { sanei_thread_waitpid( s->reader_pid, 0 ); - s->reader_pid = -1; + sanei_thread_invalidate( s->reader_pid ); s->scanning = SANE_FALSE; drvclose( s->hw ); return close_pipe(s); @@ -2735,7 +2735,7 @@ sane_read( SANE_Handle handle, SANE_Byte *data, close_pipe(s); return s->exit_code; } - s->reader_pid = -1; + sanei_thread_invalidate( s->reader_pid ); s->scanning = SANE_FALSE; return close_pipe(s); } diff --git a/backend/plustek_pp.c b/backend/plustek_pp.c index adad34753..e1d4c02f7 100644 --- a/backend/plustek_pp.c +++ b/backend/plustek_pp.c @@ -506,7 +506,7 @@ static SANE_Status do_cancel( Plustek_Scanner *scanner, SANE_Bool closepipe ) #endif } - scanner->reader_pid = -1; + sanei_thread_invalidate( scanner->reader_pid ); DBG( _DBG_PROC,"reader_process killed\n"); } @@ -2084,7 +2084,7 @@ SANE_Status sane_read( SANE_Handle handle, SANE_Byte *data, if( s->bytes_read == (unsigned long)(s->params.lines * s->params.bytes_per_line)) { sanei_thread_waitpid( s->reader_pid, 0 ); - s->reader_pid = -1; + sanei_thread_invalidate( s->reader_pid ); drvclose( s->hw ); return close_pipe(s); } @@ -2112,7 +2112,7 @@ SANE_Status sane_read( SANE_Handle handle, SANE_Byte *data, close_pipe(s); return s->exit_code; } - s->reader_pid = -1; + sanei_thread_invalidate( s->reader_pid ); return close_pipe(s); } diff --git a/backend/snapscan.c b/backend/snapscan.c index c88537be6..d9054ebbb 100644 --- a/backend/snapscan.c +++ b/backend/snapscan.c @@ -1286,7 +1286,7 @@ static SANE_Status start_reader (SnapScan_Scanner *pss) pss->nonblocking = SANE_FALSE; pss->rpipe[0] = pss->rpipe[1] = -1; - pss->child = -1; + sanei_thread_initialize (pss->child); if (pipe (pss->rpipe) != -1) { @@ -1812,7 +1812,7 @@ SANE_Status sane_read (SANE_Handle h, if (sanei_thread_is_valid (pss->child)) { sanei_thread_waitpid (pss->child, 0); /* ensure no zombies */ - pss->child = -1; + sanei_thread_invalidate (pss->child); } release_unit (pss); close_scanner (pss); @@ -1904,7 +1904,7 @@ void sane_cancel (SANE_Handle h) sanei_thread_sendsig( pss->child, SIGKILL ); #endif } - pss->child = -1; + sanei_thread_invalidate( pss->child ); DBG( DL_INFO,"reader_process killed\n"); } release_unit (pss); diff --git a/backend/sp15c.c b/backend/sp15c.c index 203bfd9dc..20b2c8077 100644 --- a/backend/sp15c.c +++ b/backend/sp15c.c @@ -1769,7 +1769,7 @@ do_cancel (struct sp15c *scanner) sanei_thread_kill (scanner->reader_pid); DBG (50, "wait for scanner to stop\n"); sanei_thread_waitpid (scanner->reader_pid, &exit_status); - scanner->reader_pid = -1; + sanei_thread_invalidate (scanner->reader_pid); } if (scanner->sfd >= 0) diff --git a/backend/tamarack.c b/backend/tamarack.c index 3fda5a7c3..feb9ee1c6 100644 --- a/backend/tamarack.c +++ b/backend/tamarack.c @@ -479,7 +479,7 @@ do_cancel (Tamarack_Scanner *s) /* ensure child knows it's time to stop: */ sanei_thread_kill (s->reader_pid); sanei_thread_waitpid (s->reader_pid, &exit_status); - s->reader_pid = -1; + sanei_thread_invalidate (s->reader_pid); } if (s->fd >= 0) diff --git a/backend/test.c b/backend/test.c index 239dcfa12..3ead456dc 100644 --- a/backend/test.c +++ b/backend/test.c @@ -1375,7 +1375,7 @@ finish_pass (Test_Device * test_device) DBG (2, "finish_pass: reader process terminated with status: %s\n", sane_strstatus (status)); } - test_device->reader_pid = -1; + sanei_thread_invalidate (test_device->reader_pid); } /* this happens when running in thread context... */ if (test_device->reader_fds >= 0) @@ -1641,7 +1641,7 @@ sane_init (SANE_Int * __sane_unused__ version_code, SANE_Auth_Callback __sane_un test_device->eof = SANE_FALSE; test_device->scanning = SANE_FALSE; test_device->cancelled = SANE_FALSE; - test_device->reader_pid = -1; + sanei_thread_initialize (test_device->reader_pid); test_device->pipe = -1; DBG (4, "sane_init: new device: `%s' is a %s %s %s\n", test_device->sane.name, test_device->sane.vendor, diff --git a/backend/u12.c b/backend/u12.c index 4725f5b2d..78e917573 100644 --- a/backend/u12.c +++ b/backend/u12.c @@ -421,7 +421,7 @@ static SANE_Status do_cancel( U12_Scanner *scanner, SANE_Bool closepipe ) sanei_thread_sendsig( scanner->reader_pid, SIGKILL ); #endif } - scanner->reader_pid = -1; + sanei_thread_invalidate( scanner->reader_pid ); DBG( _DBG_PROC, "reader_process killed\n"); if( scanner->hw->fd >= 0 ) { @@ -1773,7 +1773,7 @@ SANE_Status sane_read( SANE_Handle handle, SANE_Byte *data, if( s->bytes_read == (unsigned long)(s->params.lines * s->params.bytes_per_line)) { sanei_thread_waitpid( s->reader_pid, 0 ); - s->reader_pid = -1; + sanei_thread_invalidate( s->reader_pid ); drvClose( s->hw ); return drvClosePipes(s); } @@ -1801,7 +1801,7 @@ SANE_Status sane_read( SANE_Handle handle, SANE_Byte *data, drvClosePipes(s); return s->exit_code; } - s->reader_pid = -1; + sanei_thread_invalidate( s->reader_pid ); return drvClosePipes(s); } diff --git a/backend/umax.c b/backend/umax.c index e9fd449d4..94f8aa4e6 100644 --- a/backend/umax.c +++ b/backend/umax.c @@ -4686,7 +4686,7 @@ static SANE_Status do_cancel(Umax_Scanner *scanner) DBG(DBG_sane_info, "do_cancel: reader_process terminated with status: %s\n", sane_strstatus(status)); } - scanner->reader_pid = -1; + sanei_thread_invalidate (scanner->reader_pid); if (scanner->device->pixelbuffer != NULL) /* pixelbuffer exists? */ { @@ -7285,9 +7285,9 @@ SANE_Status sane_start(SANE_Handle handle) DBG(DBG_sane_init,"sane_start\n"); - /* Initialize reader_pid to invalid so a subsequent error and following call - * to do_cancel() won't trip over it. */ - scanner->reader_pid = -1; + /* Invalidate reader_pid so a subsequent error and following call to + * do_cancel() won't trip over it. */ + sanei_thread_invalidate(scanner->reader_pid); mode = scanner->val[OPT_MODE].s; diff --git a/include/sane/sanei_thread.h b/include/sane/sanei_thread.h index f2323cedd..6e689642a 100644 --- a/include/sane/sanei_thread.h +++ b/include/sane/sanei_thread.h @@ -94,6 +94,38 @@ extern SANE_Bool sanei_thread_is_forked (void); */ extern SANE_Bool sanei_thread_is_valid (SANE_Pid pid); +/** Invalidate a SANE_Pid + * + * This "function" should be used to invalidate a SANE_Pid in a + * portable manner. + * + * @note + * When using pthreads, this only works for those implementations + * that opted to make pthread_t an arithmatic type. This is *not* + * required by the POSIX threads specification. The choice to do + * SANE_Pid invalidation by means of a macro rather than a proper + * function circumvents to need to pass a pointer. + * If we decide to implement SANE_Pid with a void* in the future, + * this can be changed into a proper function without the need to + * change existing code. + * + * For details on the pthread_t type, see in particular Issue 6 of + * http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_types.h.html + */ +#define sanei_thread_invalidate(pid) ((pid) = (SANE_Pid)(-1)) + +/** Initialize a SANE_Pid + * + * This "function" should be used to initialize a SANE_Pid in a + * portable manner. + * + * @note + * This is at present just an alias of sanei_thread_invalidate. + * It seemed misleading to use the latter when intent clearly has + * initialization written all over it, hence the alias. + */ +#define sanei_thread_initialize sanei_thread_invalidate + /** Spawn a new task. * * This function should be used to start a new task.