STR #679

GitHub FLTK Project   FLTK News RSS Feed  
  FLTK Apps      FLTK Library      Forums      Links     Login 
 Home  |  Articles & FAQs  |  Bugs & Features  |  Documentation  |  Download  |  Screenshots  ]

Return to Bugs & Features | Roadmap 1.1 ]

STR #679

Application:FLTK Library
Status:1 - Closed w/Resolution
Priority:2 - Low, e.g. a documentation error or undocumented side-effect
Scope:3 - Applies to all machines and operating systems
Subsystem:Core Library
Summary:hang if delete_widget on last widget
Created By:jedimasterthrash
Assigned To:mike
Fix Version:1.1.7 (SVN: v4388)
Update Notification:

Receive EMails Don't Receive EMails

Trouble Report Files:

Name/Time/Date Filename/Size top right image
#1 mike
05:45 Feb 14, 2005
bottom left image   bottom right image

Trouble Report Comments:

Name/Time/Date Text top right image
#1 jedimasterthrash
08:47 Dec 31, 2004
I modified my code to use the new "delete_widget" function instead of doing "delete this" in the Close method. Luckily I'd previously made sure my destructors and not the Close methods were actually taking care of the close-stuff, so this was quite painless, and the delete_widget process appears to work very well.

Except for this one scenario. If you do a "delete_widget" on the last widget, the process hangs.

The window itself does close, which makes me think that the deletion actually took place. However, the process remains active (i.e., it still shows up in the task manager process list, and appears to be stuck in the fl::wait() loop somewhere).

It appears that forcing some windowing message can can break the hang. To demonstrate this, run it in debug mode, so that it has that console window always running in the background. After you do the close of the main window, and the window disappears, you see that the console window is still there, indiciating that fl::run() hasn't finished yet. But if you do an ALT-TAB to switch windows, the process finally exits.

I can't see the hang when stepping-through in debug mode, because the act of switching windows thus causes it to un-hang itself. But in release mode, without the extra console window, or debugging, the process remains active indefinitely.

My guess is that a bunch of messages keep showing up in the wait loop, preventing it from exiting. But I don't know where these messages are coming from.

I'm running XP pro & VS6 all the latest SPs and updates. Haven't tried on unix yet.

#include <FL/Fl.H>
#include <FL/Fl_Double_Window.H>

class SpecialWindow : public Fl_Double_Window

        SpecialWindow(unsigned int w, unsigned int h) : Fl_Double_Window(w, h)
                callback(CloseCB, this);
        static void CloseCB(Fl_Widget *pW, void *pV)
                Fl::delete_widget((SpecialWindow *)pV);

int main(int argc, char **argv)
        SpecialWindow *pDW = new SpecialWindow(300, 300);
        return Fl::run();
#2 mike
07:55 Feb 05, 2005
I tested your program on Linux and was not able to reproduce the problem.

Can you add a Fl::check() call prior to calling Fl::delete_widget() to see if that resolves the problem?
#3 jedimasterthrash
20:39 Feb 12, 2005
Adding the check() doesn't change anything, but I was able to narrow down the problem quite a bit.

The problem appears to be with the Fl_win32.cxx fl_wait() function, which probably explains why you don't see the problem in Linux.

The Fl::run()does a loop with Fl::wait(FOREVER), where FOREVER is really just 0x1e20

The first thing that wait() does is do the do_widget_deletion(). Fl_X::first correctly gets null'd after this. Then it calls fl_wait(time_to_wait).

What I discovered is that the length of time the process "hangs" is directly proportional to the time_to_wait

For instance, If I call wait(0), the process finishes immediately (no hang). If I call wait(1), the process hangs for just 1 second before finishing. If I call wait(10), the process hangs for just 10 seconds, etc.

I used MSVC's SPY++ to log all the messages going to this window while it was hanging. To my suprise, there were no messages. This means that win32 GetMessage was not being called, so my previous guess as to the cause was incorrect. But I did find this:

Here's the code in win32::fl_wait():
  if (time_to_wait < 2147483.648) {
    // Perform the requested timeout...
    have_message = PeekMessage(&fl_msg, NULL, 0, 0, PM_REMOVE);
    if (!have_message) {
      int t = (int)(time_to_wait * 1000.0 + .5);
      if (t <= 0) { // too short to measure
        return 0;
      timerid = SetTimer(NULL, 0, t, NULL);
      have_message = GetMessage(&fl_msg, NULL, 0, 0);
      KillTimer(NULL, timerid);
I don't know too much of how the internals of FLTK work, but it looks like after the last message is received, this code will set a timer and wait until the timer fires before completing. This means that when Fl::run() calls wait(FOREVER), it will set a timer for 1e20 seconds and "hang" until that timer fires. Or at least, that's what the symptoms seem to indicate.

#4 mike
05:34 Feb 14, 2005
Hmm, looks like Windows isn't sending a message to the process when a window is deleted; perhaps we need to update the Fl_Window::hide() implementation to send a message on close?!?
#5 mike
05:45 Feb 14, 2005
Fixed in Subversion repository.
Try the attached patch and let me know if that doesn't fix things...
#6 jedimasterthrash
13:54 Feb 16, 2005
Hmm. The fix doesn't seem to change anything.  
#7 mike
13:43 Feb 24, 2005

Does the problem only happen when you delete the last visible window, or ???
#8 Natevw
14:47 Feb 24, 2005
If Fl::check() is added *after* the delete_widget() or hide() calls in JMT's example, the Fl::run() loop does exit properly after the last window is closed.
Otherwise, I am getting similar results: it acts as if Fl::run() doesn't realize the last window has closed.
#9 jedimasterthrash
16:55 Feb 24, 2005
Yep, it only hangs on the last window.  
#10 matt
02:18 Jun 01, 2005
Fixed in Subversion repository.  
bottom left image   bottom right image

Return to Bugs & Features ]


Comments are owned by the poster. All other content is copyright 1998-2021 by Bill Spitzak and others. This project is hosted by The FLTK Team. Please report site problems to ''.