wmail: replaced SIGALRM handler with DA timer call-back.
The application was doing a lot of work in a signal-handler. This was not re-entrant and could interact badly with X. Since the DA event-loop supports a timer call-back use that instead.
This commit is contained in:
		
							parent
							
								
									e4760eb90f
								
							
						
					
					
						commit
						5eef361597
					
				
					 1 changed files with 26 additions and 31 deletions
				
			
		| 
						 | 
					@ -100,6 +100,7 @@ typedef enum {
 | 
				
			||||||
///////////////////////////////////////////////////////////////////////////////
 | 
					///////////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
// data
 | 
					// data
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static unsigned long lastTimeOut;
 | 
				
			||||||
mail_state_t state = STATE_NOMAIL;
 | 
					mail_state_t state = STATE_NOMAIL;
 | 
				
			||||||
int numMails = 0;
 | 
					int numMails = 0;
 | 
				
			||||||
bool namesChanged = false;
 | 
					bool namesChanged = false;
 | 
				
			||||||
| 
						 | 
					@ -160,7 +161,8 @@ static DAProgramOption options[] = {
 | 
				
			||||||
// prototypes
 | 
					// prototypes
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void PreparePixmaps( bool freeThemFirst );
 | 
					void PreparePixmaps( bool freeThemFirst );
 | 
				
			||||||
void TimerHandler( int dummy );
 | 
					void TimedOut( void );
 | 
				
			||||||
 | 
					void CheckTimeOut( bool force );
 | 
				
			||||||
void CheckMBox( void );
 | 
					void CheckMBox( void );
 | 
				
			||||||
void CheckMaildir( void );
 | 
					void CheckMaildir( void );
 | 
				
			||||||
int TraverseDirectory( const char *name, bool isNewMail );
 | 
					int TraverseDirectory( const char *name, bool isNewMail );
 | 
				
			||||||
| 
						 | 
					@ -195,28 +197,14 @@ bool HasTickerWork( void );
 | 
				
			||||||
// implementation
 | 
					// implementation
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void SetTimer( void )
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    struct itimerval timerVal;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    timerVal.it_interval.tv_sec = 0;
 | 
					 | 
				
			||||||
    timerVal.it_interval.tv_usec = 1000000/config.fps;
 | 
					 | 
				
			||||||
    timerVal.it_value.tv_sec = 0;
 | 
					 | 
				
			||||||
    timerVal.it_value.tv_usec = 1000000/config.fps;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    setitimer( ITIMER_REAL, &timerVal, NULL );
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int main( int argc, char **argv )
 | 
					int main( int argc, char **argv )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    char *usersHome;
 | 
					    char *usersHome;
 | 
				
			||||||
    struct sigaction sa;
 | 
					 | 
				
			||||||
    int ret;
 | 
					 | 
				
			||||||
    struct stat fileStat;
 | 
					    struct stat fileStat;
 | 
				
			||||||
    XTextProperty windowName;
 | 
					    XTextProperty windowName;
 | 
				
			||||||
    char *name = argv[0];
 | 
					    char *name = argv[0];
 | 
				
			||||||
    DACallbacks callbacks = { NULL, &ButtonPressed, &ButtonReleased,
 | 
					    DACallbacks callbacks = { NULL, &ButtonPressed, &ButtonReleased,
 | 
				
			||||||
			      NULL, NULL, NULL, NULL };
 | 
								      NULL, NULL, NULL, &TimedOut };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // read the config file and overide the default-settings
 | 
					    // read the config file and overide the default-settings
 | 
				
			||||||
    ReadConfigFile( false );
 | 
					    ReadConfigFile( false );
 | 
				
			||||||
| 
						 | 
					@ -303,24 +291,13 @@ int main( int argc, char **argv )
 | 
				
			||||||
    PreparePixmaps( false );
 | 
					    PreparePixmaps( false );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    DASetCallbacks( &callbacks );
 | 
					    DASetCallbacks( &callbacks );
 | 
				
			||||||
    DASetTimeout( -1 );
 | 
					    DASetTimeout (1000 / config.fps);
 | 
				
			||||||
 | 
					 | 
				
			||||||
    sa.sa_handler = TimerHandler;
 | 
					 | 
				
			||||||
    sigemptyset( &sa.sa_mask );
 | 
					 | 
				
			||||||
    sa.sa_flags = SA_RESTART;
 | 
					 | 
				
			||||||
    ret = sigaction( SIGALRM, &sa, 0 );
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if( ret ) {
 | 
					 | 
				
			||||||
	perror( "wmail error: sigaction" );
 | 
					 | 
				
			||||||
	exit( 1 );
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    XStringListToTextProperty( &name, 1, &windowName );
 | 
					    XStringListToTextProperty( &name, 1, &windowName );
 | 
				
			||||||
    XSetWMName( DADisplay, DAWindow, &windowName );
 | 
					    XSetWMName( DADisplay, DAWindow, &windowName );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    UpdatePixmap( false );
 | 
					    UpdatePixmap( false );
 | 
				
			||||||
    DAShow();
 | 
					    DAShow();
 | 
				
			||||||
    SetTimer();
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    DAEventLoop();
 | 
					    DAEventLoop();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -542,11 +519,25 @@ void RemoveChecksumFile( void )
 | 
				
			||||||
    remove( config.checksumFileName );
 | 
					    remove( config.checksumFileName );
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// dummy needed because this func is a signal-handler
 | 
					void TimedOut( void )
 | 
				
			||||||
void TimerHandler( int dummy )
 | 
					{
 | 
				
			||||||
 | 
					    CheckTimeOut( true );
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void CheckTimeOut( bool force )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    static int checkMail = 0;
 | 
					    static int checkMail = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    struct timeval now;
 | 
				
			||||||
 | 
					    gettimeofday(&now, NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    unsigned long nowMs = now.tv_sec * 1000L + now.tv_usec / 1000L;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!force && nowMs - lastTimeOut < 1000L / config.fps)
 | 
				
			||||||
 | 
						return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    lastTimeOut = nowMs;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if( readConfigFile ) {
 | 
					    if( readConfigFile ) {
 | 
				
			||||||
	readConfigFile = false;
 | 
						readConfigFile = false;
 | 
				
			||||||
	UpdateConfiguration();
 | 
						UpdateConfiguration();
 | 
				
			||||||
| 
						 | 
					@ -1252,6 +1243,8 @@ void ButtonPressed( int button, int state, int x, int y )
 | 
				
			||||||
    } else
 | 
					    } else
 | 
				
			||||||
	// reread the config file
 | 
						// reread the config file
 | 
				
			||||||
	readConfigFile = true;
 | 
						readConfigFile = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    CheckTimeOut( false );
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void ButtonReleased( int button, int state, int x, int y )
 | 
					void ButtonReleased( int button, int state, int x, int y )
 | 
				
			||||||
| 
						 | 
					@ -1265,6 +1258,8 @@ void ButtonReleased( int button, int state, int x, int y )
 | 
				
			||||||
	if( ret == 127 || ret == -1 )
 | 
						if( ret == 127 || ret == -1 )
 | 
				
			||||||
	    WARNING( "execution of command \"%s\" failed.\n", config.runCmd );
 | 
						    WARNING( "execution of command \"%s\" failed.\n", config.runCmd );
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    CheckTimeOut( false );
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void GetHexColorString( const char *colorName, char *xpmLine )
 | 
					void GetHexColorString( const char *colorName, char *xpmLine )
 | 
				
			||||||
| 
						 | 
					@ -1326,7 +1321,7 @@ void UpdateConfiguration( void )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    PreparePixmaps( true );
 | 
					    PreparePixmaps( true );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    SetTimer();
 | 
					    DASetTimeout (1000 / config.fps);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void CleanupNames( void )
 | 
					void CleanupNames( void )
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue