From 8f9f09cffb4ec84593971f553479bb4a017a460e Mon Sep 17 00:00:00 2001 From: Michael R Sweet Date: Tue, 1 Aug 2023 21:24:47 -0400 Subject: [PATCH] Add support for suspend/resume of jobs (Issue #266) --- CHANGES.md | 1 + pappl/job-filter.c | 6 ++++-- pappl/job-process.c | 50 +++++++++++++++++++++++++++++++++++++-------- pappl/job.c | 2 ++ 4 files changed, 49 insertions(+), 10 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index b5785b8f..60b0f955 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -9,6 +9,7 @@ Changes in v1.4.0 auto-adds local printers the first time a server is run (Issue #245) - Added new `papplDeviceRemoveScheme` and `papplDeviceRemoveTypes` APIs to disable unwanted device types (Issue #259) +- Added support for suspending and resuming jobs at copy boundaries (Issue #266) - Added support for server configuration files (Issue #279) - Fixed reporting of "xxx-k-octet-supported" attributes. - Fixed printing of 1/2/4-bit grayscale PNG images (Issue #267) diff --git a/pappl/job-filter.c b/pappl/job-filter.c index a57c9c31..6160f6be 100644 --- a/pappl/job-filter.c +++ b/pappl/job-filter.c @@ -78,7 +78,6 @@ papplJobFilterImage( bool smoothing) // I - `true` to smooth/interpolate the image, `false` for nearest-neighbor sampling { bool started = false;// Have we started the job? - int i; // Looping var pappl_pr_driver_data_t driver_data; // Printer driver data const unsigned char *dither; // Dither line int ileft, // Imageable left margin @@ -359,8 +358,11 @@ papplJobFilterImage( pixend = pixels + width * height * depth; // Print every copy... - for (i = 0; i < options->copies; i ++) + while (papplJobGetCopiesCompleted(job) < papplJobGetCopies(job)) { + if (papplJobGetState(job) != IPP_JSTATE_PROCESSING || papplJobIsCanceled(job)) + break; + if (!(driver_data.rstartpage_cb)(job, options, device, 1)) { papplLogJob(job, PAPPL_LOGLEVEL_ERROR, "Unable to start raster page."); diff --git a/pappl/job-process.c b/pappl/job-process.c index a7d2489d..b2875f78 100644 --- a/pappl/job-process.c +++ b/pappl/job-process.c @@ -853,9 +853,22 @@ void pappJobResume(pappl_job_t *job, // I - Job pappl_jreason_t remove) // I - Reasons to remove from "job-state-reasons" { - // TODO: Implement papplJobResume - (void)job; - (void)remove; + // Range check input... + if (!job) + return; + + // Update state... + _papplRWLockWrite(job); + + if (job->state == IPP_JSTATE_STOPPED) + { + job->state = IPP_JSTATE_PENDING; + job->state_reasons &= ~remove; + } + + _papplRWUnlock(job); + + _papplPrinterCheckJobs(job->printer); } @@ -867,9 +880,20 @@ void pappJobSuspend(pappl_job_t *job, // I - Job pappl_jreason_t add) // I - Reasons to add to "job-state-reasons" { - // TODO: Implement papplJobSuspend - (void)job; - (void)add; + // Range check input... + if (!job) + return; + + // Update state... + _papplRWLockWrite(job); + + if (job->state < IPP_JSTATE_STOPPED) + { + job->state = IPP_JSTATE_STOPPED; + job->state_reasons |= add; + } + + _papplRWUnlock(job); } @@ -992,6 +1016,16 @@ finish_job(pappl_job_t *job) // I - Job { pappl_printer_t *printer = job->printer; // Printer + static const char * const job_states[] = + { + "Pending", + "Held", + "Processing", + "Stopped", + "Canceled", + "Aborted", + "Completed" + }; _papplRWLockWrite(printer); @@ -1002,7 +1036,7 @@ finish_job(pappl_job_t *job) // I - Job else if (job->state == IPP_JSTATE_PROCESSING) job->state = IPP_JSTATE_COMPLETED; - papplLogJob(job, PAPPL_LOGLEVEL_INFO, "%s, job-impressions-completed=%d.", job->state == IPP_JSTATE_COMPLETED ? "Completed" : job->state == IPP_JSTATE_CANCELED ? "Canceled" : "Aborted", job->impcompleted); + papplLogJob(job, PAPPL_LOGLEVEL_INFO, "%s, job-impressions-completed=%d.", job_states[job->state - IPP_JSTATE_PENDING], job->impcompleted); if (job->state >= IPP_JSTATE_CANCELED) job->completed = time(NULL); @@ -1011,7 +1045,7 @@ finish_job(pappl_job_t *job) // I - Job printer->processing_job = NULL; - if (!printer->max_preserved_jobs || !job->retain_until) + if (job->state >= IPP_JSTATE_CANCELED && (!printer->max_preserved_jobs || !job->retain_until)) _papplJobRemoveFile(job); _papplSystemAddEventNoLock(job->system, job->printer, job, PAPPL_EVENT_JOB_COMPLETED, NULL); diff --git a/pappl/job.c b/pappl/job.c index 6552ee0f..a35469de 100644 --- a/pappl/job.c +++ b/pappl/job.c @@ -1003,7 +1003,9 @@ _papplPrinterCleanJobsNoLock( } } else + { break; + } } }