+/*
+ * 'cupsd_send_notification()' - Send a notification for the specified event.
+ */
+
+static void
+cupsd_send_notification(
+ cupsd_subscription_t *sub, /* I - Subscription object */
+ cupsd_event_t *event) /* I - Event to send */
+{
+ ipp_state_t state; /* IPP event state */
+
+
+ cupsdLogMessage(CUPSD_LOG_DEBUG2,
+ "cupsd_send_notification(sub=%p(%d), event=%p(%s))",
+ sub, sub->id, event, cupsdEventName(event->event));
+
+ /*
+ * Allocate the events array as needed...
+ */
+
+ if (!sub->events)
+ {
+ sub->events = cupsArrayNew3((cups_array_func_t)NULL, NULL,
+ (cups_ahash_func_t)NULL, 0,
+ (cups_acopy_func_t)NULL,
+ (cups_afree_func_t)cupsd_delete_event);
+
+ if (!sub->events)
+ {
+ cupsdLogMessage(CUPSD_LOG_CRIT,
+ "Unable to allocate memory for subscription #%d!",
+ sub->id);
+ return;
+ }
+ }
+
+ /*
+ * Purge an old event as needed...
+ */
+
+ if (cupsArrayCount(sub->events) >= MaxEvents)
+ {
+ /*
+ * Purge the oldest event in the cache...
+ */
+
+ cupsArrayRemove(sub->events, cupsArrayFirst(sub->events));
+
+ sub->first_event_id ++;
+ }
+
+ /*
+ * Add the event to the subscription. Since the events array is
+ * always MaxEvents in length, and since we will have already
+ * removed an event from the subscription cache if we hit the
+ * event cache limit, we don't need to check for overflow here...
+ */
+
+ cupsArrayAdd(sub->events, event);
+
+ /*
+ * Deliver the event...
+ */
+
+ if (sub->recipient)
+ {
+ for (;;)
+ {
+ if (sub->pipe < 0)
+ cupsd_start_notifier(sub);
+
+ cupsdLogMessage(CUPSD_LOG_DEBUG2, "sub->pipe=%d", sub->pipe);
+
+ if (sub->pipe < 0)
+ break;
+
+ event->attrs->state = IPP_IDLE;
+
+ while ((state = ippWriteFile(sub->pipe, event->attrs)) != IPP_DATA)
+ if (state == IPP_ERROR)
+ break;
+
+ if (state == IPP_ERROR)
+ {
+ if (errno == EPIPE)
+ {
+ /*
+ * Notifier died, try restarting it...
+ */
+
+ cupsdLogMessage(CUPSD_LOG_WARN,
+ "Notifier for subscription %d (%s) went away, "
+ "retrying!",
+ sub->id, sub->recipient);
+ cupsdEndProcess(sub->pid, 0);
+
+ close(sub->pipe);
+ sub->pipe = -1;
+ continue;
+ }
+
+ cupsdLogMessage(CUPSD_LOG_ERROR,
+ "Unable to send event for subscription %d (%s)!",
+ sub->id, sub->recipient);
+ }
+
+ /*
+ * If we get this far, break out of the loop...
+ */
+
+ break;
+ }
+ }
+
+ /*
+ * Bump the event sequence number...
+ */
+
+ sub->next_event_id ++;
+}
+
+