Changes between Initial Version and Version 2 of Ticket #117


Ignore:
Timestamp:
07/04/09 08:26:51 (13 years ago)
Author:
andrew_b
Comment:

Legend:

Unmodified
Added
Removed
Modified
  • Ticket #117

    • Property Severity changed from to no branch
    • Property Milestone changed from to future releases
  • Ticket #117 – Description

    initial v2  
    1616Mon 01 Oct 2007 09:03:01 PM UTC, comment #9: 
    1717 
    18 when a resize is sent before mc is completely up, it doesn't get the geometry right, either - and yes, this happens about every time an xterm -e mc is restored by session management on my system. so the signal handler should be set up before the initial geometry is queried. 
     18when a resize is sent before mc is completely up, it doesn't get 
     19the geometry right, either - and yes, this happens about every time 
     20an xterm -e mc is restored by session management on my system. so 
     21the signal handler should be set up before the initial geometry is 
     22queried. 
    1923        Oswald Buddenhagen <ossi> 
    2024Mon 01 Oct 2007 03:21:44 PM UTC, comment #8: 
     
    2226If you run without mouse support (mc -d), mc doesn't detect resizes. 
    2327 
    24 You need to press a key for mc to resize itself to new window after window is maximized or resized (press up/down arrow, Ctrl-O, almost anything will work). 
     28You need to press a key for mc to resize itself to new window after 
     29window is maximized or resized (press up/down arrow, Ctrl-O, almost 
     30anything will work). 
    2531 
    2632Tested on 4.6.2-pre1. 
     
    3339Mon 06 Nov 2006 10:24:35 PM UTC, comment #6: 
    3440 
    35 As I understand your patch/hack, eliminating the timeouts on a window resize event significantly reduces the chance mc is still waiting inside the get_event() loop when a new resize event occurs. 
     41As I understand your patch/hack, eliminating the timeouts on a 
     42window resize event significantly reduces the chance mc is still 
     43waiting inside the get_event() loop when a new resize event occurs. 
    3644        Leonard den Ottolander <leonardjo> 
    3745Project Member 
    3846Mon 06 Nov 2006 12:01:58 PM UTC, comment #5: 
    3947 
    40 Please commit it if it seems to be okay for you (I've been using mc 4.6.1 with this patch for a month, and found no side effects, while it makes mc much better when resizing the terminal). But please don't yet close this bugreport to remind us that a proper fix is still needed. This patch only makes it much better, but still there's a small chance for the bug to appear. Until we have a proper fix, it's good to apply a temporary hack to heavily decrease the chance for the bug. 
     48Please commit it if it seems to be okay for you (I've been using mc 
     494.6.1 with this patch for a month, and found no side effects, while 
     50it makes mc much better when resizing the terminal). But please 
     51don't yet close this bugreport to remind us that a proper fix is 
     52still needed. This patch only makes it much better, but still 
     53there's a small chance for the bug to appear. Until we have 
     54a proper fix, it's good to apply a temporary hack to heavily 
     55decrease the chance for the bug. 
    4156        Egmont Koblinger <egmont> 
    4257Fri 03 Nov 2006 07:14:55 PM UTC, comment #4: 
     
    4762Tue 10 Oct 2006 04:22:16 PM UTC, comment #3: 
    4863 
    49 Added a resize.patch. This does not suffer from the new bug, though I don't understand what made a difference. 
     64Added a resize.patch. This does not suffer from the new bug, though 
     65I don't understand what made a difference. 
    5066 
    5167Still a rewrite to using pipes is needed to fill a minor race condition. 
     
    5369Tue 10 Oct 2006 03:40:51 PM UTC, comment #2: 
    5470 
    55 Oh, I just found the pselect() call which is supposed to solve this problem. However, its manpage says the Linux kernel supports this only since 2.6.16 which is a quite new piece. It says that glibc had an emulation which is vulnerable to the race condition I just mentioned and pselect was just introduced for. 
    56 The manpage also mentions and recommends the self-pipe trick which is more portable. 
     71Oh, I just found the pselect() call which is supposed to solve this 
     72problem. However, its manpage says the Linux kernel supports this 
     73only since 2.6.16 which is a quite new piece. It says that glibc 
     74had an emulation which is vulnerable to the race condition I just 
     75mentioned and pselect was just introduced for. 
     76The manpage also mentions and recommends the self-pipe trick which 
     77is more portable. 
    5778        Egmont Koblinger <egmont> 
    5879Tue 10 Oct 2006 03:27:46 PM UTC, comment #1: 
    5980 
    60 Normally mc stays in a select() call in key.c:get_event() which is called by dialog.c:frontend_run_dlg(). 
     81Normally mc stays in a select() call in key.c:get_event() which is 
     82called by dialog.c:frontend_run_dlg(). 
    6183 
    62 frontend_run_dlg() checks if the window size has changed and calls the proper functions in this case. Then it does a lot of other things, then calls get_event() which yet again does a lot of other things and finally arrives at that select(). 
     84frontend_run_dlg() checks if the window size has changed and calls 
     85the proper functions in this case. Then it does a lot of other 
     86things, then calls get_event() which yet again does a lot of other 
     87things and finally arrives at that select(). 
    6388 
    64 A subsequent window resize event (SIGWINCH) causes this select to return with -1 EINTR which is later handled correctly. 
     89A subsequent window resize event (SIGWINCH) causes this select to 
     90return with -1 EINTR which is later handled correctly. 
    6591 
    66 The problem is caused by the lot of code lines executed after checking for a window size change, but before entering the select call. If another window size change event occurs while executing these commands, it will not be handled until select() exits due to a keypress for example. 
     92The problem is caused by the lot of code lines executed after 
     93checking for a window size change, but before entering the select 
     94call. If another window size change event occurs while executing 
     95these commands, it will not be handled until select() exits due to 
     96a keypress for example. 
    6797 
    68 In key.c:get_event(), I placed the following line above the "flag = select (...)" statement: 
     98In key.c:get_event(), I placed the following line above the 
     99"flag = select (...)" statement: 
    69100if (winch_flag) return EV_NONE; 
    70 and then my resizing problems were gone. So now I check again for a resize event right before entering the select function. 
     101and then my resizing problems were gone. So now I check again for 
     102a resize event right before entering the select function. 
    71103 
    72 Though this modification seems to solve my bug, another bug appeared. Press F5 on ".." so an error dialog box appears. Resize the window now. mc enters an infinite loop consuming 100% CPU time and not reacting on any keypress. I don't yet know how to fix this new bug. Swapping the new statement and the enable_interrupt_key() call right before it doesn't help either. 
     104Though this modification seems to solve my bug, another bug 
     105appeared. Press F5 on ".." so an error dialog box appears. Resize 
     106the window now. mc enters an infinite loop consuming 100% CPU time 
     107and not reacting on any keypress. I don't yet know how to fix this 
     108new bug. Swapping the new statement and the enable_interrupt_key() 
     109call right before it doesn't help either. 
    73110 
    74 On the other hand, even if we didn't have any side effects, my patch still doesn't fix my original problem, only decreases the possibility for this to occur. Still there is a chance that SIGWINCH arrives right after checking for winch_flag but before entering the select() call. 
     111On the other hand, even if we didn't have any side effects, my 
     112patch still doesn't fix my original problem, only decreases the 
     113possibility for this to occur. Still there is a chance that 
     114SIGWINCH arrives right after checking for winch_flag but before 
     115entering the select() call. 
    75116 
    76 I'm just curious how to solve this problem 100% perfectly, without any race condition, without the slightest possibility to misbehave. Now I'm interested in the theory first, not in the implementation details in mc. Let's suppose a single application that only wants to do two things: process data arriving from several file descriptors, and always correctly display the terminal size from its main loop (i.e. not from a signal handler, since doing complex things from a signal handler is just plain wrong). My only idea is the following: create a pipe, the sigwinch handler writes a byte into it, and the select() call checks for its reading end in addition to the other file descriptors it is interested in. This way the select() call immediately exits if there's an unprocessed sigwinch event, no matter if it occured before or during this select call. And of course we have to set the close-on-exec flag on these fd's so that subprocesses don't inherit them. 
     117I'm just curious how to solve this problem 100% perfectly, without 
     118any race condition, without the slightest possibility to misbehave. 
     119Now I'm interested in the theory first, not in the implementation 
     120details in mc. Let's suppose a single application that only wants 
     121to do two things: process data arriving from several file 
     122descriptors, and always correctly display the terminal size from 
     123its main loop (i.e. not from a signal handler, since doing complex 
     124things from a signal handler is just plain wrong). My only idea is 
     125the following: create a pipe, the sigwinch handler writes a byte 
     126into it, and the select() call checks for its reading end in 
     127addition to the other file descriptors it is interested in. This 
     128way the select() call immediately exits if there's an unprocessed 
     129sigwinch event, no matter if it occured before or during this 
     130select call. And of course we have to set the close-on-exec flag on 
     131these fd's so that subprocesses don't inherit them. 
    77132        Egmont Koblinger <egmont> 
    78133Fri 22 Sep 2006 01:04:44 PM UTC, original submission: 
    79134 
    80 Modern desktop environments and window managers usually resize the windows in an opaque way: plenty of resize events are sent to the application while the edge of the window is being dragged. This gives users a much better feedback than the ancient method (only showing where the edges of the window will be, and resizing when the mouse button is released), though it definitely requires much more cpu resources. 
     135Modern desktop environments and window managers usually resize the 
     136windows in an opaque way: plenty of resize events are sent to the 
     137application while the edge of the window is being dragged. This 
     138gives users a much better feedback than the ancient method (only 
     139showing where the edges of the window will be, and resizing when 
     140the mouse button is released), though it definitely requires much 
     141more cpu resources. 
    81142 
    82 Unfortunately mc is unable to properly handle when the terminal is resized opaquely. It receives tons of resize events (sigwinch), most likely ignores the new ones while processing an older one. Quite often when I finish resizing my window, mc draws its panels with a different size. Hence if I enlarge my terminal, I might get black columns/rows on its right/bottom part. If I shrink the window, the whole screen can be garbled. 
     143Unfortunately mc is unable to properly handle when the terminal is 
     144resized opaquely. It receives tons of resize events (sigwinch), 
     145most likely ignores the new ones while processing an older one. 
     146Quite often when I finish resizing my window, mc draws its panels 
     147with a different size. Hence if I enlarge my terminal, I might get 
     148black columns/rows on its right/bottom part. If I shrink the 
     149window, the whole screen can be garbled. 
    83150 
    84 Then when I press one key, or click somewhere in the terminal with the mouse, suddenly mc's screen is repainted with the right size, and everything goes on perfectly. 
     151Then when I press one key, or click somewhere in the terminal with 
     152the mouse, suddenly mc's screen is repainted with the right size, 
     153and everything goes on perfectly. 
    85154 
    86 It would be nice to eliminate these race conditions and make mc resize correctly to the final terminal size, no matter how many resize events were sent in a very short time.  
     155It would be nice to eliminate these race conditions and make mc 
     156resize correctly to the final terminal size, no matter how many 
     157resize events were sent in a very short time.  
    87158}}}