From 761d051218d4bf29a71532d7e67a18beda63cb30 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Sun, 12 May 2013 11:47:09 -0600 Subject: Fixe a race confition in NxWM::CCalibration --- NxWidgets/ChangeLog.txt | 4 ++++ NxWidgets/nxwm/include/ccalibration.hxx | 33 ++++++++++++++++++++++++++++----- NxWidgets/nxwm/src/ccalibration.cxx | 26 +++++++++++++++++--------- 3 files changed, 49 insertions(+), 14 deletions(-) diff --git a/NxWidgets/ChangeLog.txt b/NxWidgets/ChangeLog.txt index c72d20782..46eb06a08 100644 --- a/NxWidgets/ChangeLog.txt +++ b/NxWidgets/ChangeLog.txt @@ -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). diff --git a/NxWidgets/nxwm/include/ccalibration.hxx b/NxWidgets/nxwm/include/ccalibration.hxx index a54a35bf7..f114a19a2 100644 --- a/NxWidgets/nxwm/include/ccalibration.hxx +++ b/NxWidgets/nxwm/include/ccalibration.hxx @@ -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 * * 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. diff --git a/NxWidgets/nxwm/src/ccalibration.cxx b/NxWidgets/nxwm/src/ccalibration.cxx index 32aeb5ee6..04233d5ef 100644 --- a/NxWidgets/nxwm/src/ccalibration.cxx +++ b/NxWidgets/nxwm/src/ccalibration.cxx @@ -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 * * Redistribution and use in source and binary forms, with or without @@ -247,26 +247,34 @@ void CCalibration::hide(void) void CCalibration::redraw(void) { - gvdbg("Entry\n"); + uint8_t waitcount = 0; - // 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 + gvdbg("Entry\n"); - // Is the calibration thread running? + // 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 - 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); -- cgit v1.2.3