From: Michael R Sweet Date: Thu, 10 Jan 2019 22:07:29 +0000 (-0500) Subject: Fixed a performance regression with large PPDs (rdar://47040759) X-Git-Tag: v2.3b8~161 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ef3aba66ffdef16ab4bedf5d9ccb00de6c187c8b;p=thirdparty%2Fcups.git Fixed a performance regression with large PPDs (rdar://47040759) scheduler/printers.c: - create_media_col(): Drop media-source/media-type support. - load_ppd(): Stop enumerating all combinations of media size, source, and type. --- diff --git a/CHANGES.md b/CHANGES.md index 7242ebbdb5..005f71f279 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -6,6 +6,7 @@ Changes in CUPS v2.3b8 ---------------------- - Fixed a potential crash bug in cups-driverd (rdar://46625579) +- Fixed a performance regression with large PPDs (rdar://47040759) - Fixed a potential memory leak when reading at the end of a file (Issue #5473) - Localization updates (Issue #5461, Issues #5471) diff --git a/scheduler/printers.c b/scheduler/printers.c index ff381cdd5a..e4841c0713 100644 --- a/scheduler/printers.c +++ b/scheduler/printers.c @@ -1,7 +1,7 @@ /* * Printer routines for the CUPS scheduler. * - * Copyright © 2007-2018 by Apple Inc. + * Copyright © 2007-2019 by Apple Inc. * Copyright © 1997-2007 by Easy Software Products, all rights reserved. * * Licensed under Apache License v2.0. See the file "LICENSE" for more @@ -45,8 +45,7 @@ static int compare_printers(void *first, void *second, void *data); static void delete_printer_filters(cupsd_printer_t *p); static void dirty_printer(cupsd_printer_t *p); static void load_ppd(cupsd_printer_t *p); -static ipp_t *new_media_col(pwg_size_t *size, const char *source, - const char *type); +static ipp_t *new_media_col(pwg_size_t *size); static void write_xml_string(cups_file_t *fp, const char *s); @@ -3846,22 +3845,20 @@ dirty_printer(cupsd_printer_t *p) /* I - Printer */ static void load_ppd(cupsd_printer_t *p) /* I - Printer */ { - int i, j, k; /* Looping vars */ + int i, j; /* Looping vars */ char cache_name[1024]; /* Cache filename */ struct stat cache_info; /* Cache file info */ ppd_file_t *ppd; /* PPD file */ char ppd_name[1024]; /* PPD filename */ struct stat ppd_info; /* PPD file info */ char strings_name[1024]; /* Strings filename */ - int num_media; /* Number of media options */ + int num_media; /* Number of media values */ ppd_size_t *size; /* Current PPD size */ ppd_option_t *duplex, /* Duplex option */ *output_bin, /* OutputBin option */ *output_mode, /* OutputMode option */ *resolution; /* (Set|JCL|)Resolution option */ - ppd_choice_t *choice, /* Current PPD choice */ - *input_slot, /* Current input slot */ - *media_type; /* Current media type */ + ppd_choice_t *choice; /* Current PPD choice */ ppd_attr_t *ppd_attr; /* PPD attribute */ int xdpi, /* Horizontal resolution */ ydpi; /* Vertical resolution */ @@ -4131,12 +4128,7 @@ load_ppd(cupsd_printer_t *p) /* I - Printer */ { ipp_t *col; /* Collection value */ - input_slot = ppdFindMarkedChoice(ppd, "InputSlot"); - media_type = ppdFindMarkedChoice(ppd, "MediaType"); - col = new_media_col(pwgsize, - input_slot ? _ppdCacheGetSource(p->pc, input_slot->choice) : NULL, - media_type ? _ppdCacheGetType(p->pc, media_type->choice) : NULL); - + col = new_media_col(pwgsize); ippAddCollection(p->ppd_attrs, IPP_TAG_PRINTER, "media-col-default", col); ippDelete(col); } @@ -4331,89 +4323,19 @@ load_ppd(cupsd_printer_t *p) /* I - Printer */ * media-col-database */ - num_media = p->pc->num_sizes; - if (p->pc->num_sources) + if ((attr = ippAddCollections(p->ppd_attrs, IPP_TAG_PRINTER, "media-col-database", p->pc->num_sizes, NULL)) != NULL) { - if (p->pc->num_types > 0) - num_media += p->pc->num_sizes * p->pc->num_sources * - p->pc->num_types; - else - num_media += p->pc->num_sizes * p->pc->num_sources; - } - else if (p->pc->num_types) - num_media += p->pc->num_sizes * p->pc->num_types; + /* + * Add each page size without source or type... + */ - if ((attr = ippAddCollections(p->ppd_attrs, IPP_TAG_PRINTER, - "media-col-database", num_media, - NULL)) != NULL) - { - for (i = p->pc->num_sizes, pwgsize = p->pc->sizes, val = attr->values; - i > 0; - i --, pwgsize ++) + for (i = 0, pwgsize = p->pc->sizes; i < p->pc->num_sizes; i ++, pwgsize ++) { - /* - * Start by adding the page size without source or type... - */ - - ppdMarkOption(ppd, "PageSize", pwgsize->map.ppd); - - val->collection = new_media_col(pwgsize, NULL, NULL); - val ++; - - /* - * Then add the specific, supported combinations of size, source, and - * type... - */ + ipp_t *col = new_media_col(pwgsize); - if (p->pc->num_sources > 0) - { - for (j = p->pc->num_sources, pwgsource = p->pc->sources; - j > 0; - j --, pwgsource ++) - { - ppdMarkOption(ppd, "InputSlot", pwgsource->ppd); - - if (p->pc->num_types > 0) - { - for (k = p->pc->num_types, pwgtype = p->pc->types; - k > 0; - k --, pwgtype ++) - { - if (!ppdMarkOption(ppd, "MediaType", pwgtype->ppd)) - { - val->collection = new_media_col(pwgsize, pwgsource->pwg, - pwgtype->pwg); - val ++; - } - } - } - else if (!ppdConflicts(ppd)) - { - val->collection = new_media_col(pwgsize, pwgsource->pwg, NULL); - val ++; - } - } - } - else if (p->pc->num_types > 0) - { - for (j = p->pc->num_types, pwgtype = p->pc->types; - j > 0; - j --, pwgtype ++) - { - if (!ppdMarkOption(ppd, "MediaType", pwgtype->ppd)) - { - val->collection = new_media_col(pwgsize, NULL, pwgtype->pwg); - val ++; - } - } - } + ippSetCollection(p->ppd_attrs, &attr, i, col); + ippDelete(col); } - - /* - * Update the number of media-col-database values... - */ - - attr->num_values = val - attr->values; } } @@ -5127,9 +5049,7 @@ load_ppd(cupsd_printer_t *p) /* I - Printer */ */ static ipp_t * /* O - Collection value */ -new_media_col(pwg_size_t *size, /* I - media-size/margin values */ - const char *source, /* I - media-source value */ - const char *type) /* I - media-type value */ +new_media_col(pwg_size_t *size) /* I - media-size/margin values */ { ipp_t *media_col, /* Collection value */ *media_size; /* media-size value */ @@ -5138,29 +5058,15 @@ new_media_col(pwg_size_t *size, /* I - media-size/margin values */ media_col = ippNew(); media_size = ippNew(); - ippAddInteger(media_size, IPP_TAG_PRINTER, IPP_TAG_INTEGER, - "x-dimension", size->width); - ippAddInteger(media_size, IPP_TAG_PRINTER, IPP_TAG_INTEGER, - "y-dimension", size->length); + ippAddInteger(media_size, IPP_TAG_PRINTER, IPP_TAG_INTEGER, "x-dimension", size->width); + ippAddInteger(media_size, IPP_TAG_PRINTER, IPP_TAG_INTEGER, "y-dimension", size->length); ippAddCollection(media_col, IPP_TAG_PRINTER, "media-size", media_size); ippDelete(media_size); - ippAddInteger(media_col, IPP_TAG_PRINTER, IPP_TAG_INTEGER, - "media-bottom-margin", size->bottom); - ippAddInteger(media_col, IPP_TAG_PRINTER, IPP_TAG_INTEGER, - "media-left-margin", size->left); - ippAddInteger(media_col, IPP_TAG_PRINTER, IPP_TAG_INTEGER, - "media-right-margin", size->right); - ippAddInteger(media_col, IPP_TAG_PRINTER, IPP_TAG_INTEGER, - "media-top-margin", size->top); - - if (source) - ippAddString(media_col, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, "media-source", - NULL, source); - - if (type) - ippAddString(media_col, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, "media-type", - NULL, type); + ippAddInteger(media_col, IPP_TAG_PRINTER, IPP_TAG_INTEGER, "media-bottom-margin", size->bottom); + ippAddInteger(media_col, IPP_TAG_PRINTER, IPP_TAG_INTEGER, "media-left-margin", size->left); + ippAddInteger(media_col, IPP_TAG_PRINTER, IPP_TAG_INTEGER, "media-right-margin", size->right); + ippAddInteger(media_col, IPP_TAG_PRINTER, IPP_TAG_INTEGER, "media-top-margin", size->top); return (media_col); }