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 /dw | |
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.
Diffstat (limited to 'dw')
-rw-r--r-- | dw/layout.cc | 28 | ||||
-rw-r--r-- | dw/layout.hh | 2 |
2 files changed, 24 insertions, 6 deletions
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--; } |