ppisa commented on issue #18566:
URL: https://github.com/apache/nuttx/issues/18566#issuecomment-4702829646

   @Acfboy thanks for the report. As for the timer, I think I see the problem. 
The 
[select()](https://pubs.opengroup.org/onlinepubs/9799919799/functions/pselect.html)
 standard behavior is to wait for event indefinitely if the `timeout` argument 
is NULL. If it points to `{0,0}` structure, it should check for event and if 
none is pending then it return immediately. When there is long drawing time or 
other even more valid reason than it is possible that timer from the 
application level already expires and 
[MwGetNextTimeoutValue()](https://github.com/ghaerr/microwindows/blob/master/src/mwin/winuser.c#L1963)
 returns `0`. But the case that there is no timer on Mw level pending 
(`MwGetNextTimeoutValue()` return `-1`) is converted to the same `timeout = 0` 
case in `MwSelect()`. Then the check of timers from Microwidows engine/devices 
level are consulted by 
[GdGetNextTimeout()](https://github.com/ghaerr/microwindows/blob/master/src/engine/devtimer.c#L168)
 to check if there is some earlier tim
 er on this second timers list. But this function considers the case if the 
input `timeout` is `0` as the indication that there is no Mw level timer 
pending at all and if there is no other Gd timer pending, it returns `false` 
which is converted to wait forever. @ghaerr, what do you think about next 
change 
   ```diff
   diff --git a/src/mwin/winmain.c b/src/mwin/winmain.c
   index a27c142..e67c0ae 100644
   --- a/src/mwin/winmain.c
   +++ b/src/mwin/winmain.c
   @@ -281,23 +281,27 @@ MwSelect(BOOL canBlock)
        int poll = (!canBlock || dragwp);               /* just poll if can't 
block or window move in progress*/
        if (!poll)
        {
   -            if ((timeout = MwGetNextTimeoutValue()) == (MWTIMEOUT) -1L)     
/* get next mwin timer*/
   -                    timeout = 0;                                            
                                        /* no mwin timers*/
   +            timeout = MwGetNextTimeoutValue();      /* get next mwin timer 
or (MWTIMEOUT) -1L if none */
    #if MW_FEATURE_TIMERS
                /* get next timer or use passed timeout and convert to timeval 
struct*/
   -            if (!GdGetNextTimeout(&tout, timeout))          /* no VTSWITCH 
timer?*/
   +            if (timeout != 0) {
   +                    if (timeout == (MWTIMEOUT) -1L) /* no mwin timers */
   +                            timeout = 0;                    /* convert to 
GdGetNextTimeout forever */
   +                    if (!GdGetNextTimeout(&tout, timeout))          /* no 
VTSWITCH timer?*/
   +                            to = NULL;                                      
                        /* no timers, block*/
   +            }
    #else
   -            if (timeout)                                                    
        /* setup mwin poll timer*/
   +            if (timeout != (MWTIMEOUT) -1L)                 /* setup mwin 
poll timer*/
                {
                        /* convert wait timeout to timeval struct*/
                        tout.tv_sec = timeout / 1000;
                        tout.tv_usec = (timeout % 1000) * 1000;
                }
                else
   -#endif
                {
                        to = NULL;                                              
                /* no timers, block*/
                }
   +#endif
        }
    
        /* some drivers can't block in select as backend is poll based (SDL)*/
   ```
   
   The poll/no wait is preset in the `tout` by
   ```
   timeout = tout.tv_sec = tout.tv_usec = 0L;
   ```
   and this initial value is used by `poll = (!canBlock || dragwp)` so it 
should be safe and fixes behavior.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to