Index: doc/help/ref-cupsd-conf.html.in
===================================================================
--- doc/help/ref-cupsd-conf.html.in (revision 7465)
+++ doc/help/ref-cupsd-conf.html.in (working copy)
@@ -1007,6 +1007,22 @@
HREF="#Limit">Limit
section.
+
+
+Examples
+
+
+DirtyCleanInterval 60
+DirtyCleanInterval 0
+
+
+Description
+
+The DirtyCleanInterval
directive specifies the number of
+seconds to wait before updating configuration and state files for printers,
+classes, subscriptions, and jobs. The default is 60 seconds.
+
+
Examples
Index: scheduler/subscriptions.c
===================================================================
--- scheduler/subscriptions.c (revision 7465)
+++ scheduler/subscriptions.c (working copy)
@@ -297,7 +297,7 @@
}
if (temp)
- cupsdSaveAllSubscriptions();
+ cupsdMarkDirty(CUPSD_DIRTY_SUBSCRIPTIONS);
else
cupsdLogMessage(CUPSD_LOG_DEBUG, "Discarding unused %s event...",
cupsdEventName(event));
@@ -463,7 +463,7 @@
*/
if (update)
- cupsdSaveAllSubscriptions();
+ cupsdMarkDirty(CUPSD_DIRTY_SUBSCRIPTIONS);
}
@@ -646,7 +646,7 @@
}
if (update)
- cupsdSaveAllSubscriptions();
+ cupsdMarkDirty(CUPSD_DIRTY_SUBSCRIPTIONS);
}
Index: scheduler/sysman.c
===================================================================
--- scheduler/sysman.c (revision 7465)
+++ scheduler/sysman.c (working copy)
@@ -3,7 +3,7 @@
*
* System management definitions for the Common UNIX Printing System (CUPS).
*
- * Copyright 2007 by Apple Inc.
+ * Copyright 2007-2008 by Apple Inc.
* Copyright 2006 by Easy Software Products.
*
* These coded instructions, statements, and computer programs are the
@@ -14,6 +14,9 @@
*
* Contents:
*
+ * cupsdCleanDirty() - Write dirty config and state files.
+ * cupsdMarkDirty() - Mark config or state files as needing a
+ * write.
* cupsdStartSystemMonitor() - Start monitoring for system change.
* cupsdStopSystemMonitor() - Stop monitoring for system change.
* cupsdUpdateSystemMonitor() - Update the current system state.
@@ -34,15 +37,91 @@
/*
- * Power management is a new addition to CUPS. Right now it is only
- * implemented on MacOS X, but essentially we use these three functions
- * to let the OS know when it is OK to put the system to sleep, typically
- * when we are not in the middle of printing a job.
+ * The system management functions cover disk and power management which
+ * are primarily used on portable computers.
*
- * Once put to sleep, we invalidate all remote printers since it is
- * common to wake up in a new location.
+ * Disk management involves delaying the write of certain configuration
+ * and state files to minimize the number of times the disk has to spin
+ * up.
+ *
+ * Power management support is currently only implemented on MacOS X, but
+ * essentially we use four functions to let the OS know when it is OK to
+ * put the system to idle sleep, typically when we are not in the middle of
+ * printing a job.
+ *
+ * Once put to sleep, we invalidate all remote printers since it is common
+ * to wake up in a new location/on a new wireless network.
*/
+
+/*
+ * 'cupsdCleanDirty()' - Write dirty config and state files.
+ */
+
+void
+cupsdCleanDirty(void)
+{
+ if (DirtyFiles & CUPSD_DIRTY_PRINTERS)
+ cupsdSaveAllPrinters();
+
+ if (DirtyFiles & CUPSD_DIRTY_CLASSES)
+ cupsdSaveAllClasses();
+
+ if (DirtyFiles & CUPSD_DIRTY_REMOTE)
+ cupsdSaveRemoteCache();
+
+ if (DirtyFiles & CUPSD_DIRTY_PRINTCAP)
+ cupsdWritePrintcap();
+
+ if (DirtyFiles & CUPSD_DIRTY_JOBS)
+ {
+ cupsd_job_t *job; /* Current job */
+
+ cupsdSaveAllJobs();
+
+ for (job = (cupsd_job_t *)cupsArrayFirst(Jobs);
+ job;
+ job = (cupsd_job_t *)cupsArrayNext(Jobs))
+ if (job->dirty)
+ cupsdSaveJob(job);
+ }
+
+ if (DirtyFiles & CUPSD_DIRTY_SUBSCRIPTIONS)
+ cupsdSaveAllSubscriptions();
+
+ DirtyFiles = CUPSD_DIRTY_NONE;
+ DirtyCleanTime = 0;
+}
+
+
+/*
+ * 'cupsdMarkDirty()' - Mark config or state files as needing a write.
+ */
+
+void
+cupsdMarkDirty(int what) /* I - What file(s) are dirty? */
+{
+ cupsdSetBusy(1);
+
+ DirtyFiles |= what;
+
+ if (!DirtyCleanTime)
+ DirtyCleanTime = time(NULL) + DirtyCleanInterval;
+}
+
+
+/*
+ * 'cupsdSetBusy()' - Let the system know when we are busy doing something.
+ */
+
+void
+cupsdSetBusy(int busy) /* I - 1 = busy, 0 = idle */
+{
+ /* TODO */
+ (void)busy;
+}
+
+
#ifdef __APPLE__
/*
* This is the Apple-specific system event code. It works by creating
Index: scheduler/sysman.h
===================================================================
--- scheduler/sysman.h (revision 7465)
+++ scheduler/sysman.h (working copy)
@@ -3,7 +3,7 @@
*
* System management definitions for the Common UNIX Printing System (CUPS).
*
- * Copyright 2007 by Apple Inc.
+ * Copyright 2007-2008 by Apple Inc.
* Copyright 2006 by Easy Software Products.
*
* These coded instructions, statements, and computer programs are the
@@ -14,9 +14,27 @@
*/
/*
+ * Constants...
+ */
+
+#define CUPSD_DIRTY_NONE 0 /* Nothing is dirty */
+#define CUPSD_DIRTY_PRINTERS 1 /* printers.conf is dirty */
+#define CUPSD_DIRTY_CLASSES 2 /* classes.conf is dirty */
+#define CUPSD_DIRTY_REMOTE 4 /* remote.cache is dirty */
+#define CUPSD_DIRTY_PRINTCAP 8 /* printcap is dirty */
+#define CUPSD_DIRTY_JOBS 16 /* jobs.cache or "c" file(s) are dirty */
+#define CUPSD_DIRTY_SUBSCRIPTIONS 32 /* subscriptions.conf is dirty */
+
+/*
* Globals...
*/
+VAR int DirtyFiles VALUE(CUPSD_DIRTY_NONE),
+ /* What files are dirty? */
+ DirtyCleanInterval VALUE(60);
+ /* How often do we write dirty files? */
+VAR time_t DirtyCleanTime VALUE(0);
+ /* When to clean dirty files next */
VAR int Sleeping VALUE(0);
/* Non-zero if machine is entering or *
* in a sleep state... */
@@ -30,6 +48,9 @@
* Prototypes...
*/
+extern void cupsdCleanDirty(void);
+extern void cupsdMarkDirty(int what);
+extern void cupsdSetBusy(int busy);
extern void cupsdStartSystemMonitor(void);
extern void cupsdStopSystemMonitor(void);
extern void cupsdUpdateSystemMonitor(void);
Index: scheduler/conf.c
===================================================================
--- scheduler/conf.c (revision 7465)
+++ scheduler/conf.c (working copy)
@@ -103,6 +103,7 @@
{ "DefaultLeaseDuration", &DefaultLeaseDuration, CUPSD_VARTYPE_INTEGER },
{ "DefaultPolicy", &DefaultPolicy, CUPSD_VARTYPE_STRING },
{ "DefaultShared", &DefaultShared, CUPSD_VARTYPE_BOOLEAN },
+ { "DirtyCleanInterval", &DirtyCleanInterval, CUPSD_VARTYPE_INTEGER },
{ "DocumentRoot", &DocumentRoot, CUPSD_VARTYPE_STRING },
{ "ErrorLog", &ErrorLog, CUPSD_VARTYPE_STRING },
{ "ErrorPolicy", &ErrorPolicy, CUPSD_VARTYPE_STRING },
@@ -516,6 +517,7 @@
#ifdef HAVE_SSL
DefaultEncryption = HTTP_ENCRYPT_REQUIRED;
#endif /* HAVE_SSL */
+ DirtyCleanInterval = 60;
JobRetryLimit = 5;
JobRetryInterval = 300;
FileDevice = FALSE;
@@ -1188,7 +1190,7 @@
cupsdLoadAllPrinters();
cupsdLoadAllClasses();
cupsdLoadRemoteCache();
- cupsdWritePrintcap();
+ cupsdMarkDirty(CUPSD_DIRTY_PRINTCAP);
cupsdCreateCommonData();
@@ -1219,7 +1221,7 @@
*/
cupsdUpdatePrinters();
- cupsdWritePrintcap();
+ cupsdMarkDirty(CUPSD_DIRTY_PRINTCAP);
cupsdLogMessage(CUPSD_LOG_INFO, "Partial reload complete.");
}
Index: scheduler/ipp.c
===================================================================
--- scheduler/ipp.c (revision 7465)
+++ scheduler/ipp.c (working copy)
@@ -858,14 +858,14 @@
if (dtype & CUPS_PRINTER_CLASS)
{
- cupsdSaveAllClasses();
+ cupsdMarkDirty(CUPSD_DIRTY_CLASSES);
cupsdLogMessage(CUPSD_LOG_INFO, "Class \"%s\" now accepting jobs (\"%s\").",
printer->name, get_username(con));
}
else
{
- cupsdSaveAllPrinters();
+ cupsdMarkDirty(CUPSD_DIRTY_PRINTERS);
cupsdLogMessage(CUPSD_LOG_INFO,
"Printer \"%s\" now accepting jobs (\"%s\").",
@@ -1162,7 +1162,7 @@
*/
cupsdSetPrinterAttrs(pclass);
- cupsdSaveAllClasses();
+ cupsdMarkDirty(CUPSD_DIRTY_CLASSES);
if (need_restart_job && pclass->job)
{
@@ -1183,7 +1183,7 @@
if (need_restart_job)
cupsdCheckJobs();
- cupsdWritePrintcap();
+ cupsdMarkDirty(CUPSD_DIRTY_PRINTCAP);
if (modify)
{
@@ -1265,6 +1265,9 @@
job->num_files ++;
+ job->dirty = 1;
+ cupsdMarkDirty(CUPSD_DIRTY_JOBS);
+
return (0);
}
@@ -1487,8 +1490,11 @@
job->dtype = printer->type & (CUPS_PRINTER_CLASS | CUPS_PRINTER_IMPLICIT |
CUPS_PRINTER_REMOTE);
job->attrs = con->request;
+ job->dirty = 1;
con->request = ippNewRequest(job->attrs->request.op.operation_id);
+ cupsdMarkDirty(CUPSD_DIRTY_JOBS);
+
add_job_uuid(con, job);
apply_printer_defaults(printer, job);
@@ -2071,7 +2077,7 @@
attr = attr->next;
}
- cupsdSaveAllSubscriptions();
+ cupsdMarkDirty(CUPSD_DIRTY_SUBSCRIPTIONS);
/*
* Remove all of the subscription attributes from the job request...
@@ -2720,7 +2726,7 @@
*/
cupsdSetPrinterAttrs(printer);
- cupsdSaveAllPrinters();
+ cupsdMarkDirty(CUPSD_DIRTY_PRINTERS);
if (need_restart_job && printer->job)
{
@@ -2741,7 +2747,7 @@
if (need_restart_job)
cupsdCheckJobs();
- cupsdWritePrintcap();
+ cupsdMarkDirty(CUPSD_DIRTY_PRINTCAP);
if (modify)
{
@@ -5453,8 +5459,6 @@
* Save and log the job...
*/
- cupsdSaveJob(job);
-
cupsdLogMessage(CUPSD_LOG_INFO, "[Job %d] Queued on \"%s\" by \"%s\".",
job->id, job->dest, job->username);
}
@@ -6001,8 +6005,7 @@
attr = attr->next;
}
- cupsdSaveAllSubscriptions();
-
+ cupsdMarkDirty(CUPSD_DIRTY_SUBSCRIPTIONS);
}
@@ -6091,7 +6094,7 @@
printer->name, get_username(con));
cupsdDeletePrinter(printer, 0);
- cupsdSaveAllClasses();
+ cupsdMarkDirty(CUPSD_DIRTY_CLASSES);
}
else
{
@@ -6099,10 +6102,10 @@
printer->name, get_username(con));
cupsdDeletePrinter(printer, 0);
- cupsdSaveAllPrinters();
+ cupsdMarkDirty(CUPSD_DIRTY_PRINTERS);
}
- cupsdWritePrintcap();
+ cupsdMarkDirty(CUPSD_DIRTY_PRINTCAP);
/*
* Return with no errors...
@@ -6597,6 +6600,11 @@
completed = 0;
list = Jobs;
}
+ else if (attr && !strcmp(attr->values[0].string.text, "printing"))
+ {
+ completed = 0;
+ list = PrintingJobs;
+ }
else
{
completed = 0;
@@ -6611,7 +6619,7 @@
IPP_TAG_INTEGER)) != NULL)
limit = attr->values[0].integer;
else
- limit = 1000000;
+ limit = 0;
if ((attr = ippFindAttribute(con->request, "first-job-id",
IPP_TAG_INTEGER)) != NULL)
@@ -6637,7 +6645,7 @@
*/
for (count = 0, job = (cupsd_job_t *)cupsArrayFirst(list);
- count < limit && job;
+ (limit <= 0 || count < limit) && job;
job = (cupsd_job_t *)cupsArrayNext(list))
{
/*
@@ -8271,8 +8279,6 @@
cupsdLogMessage(CUPSD_LOG_DEBUG, "[Job %d] hold_until = %d", job->id,
(int)job->hold_until);
- cupsdSaveJob(job);
-
/*
* Start the job if possible...
*/
@@ -8525,14 +8531,14 @@
if (dtype & CUPS_PRINTER_CLASS)
{
- cupsdSaveAllClasses();
+ cupsdMarkDirty(CUPSD_DIRTY_CLASSES);
cupsdLogMessage(CUPSD_LOG_INFO, "Class \"%s\" rejecting jobs (\"%s\").",
printer->name, get_username(con));
}
else
{
- cupsdSaveAllPrinters();
+ cupsdMarkDirty(CUPSD_DIRTY_PRINTERS);
cupsdLogMessage(CUPSD_LOG_INFO, "Printer \"%s\" rejecting jobs (\"%s\").",
printer->name, get_username(con));
@@ -8761,7 +8767,7 @@
sub->expire = sub->lease ? time(NULL) + sub->lease : 0;
- cupsdSaveAllSubscriptions();
+ cupsdMarkDirty(CUPSD_DIRTY_SUBSCRIPTIONS);
con->response->request.status.status_code = IPP_OK;
@@ -9485,7 +9491,8 @@
}
}
- cupsdSaveJob(job);
+ job->dirty = 1;
+ cupsdMarkDirty(CUPSD_DIRTY_JOBS);
/*
* Start the job if possible... Since cupsdCheckJobs() can cancel a
@@ -9509,7 +9516,9 @@
job->state->values[0].integer = IPP_JOB_HELD;
job->state_value = IPP_JOB_HELD;
job->hold_until = time(NULL) + 60;
- cupsdSaveJob(job);
+ job->dirty = 1;
+
+ cupsdMarkDirty(CUPSD_DIRTY_JOBS);
}
}
@@ -9676,11 +9685,9 @@
DefaultPrinter = printer;
- cupsdSaveAllPrinters();
- cupsdSaveAllClasses();
+ cupsdMarkDirty(CUPSD_DIRTY_PRINTERS | CUPSD_DIRTY_CLASSES |
+ CUPSD_DIRTY_REMOTE | CUPSD_DIRTY_PRINTCAP);
- cupsdWritePrintcap();
-
cupsdLogMessage(CUPSD_LOG_INFO,
"Default destination set to \"%s\" by \"%s\".",
printer->name, get_username(con));
@@ -10025,7 +10032,8 @@
* Save the job...
*/
- cupsdSaveJob(job);
+ job->dirty = 1;
+ cupsdMarkDirty(CUPSD_DIRTY_JOBS);
/*
* Send events as needed...
Index: scheduler/dirsvc.c
===================================================================
--- scheduler/dirsvc.c (revision 7465)
+++ scheduler/dirsvc.c (working copy)
@@ -98,7 +98,7 @@
ipp_pstate_t state, const char *location,
const char *info, const char *make_model,
int num_attrs, cups_option_t *attrs);
-static void process_implicit_classes(int *write_printcap);
+static void process_implicit_classes(void);
static void send_cups_browse(cupsd_printer_t *p);
#ifdef HAVE_LDAP
static void send_ldap_browse(cupsd_printer_t *p);
@@ -616,7 +616,7 @@
* Do auto-classing if needed...
*/
- process_implicit_classes(NULL);
+ process_implicit_classes();
}
@@ -801,7 +801,6 @@
cupsd_printer_t *p; /* Current printer */
time_t ut, /* Minimum update time */
to; /* Timeout time */
- int write_printcap; /* Write the printcap file? */
if (!Browsing || !BrowseLocalProtocols || !Printers)
@@ -899,7 +898,7 @@
* Loop through all of the printers and send local updates as needed...
*/
- for (p = (cupsd_printer_t *)cupsArrayFirst(Printers), write_printcap = 0;
+ for (p = (cupsd_printer_t *)cupsArrayFirst(Printers);
p;
p = (cupsd_printer_t *)cupsArrayNext(Printers))
{
@@ -924,13 +923,10 @@
cupsArraySave(Printers);
cupsdDeletePrinter(p, 1);
cupsArrayRestore(Printers);
- write_printcap = 1;
+ cupsdMarkDirty(CUPSD_DIRTY_PRINTCAP);
}
}
}
-
- if (write_printcap)
- cupsdWritePrintcap();
}
@@ -1749,8 +1745,7 @@
cups_option_t *attrs) /* I - Attributes */
{
int i; /* Looping var */
- int update, /* Update printer attributes? */
- write_printcap; /* Write the printcap file? */
+ int update; /* Update printer attributes? */
char finaluri[HTTP_MAX_URI], /* Final URI for printer */
name[IPP_MAX_NAME], /* Name of printer */
newname[IPP_MAX_NAME], /* New name of printer */
@@ -1837,12 +1832,11 @@
* See if we already have it listed in the Printers list, and add it if not...
*/
- type |= CUPS_PRINTER_REMOTE | CUPS_PRINTER_DISCOVERED;
- type &= ~CUPS_PRINTER_IMPLICIT;
- update = 0;
- write_printcap = 0;
- hptr = strchr(host, '.');
- sptr = strchr(ServerName, '.');
+ type |= CUPS_PRINTER_REMOTE | CUPS_PRINTER_DISCOVERED;
+ type &= ~CUPS_PRINTER_IMPLICIT;
+ update = 0;
+ hptr = strchr(host, '.');
+ sptr = strchr(ServerName, '.');
if (!ServerNameIsIP && sptr != NULL && hptr != NULL)
{
@@ -1965,8 +1959,9 @@
cupsdSetString(&p->device_uri, uri);
cupsdSetString(&p->hostname, host);
- update = 1;
- write_printcap = 1;
+ update = 1;
+
+ cupsdMarkDirty(CUPSD_DIRTY_PRINTCAP);
}
}
else
@@ -2072,8 +2067,9 @@
cupsdSetString(&p->uri, uri);
cupsdSetString(&p->device_uri, uri);
- write_printcap = 1;
- update = 1;
+ update = 1;
+
+ cupsdMarkDirty(CUPSD_DIRTY_PRINTCAP);
}
}
@@ -2132,8 +2128,9 @@
if (info && (!p->info || strcmp(p->info, info)))
{
cupsdSetString(&p->info, info);
- update = 1;
- write_printcap = 1;
+ update = 1;
+
+ cupsdMarkDirty(CUPSD_DIRTY_PRINTCAP);
}
if (!make_model || !make_model[0])
@@ -2198,7 +2195,7 @@
cupsdDeletePrinter(p, 1);
cupsdUpdateImplicitClasses();
- write_printcap = 1;
+ cupsdMarkDirty(CUPSD_DIRTY_PRINTCAP);
}
else if (update)
{
@@ -2223,7 +2220,7 @@
if (p->type & CUPS_PRINTER_DEFAULT)
{
DefaultPrinter = p;
- write_printcap = 1;
+ cupsdMarkDirty(CUPSD_DIRTY_PRINTCAP);
break;
}
}
@@ -2232,14 +2229,7 @@
* Do auto-classing if needed...
*/
- process_implicit_classes(&write_printcap);
-
- /*
- * Update the printcap file...
- */
-
- if (write_printcap)
- cupsdWritePrintcap();
+ process_implicit_classes();
}
@@ -2766,8 +2756,7 @@
*/
static void
-process_implicit_classes(
- int *write_printcap) /* O - Write printcap file? */
+process_implicit_classes(void)
{
int i; /* Looping var */
int update; /* Update printer attributes? */
@@ -2848,8 +2837,7 @@
update = 1;
- if (write_printcap)
- *write_printcap = 1;
+ cupsdMarkDirty(CUPSD_DIRTY_PRINTCAP);
cupsdLogMessage(CUPSD_LOG_DEBUG, "Added implicit class \"%s\"...",
name);
Index: scheduler/printers.c
===================================================================
--- scheduler/printers.c (revision 7465)
+++ scheduler/printers.c (working copy)
@@ -2793,9 +2793,9 @@
update)
{
if (p->type & CUPS_PRINTER_CLASS)
- cupsdSaveAllClasses();
+ cupsdMarkDirty(CUPSD_DIRTY_CLASSES);
else
- cupsdSaveAllPrinters();
+ cupsdMarkDirty(CUPSD_DIRTY_PRINTERS);
}
}
@@ -2841,8 +2841,9 @@
job->state->values[0].integer = IPP_JOB_PENDING;
job->state_value = IPP_JOB_PENDING;
+ job->dirty = 1;
- cupsdSaveJob(job);
+ cupsdMarkDirty(CUPSD_DIRTY_JOBS);
cupsdAddEvent(CUPSD_EVENT_JOB_STOPPED, p, job,
"Job stopped due to printer being paused");
Index: scheduler/server.c
===================================================================
--- scheduler/server.c (revision 7465)
+++ scheduler/server.c (working copy)
@@ -3,7 +3,7 @@
*
* Server start/stop routines for the Common UNIX Printing System (CUPS).
*
- * Copyright 2007 by Apple Inc.
+ * Copyright 2007-2008 by Apple Inc.
* Copyright 1997-2006 by Easy Software Products, all rights reserved.
*
* These coded instructions, statements, and computer programs are the
@@ -137,7 +137,6 @@
cupsdStopPolling();
cupsdStopBrowsing();
cupsdStopAllNotifiers();
- cupsdSaveRemoteCache();
cupsdDeleteAllCerts();
if (Clients)
@@ -203,6 +202,13 @@
cupsdDestroyProfile(DefaultProfile);
DefaultProfile = NULL;
+ /*
+ * Write out any dirty files...
+ */
+
+ if (DirtyFiles)
+ cupsdCleanDirty();
+
started = 0;
}
Index: scheduler/job.c
===================================================================
--- scheduler/job.c (revision 7466)
+++ scheduler/job.c (working copy)
@@ -211,10 +211,11 @@
cupsdExpireSubscriptions(NULL, job);
/*
- * Remove the job from the active list...
+ * Remove the job from the active and printing lists...
*/
cupsArrayRemove(ActiveJobs, job);
+ cupsArrayRemove(PrintingJobs, job);
/*
* Remove any authentication data...
@@ -277,7 +278,8 @@
* Save job state info...
*/
- cupsdSaveJob(job);
+ job->dirty = 1;
+ cupsdMarkDirty(CUPSD_DIRTY_JOBS);
}
else
{
@@ -301,6 +303,9 @@
free_job(job);
}
+
+ if (!cupsArrayCount(PrintingJobs) && !DirtyCleanTime)
+ cupsdSetBusy(0);
}
@@ -395,7 +400,8 @@
{
attr->value_tag = IPP_TAG_KEYWORD;
cupsdSetString(&(attr->values[0].string.text), "no-hold");
- cupsdSaveJob(job);
+ job->dirty = 1;
+ cupsdMarkDirty(CUPSD_DIRTY_JOBS);
}
}
@@ -462,6 +468,9 @@
else
ippAddString(job->attrs, IPP_TAG_JOB, IPP_TAG_URI,
"job-actual-printer-uri", NULL, printer->uri);
+
+ job->dirty = 1;
+ cupsdMarkDirty(CUPSD_DIRTY_JOBS);
}
if ((!(printer->type & CUPS_PRINTER_DISCOVERED) && /* Printer is local */
@@ -608,7 +617,8 @@
job->state_value = IPP_JOB_PENDING;
}
- cupsdSaveJob(job);
+ job->dirty = 1;
+ cupsdMarkDirty(CUPSD_DIRTY_JOBS);
/*
* If the job was queued to a class, try requeuing it... For
@@ -686,7 +696,8 @@
job->state->values[0].integer = IPP_JOB_HELD;
job->state_value = IPP_JOB_HELD;
- cupsdSaveJob(job);
+ job->dirty = 1;
+ cupsdMarkDirty(CUPSD_DIRTY_JOBS);
cupsdAddEvent(CUPSD_EVENT_JOB_STOPPED, printer, job,
"Job held due to backend errors; please consult "
@@ -703,7 +714,9 @@
job->state->values[0].integer = IPP_JOB_PENDING;
job->state_value = IPP_JOB_PENDING;
- cupsdSaveJob(job);
+ job->dirty = 1;
+ cupsdMarkDirty(CUPSD_DIRTY_JOBS);
+
cupsdSetPrinterState(printer, IPP_PRINTER_STOPPED, 1);
cupsdAddEvent(CUPSD_EVENT_JOB_STOPPED, printer, job,
@@ -730,7 +743,8 @@
job->state->values[0].integer = IPP_JOB_HELD;
job->state_value = IPP_JOB_HELD;
- cupsdSaveJob(job);
+ job->dirty = 1;
+ cupsdMarkDirty(CUPSD_DIRTY_JOBS);
cupsdAddEvent(CUPSD_EVENT_JOB_STOPPED, printer, job,
"Authentication is required for job %d.", job->id);
@@ -752,7 +766,8 @@
cupsdLogMessage(CUPSD_LOG_ERROR,
"[Job %d] Job stopped due to filter errors.", job->id);
cupsdStopJob(job, 1);
- cupsdSaveJob(job);
+ job->dirty = 1;
+ cupsdMarkDirty(CUPSD_DIRTY_JOBS);
cupsdAddEvent(CUPSD_EVENT_JOB_STOPPED, printer, job,
"Job stopped due to filter errors; please consult the "
"error_log file for details.");
@@ -812,6 +827,7 @@
{
cupsArrayRemove(Jobs, job);
cupsArrayRemove(ActiveJobs, job);
+ cupsArrayRemove(PrintingJobs, job);
free_job(job);
}
@@ -902,7 +918,8 @@
job->state_value = IPP_JOB_HELD;
job->current_file = 0;
- cupsdSaveJob(job);
+ job->dirty = 1;
+ cupsdMarkDirty(CUPSD_DIRTY_JOBS);
cupsdCheckJobs();
}
@@ -931,6 +948,9 @@
if (!ActiveJobs)
ActiveJobs = cupsArrayNew(compare_active_jobs, NULL);
+ if (!PrintingJobs)
+ PrintingJobs = cupsArrayNew(compare_jobs, NULL);
+
/*
* See whether the job.cache file is older than the RequestRoot directory...
*/
@@ -1317,7 +1337,8 @@
"Job #%d moved from %s to %s.", job->id, olddest,
p->name);
- cupsdSaveJob(job);
+ job->dirty = 1;
+ cupsdMarkDirty(CUPSD_DIRTY_JOBS);
}
@@ -1336,7 +1357,8 @@
job->state->values[0].integer = IPP_JOB_PENDING;
job->state_value = IPP_JOB_PENDING;
- cupsdSaveJob(job);
+ job->dirty = 1;
+ cupsdMarkDirty(CUPSD_DIRTY_JOBS);
cupsdCheckJobs();
}
}
@@ -1364,7 +1386,8 @@
job->state->values[0].integer = IPP_JOB_PENDING;
job->state_value = IPP_JOB_PENDING;
- cupsdSaveJob(job);
+ job->dirty = 1;
+ cupsdMarkDirty(CUPSD_DIRTY_JOBS);
if (old_state > IPP_JOB_STOPPED)
cupsArrayAdd(ActiveJobs, job);
@@ -1479,6 +1502,8 @@
"[Job %d] Unable to write job control file!", job->id);
cupsFileClose(fp);
+
+ job->dirty = 0;
}
@@ -1654,7 +1679,8 @@
cupsArrayAdd(ActiveJobs, job);
- cupsdSaveJob(job);
+ job->dirty = 1;
+ cupsdMarkDirty(CUPSD_DIRTY_JOBS);
}
@@ -1780,7 +1806,12 @@
job = (cupsd_job_t *)cupsArrayNext(Jobs))
if (job->attrs && job->state_value >= IPP_JOB_STOPPED &&
job->access_time < expire)
+ {
+ if (job->dirty)
+ cupsdSaveJob(job);
+
unload_job(job);
+ }
}
@@ -2426,7 +2457,8 @@
else
cupsdSetString(&attr->values[0].string.text, holdstr);
- cupsdSaveJob(job);
+ job->dirty = 1;
+ cupsdMarkDirty(CUPSD_DIRTY_JOBS);
}
@@ -2728,6 +2760,14 @@
if (job->current_file == 0)
{
/*
+ * Add to the printing list...
+ */
+
+ cupsArrayAdd(PrintingJobs, job);
+
+ cupsdSetBusy(1);
+
+ /*
* Set the processing time...
*/
@@ -3692,7 +3732,11 @@
{
cupsdSetAuthInfoRequired(job->printer, attr, NULL);
cupsdSetPrinterAttrs(job->printer);
- cupsdSaveAllPrinters();
+
+ if (job->printer->type & CUPS_PRINTER_DISCOVERED)
+ cupsdMarkDirty(CUPSD_DIRTY_REMOTE);
+ else
+ cupsdMarkDirty(CUPSD_DIRTY_PRINTERS);
}
if ((attr = cupsGetOption("printer-alert", num_attrs, attrs)) != NULL)
Index: scheduler/job.h
===================================================================
--- scheduler/job.h (revision 7465)
+++ scheduler/job.h (working copy)
@@ -20,7 +20,8 @@
typedef struct cupsd_job_s
{
int id, /* Job ID */
- priority; /* Job priority */
+ priority, /* Job priority */
+ dirty; /* Do we need to write the "c" file? */
ipp_jstate_t state_value; /* Cached job-state */
int pending_timeout;/* Non-zero if the job was created and waiting on files */
char *username; /* Printing user */
@@ -84,8 +85,10 @@
/* Automatically purge jobs */
VAR cups_array_t *Jobs VALUE(NULL),
/* List of current jobs */
- *ActiveJobs VALUE(NULL);
+ *ActiveJobs VALUE(NULL),
/* List of active jobs */
+ *PrintingJobs VALUE(NULL);
+ /* List of jobs that are printing */
VAR int NextJobId VALUE(1);
/* Next job ID to use */
VAR int JobRetryLimit VALUE(5),
Index: scheduler/main.c
===================================================================
--- scheduler/main.c (revision 7465)
+++ scheduler/main.c (working copy)
@@ -862,6 +862,18 @@
current_time = time(NULL);
+ /*
+ * Write dirty config/state files...
+ */
+
+ if (DirtyCleanTime && current_time >= DirtyCleanTime)
+ {
+ cupsdCleanDirty();
+
+ if (!cupsArrayCount(PrintingJobs))
+ cupsdSetBusy(0);
+ }
+
#ifndef __APPLE__
/*
* Update the network interfaces once a minute...
@@ -1910,6 +1922,16 @@
* Check for any active jobs...
*/
+ if (DirtyCleanTime && timeout > DirtyCleanTime)
+ {
+ timeout = DirtyCleanTime;
+ why = "write dirty config/state files";
+ }
+
+ /*
+ * Check for any active jobs...
+ */
+
if (timeout > (now + 10) && ActiveJobs)
{
for (job = (cupsd_job_t *)cupsArrayFirst(ActiveJobs);