Changeset 162073 in webkit


Ignore:
Timestamp:
Jan 15, 2014 9:37:36 AM (10 years ago)
Author:
Carlos Garcia Campos
Message:

[GTK] Web process sometimes crashes when printing in synchronous mode
https://bugs.webkit.org/show_bug.cgi?id=126979

Reviewed by Gustavo Noronha Silva.

Source/WebKit2:

When printing synchronously in GTK+ we need to make sure that we
have a list of Printers before starting the print operation. Getting
the list of printers is done synchronously by GTK+, but using a
nested main loop that might process IPC messages comming from the
UI process like EndPrinting. When the EndPrinting message is
received while the printer list is being populated, the print
operation is finished unexpectely and the web process crashes. The
PrinterListGtk class gets the list of printers in the constructor
so we just need to ensure there's an instance alive during the
synchronous print operation. In case of asynchronous printing the
printer list will be created during the print operation without
any risk, because the EndPrinting message is not sent until the
printing callback has been received in the UI process.

  • GNUmakefile.list.am: Add new files to compilation.
  • PlatformGTK.cmake: Ditto.
  • WebProcess/WebCoreSupport/WebChromeClient.cpp:

(WebKit::WebChromeClient::print): Ensure PrinterListGtk is created
before the synchronous printing and destroyed afterwards.

  • WebProcess/WebPage/gtk/PrinterListGtk.cpp: Added.

(WebKit::PrinterListGtk::shared): Return the singleton.
(WebKit::PrinterListGtk::enumeratePrintersFunction): Callback
called by gtk_enumerate_printers() when a new printer is found.
(WebKit::PrinterListGtk::PrinterListGtk): Call
gtk_enumerate_printers() in syhchronous mode.
(WebKit::PrinterListGtk::~PrinterListGtk):
(WebKit::PrinterListGtk::addPrinter): Add the printer to the list
and set the default printer if needed.
(WebKit::PrinterListGtk::findPrinter): Find the printer for the
given name.

  • WebProcess/WebPage/gtk/PrinterListGtk.h: Added.
  • WebProcess/WebPage/gtk/WebPrintOperationGtk.cpp: Use

PrinterListGtk class to find the printer instead of calling
gtk_enumerate_printers().

Tools:

  • Scripts/run-gtk-tests:

(TestRunner): Unskip
/webkit2/WebKitPrintOperation/close-after-print.

Location:
trunk
Files:
2 added
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebKit2/ChangeLog

    r162059 r162073  
     12014-01-15  Carlos Garcia Campos  <cgarcia@igalia.com>
     2
     3        [GTK] Web process sometimes crashes when printing in synchronous mode
     4        https://bugs.webkit.org/show_bug.cgi?id=126979
     5
     6        Reviewed by Gustavo Noronha Silva.
     7
     8        When printing synchronously in GTK+ we need to make sure that we
     9        have a list of Printers before starting the print operation. Getting
     10        the list of printers is done synchronously by GTK+, but using a
     11        nested main loop that might process IPC messages comming from the
     12        UI process like EndPrinting. When the EndPrinting message is
     13        received while the printer list is being populated, the print
     14        operation is finished unexpectely and the web process crashes. The
     15        PrinterListGtk class gets the list of printers in the constructor
     16        so we just need to ensure there's an instance alive during the
     17        synchronous print operation. In case of asynchronous printing the
     18        printer list will be created during the print operation without
     19        any risk, because the EndPrinting message is not sent until the
     20        printing callback has been received in the UI process.
     21
     22        * GNUmakefile.list.am: Add new files to compilation.
     23        * PlatformGTK.cmake: Ditto.
     24        * WebProcess/WebCoreSupport/WebChromeClient.cpp:
     25        (WebKit::WebChromeClient::print): Ensure PrinterListGtk is created
     26        before the synchronous printing and destroyed afterwards.
     27        * WebProcess/WebPage/gtk/PrinterListGtk.cpp: Added.
     28        (WebKit::PrinterListGtk::shared): Return the singleton.
     29        (WebKit::PrinterListGtk::enumeratePrintersFunction): Callback
     30        called by gtk_enumerate_printers() when a new printer is found.
     31        (WebKit::PrinterListGtk::PrinterListGtk): Call
     32        gtk_enumerate_printers() in syhchronous mode.
     33        (WebKit::PrinterListGtk::~PrinterListGtk):
     34        (WebKit::PrinterListGtk::addPrinter): Add the printer to the list
     35        and set the default printer if needed.
     36        (WebKit::PrinterListGtk::findPrinter): Find the printer for the
     37        given name.
     38        * WebProcess/WebPage/gtk/PrinterListGtk.h: Added.
     39        * WebProcess/WebPage/gtk/WebPrintOperationGtk.cpp: Use
     40        PrinterListGtk class to find the printer instead of calling
     41        gtk_enumerate_printers().
     42
    1432014-01-15  Tomas Popela  <tpopela@redhat.com>
    244
  • trunk/Source/WebKit2/GNUmakefile.list.am

    r162044 r162073  
    12441244        Source/WebKit2/WebProcess/WebPage/atk/WebPageAccessibilityObject.h \
    12451245        Source/WebKit2/WebProcess/WebPage/atk/WebPageAccessibilityObjectAtk.cpp \
     1246        Source/WebKit2/WebProcess/WebPage/gtk/PrinterListGtk.h \
     1247        Source/WebKit2/WebProcess/WebPage/gtk/PrinterListGtk.cpp \
    12461248        Source/WebKit2/WebProcess/WebPage/gtk/WebInspectorGtk.cpp \
    12471249        Source/WebKit2/WebProcess/WebPage/gtk/WebPageGtk.cpp \
  • trunk/Source/WebKit2/PlatformGTK.cmake

    r161919 r162073  
    284284
    285285    WebProcess/WebPage/gtk/LayerTreeHostGtk.cpp
     286    WebProcess/WebPage/gtk/PrinterListGtk.cpp
    286287    WebProcess/WebPage/gtk/WebInspectorGtk.cpp
    287288    WebProcess/WebPage/gtk/WebPageGtk.cpp
  • trunk/Source/WebKit2/WebProcess/WebCoreSupport/WebChromeClient.cpp

    r162007 r162073  
    7474#endif
    7575
     76#if PLATFORM(GTK)
     77#include "PrinterListGtk.h"
     78#endif
     79
    7680using namespace WebCore;
    7781using namespace HTMLNames;
     
    597601    ASSERT(webFrame);
    598602
     603#if PLATFORM(GTK) && defined(HAVE_GTK_UNIX_PRINTING)
     604    // When printing synchronously in GTK+ we need to make sure that we have a list of Printers before starting the print operation.
     605    // Getting the list of printers is done synchronously by GTK+, but using a nested main loop that might process IPC messages
     606    // comming from the UI process like EndPrinting. When the EndPriting message is received while the printer list is being populated,
     607    // the print operation is finished unexpectely and the web process crashes, see https://bugs.webkit.org/show_bug.cgi?id=126979.
     608    // The PrinterListGtk class gets the list of printers in the constructor so we just need to ensure there's an instance alive
     609    // during the synchronous print operation.
     610    RefPtr<PrinterListGtk> printerList = PrinterListGtk::shared();
     611#endif
     612
    599613    m_page->sendSync(Messages::WebPageProxy::PrintFrame(webFrame->frameID()), Messages::WebPageProxy::PrintFrame::Reply());
    600614}
  • trunk/Source/WebKit2/WebProcess/WebPage/gtk/WebPrintOperationGtk.cpp

    r159042 r162073  
    4141
    4242#ifdef HAVE_GTK_UNIX_PRINTING
     43#include "PrinterListGtk.h"
    4344#include <cairo-pdf.h>
    4445#include <cairo-ps.h>
     
    5758    }
    5859
    59     static gboolean enumeratePrintersFunction(GtkPrinter* printer, WebPrintOperationGtkUnix* printOperation)
    60     {
    61         const char* printerName = gtk_print_settings_get_printer(printOperation->printSettings());
    62         if ((printerName && strcmp(printerName, gtk_printer_get_name(printer)))
    63             || (!printerName && !gtk_printer_is_default(printer)))
    64             return FALSE;
     60    void startPrint(WebCore::PrintContext* printContext, uint64_t callbackID)
     61    {
     62        m_printContext = printContext;
     63        m_callbackID = callbackID;
     64
     65        RefPtr<PrinterListGtk> printerList = PrinterListGtk::shared();
     66        const char* printerName = gtk_print_settings_get_printer(m_printSettings.get());
     67        GtkPrinter* printer = printerName ? printerList->findPrinter(printerName) : printerList->defaultPrinter();
     68        if (!printer) {
     69            printDone(printerNotFoundError(m_printContext));
     70            return;
     71        }
    6572
    6673        static int jobNumber = 0;
    6774        const char* applicationName = g_get_application_name();
    6875        GOwnPtr<char>jobName(g_strdup_printf("%s job #%d", applicationName ? applicationName : "WebKit", ++jobNumber));
    69         printOperation->m_printJob = adoptGRef(gtk_print_job_new(jobName.get(), printer,
    70                                                                  printOperation->printSettings(),
    71                                                                  printOperation->pageSetup()));
    72         return TRUE;
    73     }
    74 
    75     static void enumeratePrintersFinished(WebPrintOperationGtkUnix* printOperation)
    76     {
    77         if (!printOperation->m_printJob) {
    78             printOperation->printDone(printerNotFoundError(printOperation->m_printContext));
     76        m_printJob = adoptGRef(gtk_print_job_new(jobName.get(), printer, m_printSettings.get(), m_pageSetup.get()));
     77
     78        GOwnPtr<GError> error;
     79        cairo_surface_t* surface = gtk_print_job_get_surface(m_printJob.get(), &error.outPtr());
     80        if (!surface) {
     81            printDone(printError(m_printContext, error->message));
    7982            return;
    8083        }
    8184
    82         GOwnPtr<GError> error;
    83         cairo_surface_t* surface = gtk_print_job_get_surface(printOperation->m_printJob.get(), &error.outPtr());
    84         if (!surface) {
    85             printOperation->printDone(printError(printOperation->m_printContext, error->message));
    86             return;
    87         }
    88 
    8985        int rangesCount;
    90         printOperation->m_pageRanges = gtk_print_job_get_page_ranges(printOperation->m_printJob.get(), &rangesCount);
    91         printOperation->m_pageRangesCount = rangesCount;
    92         printOperation->m_pagesToPrint = gtk_print_job_get_pages(printOperation->m_printJob.get());
    93         printOperation->m_needsRotation = gtk_print_job_get_rotate(printOperation->m_printJob.get());
     86        m_pageRanges = gtk_print_job_get_page_ranges(m_printJob.get(), &rangesCount);
     87        m_pageRangesCount = rangesCount;
     88        m_pagesToPrint = gtk_print_job_get_pages(m_printJob.get());
     89        m_needsRotation = gtk_print_job_get_rotate(m_printJob.get());
    9490
    9591        // Manual capabilities.
    96         printOperation->m_numberUp = gtk_print_job_get_n_up(printOperation->m_printJob.get());
    97         printOperation->m_numberUpLayout = gtk_print_job_get_n_up_layout(printOperation->m_printJob.get());
    98         printOperation->m_pageSet = gtk_print_job_get_page_set(printOperation->m_printJob.get());
    99         printOperation->m_reverse = gtk_print_job_get_reverse(printOperation->m_printJob.get());
    100         printOperation->m_copies = gtk_print_job_get_num_copies(printOperation->m_printJob.get());
    101         printOperation->m_collateCopies = gtk_print_job_get_collate(printOperation->m_printJob.get());
    102         printOperation->m_scale = gtk_print_job_get_scale(printOperation->m_printJob.get());
    103 
    104         printOperation->print(surface, 72, 72);
    105     }
    106 
    107     void startPrint(WebCore::PrintContext* printContext, uint64_t callbackID)
    108     {
    109         m_printContext = printContext;
    110         m_callbackID = callbackID;
    111         gtk_enumerate_printers(reinterpret_cast<GtkPrinterFunc>(enumeratePrintersFunction), this,
    112             reinterpret_cast<GDestroyNotify>(enumeratePrintersFinished), m_printMode == PrintInfo::PrintModeSync);
     92        m_numberUp = gtk_print_job_get_n_up(m_printJob.get());
     93        m_numberUpLayout = gtk_print_job_get_n_up_layout(m_printJob.get());
     94        m_pageSet = gtk_print_job_get_page_set(m_printJob.get());
     95        m_reverse = gtk_print_job_get_reverse(m_printJob.get());
     96        m_copies = gtk_print_job_get_num_copies(m_printJob.get());
     97        m_collateCopies = gtk_print_job_get_collate(m_printJob.get());
     98        m_scale = gtk_print_job_get_scale(m_printJob.get());
     99
     100        print(surface, 72, 72);
    113101    }
    114102
  • trunk/Tools/ChangeLog

    r162060 r162073  
     12014-01-15  Carlos Garcia Campos  <cgarcia@igalia.com>
     2
     3        [GTK] Web process sometimes crashes when printing in synchronous mode
     4        https://bugs.webkit.org/show_bug.cgi?id=126979
     5
     6        Reviewed by Gustavo Noronha Silva.
     7
     8        * Scripts/run-gtk-tests:
     9        (TestRunner): Unskip
     10        /webkit2/WebKitPrintOperation/close-after-print.
     11
    1122014-01-15  ChangSeok Oh  <changseok.oh@collabora.com>
    213
  • trunk/Tools/Scripts/run-gtk-tests

    r162056 r162073  
    7070        SkippedTest("WebKit2Gtk/TestContextMenu", SkippedTest.ENTIRE_SUITE, "Test times out after r150890", 117689),
    7171        SkippedTest("WebKit2Gtk/TestWebKitWebView", "/webkit2/WebKitWebView/snapshot", "Test fails", 120404),
    72         SkippedTest("WebKit2Gtk/TestPrinting", "/webkit2/WebKitPrintOperation/close-after-print", "Test times out", 126979),
    7372        SkippedTest("WebKit2/TestWebKit2", "WebKit2.MouseMoveAfterCrash", "Test is flaky", 85066),
    7473        SkippedTest("WebKit2/TestWebKit2", "WebKit2.NewFirstVisuallyNonEmptyLayoutForImages", "Test is flaky", 85066),
Note: See TracChangeset for help on using the changeset viewer.