Fixe a race confition in NxWM::CCalibration

This commit is contained in:
Gregory Nutt 2013-05-12 11:47:09 -06:00
parent 27689b5aa5
commit 9837ed0170
3 changed files with 49 additions and 14 deletions

View File

@ -354,3 +354,7 @@
need to minimize the icon size a bit. From Ken Pettit (2013-5-11).
* NxWidgets/nxwm/src/glyph_mediaplayer.cxx: Smaller version of the
media player glyph. From Ken Pettit (2013-5-12).
* NxWidgets/nxwm/include/ccalibration.hxx and src/ccalibration.cxx:
Fix a race condition that would cause the calibration screen
to fail to come up when its icon was touched (From Ken Pettit,
2013-5-12).

View File

@ -1,7 +1,7 @@
/****************************************************************************
* NxWidgets/nxwm/include/ccalibration.hxx
*
* Copyright (C) 2012 Gregory Nutt. All rights reserved.
* Copyright (C) 2012-2013 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@ -175,21 +175,44 @@ namespace NxWM
/**
* Return true if the calibration thread is running normally. There are
* lots of potential race conditions. Let's hope that things are running
* orderly and we that we do not have to concern ourself with them
* lots of potential race conditions. There are also two ambiguous
* states:
*
* 1) The thread may have been started but not yet running
* (CALTHREAD_STARTED), or the
* 2) The thread may been requested to terminate, but has not yet
* terminated (CALTHREAD_STOPREQUESTED)
*
* Both of those states will cause isRunning() to return false.
*
* @return True if the calibration thread is runnning normally.
*/
inline bool isRunning(void) const
{
// What if the boundary states CALTHREAD_STARTED and CALTHREAD_STOPREQUESTED?
return (m_calthread == CALTHREAD_RUNNING ||
m_calthread == CALTHREAD_HIDE ||
m_calthread == CALTHREAD_SHOW);
}
/**
* Return true if the calibration thread is has been started and has not
* yet terminated. There is a potential race condition here when the
* thread has been requested to terminate, but has not yet terminated
* (CALTHREAD_STOPREQUESTED). isStarted() will return false in that case.
*
* @return True if the calibration thread has been started and/or is
* running normally.
*/
inline bool isStarted(void) const
{
return (m_calthread == CALTHREAD_STARTED ||
m_calthread == CALTHREAD_RUNNING ||
m_calthread == CALTHREAD_HIDE ||
m_calthread == CALTHREAD_SHOW);
}
/**
* The calibration thread. This is the entry point of a thread that provides the
* calibration displays, waits for input, and collects calibration data.

View File

@ -1,7 +1,7 @@
/****************************************************************************
* NxWidgets/nxwm/src/ccalibration.cxx
*
* Copyright (C) 2012 Gregory Nutt. All rights reserved.
* Copyright (C) 2012-2013 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@ -247,26 +247,34 @@ void CCalibration::hide(void)
void CCalibration::redraw(void)
{
uint8_t waitcount = 0;
gvdbg("Entry\n");
// Is the calibration thread running? We might have to restart it if
// we have completed the calibration early but are being brought to
// top of the display again
// Is the calibration thread still running? We might have to restart
// it if we have completed the calibration early but are being brought
// to top of the display again
// Is the calibration thread running?
if (!isRunning())
if (!isStarted())
{
gvdbg("Starting calibration: m_calthread=%d\n", (int)m_calthread);
(void)startCalibration(CALTHREAD_SHOW);
}
// Is the calibration thread running? If not, then wait until it is.
while (!isRunning() && (++waitcount < 10))
{
usleep(500);
}
// The calibration thread is running. Make sure that is is not
// already processing a redraw
else if (m_calthread != CALTHREAD_SHOW)
if (m_calthread != CALTHREAD_SHOW)
{
// Ask the calibration thread to restart the calibration and redraw the display
// Ask the calibration thread to restart the calibration and redraw
// the display
m_calthread = CALTHREAD_SHOW;
(void)pthread_kill(m_thread, CONFIG_NXWM_CALIBRATION_SIGNO);