diff options
author | Rodrigo Arias <rodarima@gmail.com> | 2024-08-07 03:28:12 +0200 |
---|---|---|
committer | Rodrigo Arias Mallo <rodarima@gmail.com> | 2024-08-07 20:50:51 +0200 |
commit | b298347fdcaee0d44b7b0b39f9764fba4cf7415c (patch) | |
tree | 6584044bc2efe5e4c803fc97029dcd6636e1adc3 | |
parent | d156863f8b4a08d0487b22f2ab9ac2d5809539ed (diff) |
Stop the layouting loop after 1000 iterations
Prevents Dillo from hoarding the CPU due to an infinite loop in the
layouting. We also return the control to FLTK to update the screen and
process events each 100 iterations, to keep the window responsive.
It doesn't fix the root cause of the github-infinite-loop test, but it
does allow the rendering to finish with no differences with the
reference test.
-rw-r--r-- | ChangeLog | 2 | ||||
-rw-r--r-- | dw/layout.cc | 28 | ||||
-rw-r--r-- | dw/layout.hh | 2 | ||||
-rw-r--r-- | test/html/Makefile.am | 1 |
4 files changed, 26 insertions, 7 deletions
@@ -18,6 +18,8 @@ dillo-3.2.0 [Not released yet] - Add line number anchors in HTML source view. - Make Dillo strictly C99, C++11 and POSIX-2001 compliant, without depending on GNU extensions. + - Perform an emergency stop of the layout engine loop after 1000 iterations to + prevent a hang. Patches: Rodrigo Arias Mallo +- Add primitive support for SVG using the nanosvg.h library. Patches: dogma, Rodrigo Arias Mallo diff --git a/dw/layout.cc b/dw/layout.cc index 96653643..ee54e892 100644 --- a/dw/layout.cc +++ b/dw/layout.cc @@ -307,7 +307,7 @@ Layout::Layout (Platform *platform) layoutImgRenderer = NULL; resizeIdleCounter = queueResizeCounter = sizeAllocateCounter - = sizeRequestCounter = getExtremesCounter = 0; + = sizeRequestCounter = getExtremesCounter = resizeCounter = 0; } Layout::~Layout () @@ -443,6 +443,10 @@ void Layout::setWidget (Widget *widget) addWidget (widget); updateCursor (); + + /* Reset the resizeCounter when we change the top level widget, as we are + * changing to another page */ + resizeCounter = 0; } /** @@ -868,16 +872,30 @@ void Layout::resizeIdle () enterResizeIdle (); - //static int calls = 0; - // There are two commits, 2863:b749629fbfc9 and 4645:ab70f9ce4353, the second // reverting the former. Interrestingly, the second fixes a bug. However, it // should still examined what happens here, and what happens the other calls // to Layout::resizeIdle() which should be still in the queue. (See // Layout::queueResize(), where resizeIdleId is indeed checked.) - while (resizeIdleId != -1) { - _MSG("Layout::resizeIdle calls = %d\n", ++calls); + for (int i = 0; resizeIdleId != -1; i++) { + + /* Prevent infinite resize loop, if we reach this point it is very likely + * there is a bug in the layouting process */ + if (resizeCounter >= 1000) { + MSG_ERR("Emergency layout stop after %d iterations\n", resizeCounter); + MSG_ERR("Please file a bug report with the complete console output\n"); + resizeIdleId = -1; + break; + } + + /* Only allow 100 iterations before returning to redraw the screen. */ + if (i >= 100) { + MSG_WARN("Stopping layout loop after %d iterations\n", resizeCounter); + break; + } + + resizeCounter++; for (typed::Iterator <Widget> it = queueResizeList->iterator(); it.hasNext (); ) { diff --git a/dw/layout.hh b/dw/layout.hh index aada2069..e2b64901 100644 --- a/dw/layout.hh +++ b/dw/layout.hh @@ -246,7 +246,7 @@ private: ...Entered) defined here and in Widget. */ int resizeIdleCounter, queueResizeCounter, sizeAllocateCounter, - sizeRequestCounter, getExtremesCounter; + sizeRequestCounter, getExtremesCounter, resizeCounter; void enterResizeIdle () { resizeIdleCounter++; } void leaveResizeIdle () { resizeIdleCounter--; } diff --git a/test/html/Makefile.am b/test/html/Makefile.am index 3cac57c6..5b6643d6 100644 --- a/test/html/Makefile.am +++ b/test/html/Makefile.am @@ -43,7 +43,6 @@ TESTS = \ XFAIL_TESTS = \ render/div-100-percent-with-padding.html \ render/float-img-justify.html \ - render/github-infinite-loop.html \ render/img-aspect-ratio.html \ render/margin-auto.html \ render/max-width-html.html \ |