/*
* Main loop for the CUPS scheduler.
*
- * Copyright 2007-2017 by Apple Inc.
+ * Copyright 2007-2018 by Apple Inc.
* Copyright 1997-2007 by Easy Software Products, all rights reserved.
*
- * These coded instructions, statements, and computer programs are the
- * property of Apple Inc. and are protected by Federal copyright
- * law. Distribution and use rights are outlined in the file "LICENSE.txt"
- * "LICENSE" which should have been included with this file. If this
- * file is missing or damaged, see the license at "http://www.cups.org/".
+ * Licensed under Apache License v2.0. See the file "LICENSE" for more
+ * information.
*/
/*
#define _MAIN_C_
#include "cupsd.h"
#include <sys/resource.h>
+#ifdef __APPLE__
+# include <xpc/xpc.h>
+# include <pthread/qos.h>
+#endif /* __APPLE__ */
#ifdef HAVE_ASL_H
# include <asl.h>
#elif defined(HAVE_SYSTEMD_SD_JOURNAL_H)
static long select_timeout(int fds);
static void service_checkin(void);
static void service_checkout(int shutdown);
-static void usage(int status) __attribute__((noreturn));
+static void usage(int status) _CUPS_NORETURN;
/*
fg = 0;
-#ifdef HAVE_LAUNCHD
- if (getenv("CUPSD_LAUNCHD"))
- {
- OnDemand = 1;
- fg = 1;
- close_all = 0;
- disconnect = 0;
- }
-#endif /* HAVE_LAUNCHD */
-
for (i = 1; i < argc; i ++)
if (argv[i][0] == '-')
for (opt = argv[i] + 1; *opt != '\0'; opt ++)
exit(errno);
}
+ /*
+ * Let the system know we are busy while we bring up cupsd...
+ */
+
+ cupsdSetBusyState(1);
+
/*
* Set the timezone info...
*/
else
cupsdAddEvent(CUPSD_EVENT_SERVER_STARTED, NULL, NULL, "Scheduler started in background.");
+ cupsdSetBusyState(0);
+
/*
* Start any pending print jobs...
*/
current_time = time(NULL);
event_time = current_time;
expire_time = current_time;
- local_timeout = current_time + 60;
+ local_timeout = 0;
fds = 1;
report_time = 0;
senddoc_time = current_time;
#ifdef HAVE_ONDEMAND
/*
- * If no other work is scheduled and we're being controlled by
- * launchd then timeout after 'LaunchdTimeout' seconds of
+ * If no other work is scheduled and we're being controlled by launchd,
+ * systemd, etc. then timeout after 'IdleExitTimeout' seconds of
* inactivity...
*/
if (timeout == 86400 && OnDemand && IdleExitTimeout &&
- !cupsArrayCount(ActiveJobs) &&
# ifdef HAVE_SYSTEMD
!WebInterface &&
# endif /* HAVE_SYSTEMD */
- (!Browsing || !BrowseLocalProtocols || !cupsArrayCount(Printers)))
+ !cupsArrayCount(ActiveJobs))
{
- timeout = IdleExitTimeout;
- service_idle_exit = 1;
+ cupsd_printer_t *p = NULL; /* Current printer */
+
+ if (Browsing && BrowseLocalProtocols)
+ {
+ for (p = (cupsd_printer_t *)cupsArrayFirst(Printers); p; p = (cupsd_printer_t *)cupsArrayNext(Printers))
+ if (p->shared)
+ break;
+ }
+
+ if (!p)
+ {
+ timeout = IdleExitTimeout;
+ service_idle_exit = 1;
+ }
}
else
service_idle_exit = 0;
* Write dirty config/state files...
*/
- if (DirtyCleanTime && current_time >= DirtyCleanTime && cupsArrayCount(Clients) == 0)
+ if (DirtyCleanTime && current_time >= DirtyCleanTime)
cupsdCleanDirty();
#ifdef __APPLE__
*/
if (current_time >= local_timeout)
+ {
cupsdDeleteTemporaryPrinters(0);
+ local_timeout = 0;
+ }
#ifndef HAVE_AUTHORIZATION_H
/*
(!job->filters[i] && WIFEXITED(old_status)))
{ /* Backend and filter didn't crash */
if (job->filters[i])
+ {
job->status = status; /* Filter failed */
+ }
else
+ {
job->status = -status; /* Backend failed */
+
+ if (job->current_file < job->num_files)
+ cupsdSetJobState(job, IPP_JOB_ABORTED, CUPSD_JOB_FORCE, "Canceling multi-file job due to backend failure.");
+ }
}
if (job->state_value == IPP_JOB_PROCESSING &&
for (printer = (cupsd_printer_t *)cupsArrayFirst(Printers); printer; printer = (cupsd_printer_t *)cupsArrayNext(Printers))
{
- if (printer->temporary && !printer->job && local_timeout > (printer->state_time + 60))
+ if (printer->temporary && !printer->job && (!local_timeout || local_timeout > (printer->state_time + 60)))
local_timeout = printer->state_time + 60;
}
- if (timeout > local_timeout)
+ if (timeout > local_timeout && local_timeout)
{
timeout = local_timeout;
why = "delete stale local printers";
count; /* Number of listeners */
int *ld_sockets; /* Listener sockets */
+# ifdef __APPLE__
+ /*
+ * Force "user initiated" priority for the main thread...
+ */
+
+ pthread_set_qos_class_self_np(QOS_CLASS_USER_INITIATED, 0);
+# endif /* __APPLE__ */
+
/*
* Check-in with launchd...
*/
service_add_listener(ld_sockets[i], (int)i);
free(ld_sockets);
+
+# ifdef __APPLE__
+ xpc_transaction_begin();
+# endif /* __APPLE__ */
}
#elif defined(HAVE_SYSTEMD)
else
cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to create KeepAlive/PID file \"%s\": %s", pidfile, strerror(errno));
}
+
+# ifdef __APPLE__
+ if (OnDemand && shutdown)
+ xpc_transaction_end();
+# endif /* __APPLE__ */
}