[{"id":2803,"web_url":"https://patchwork.libcamera.org/comment/2803/","msgid":"<20191006193159.6m7jdswkgq7nyn5x@uno.localdomain>","date":"2019-10-06T19:31:59","subject":"Re: [libcamera-devel] [PATCH 6/9] libcamera: timer: Forbid starting\n\tor stopping timer from another thread","submitter":{"id":3,"url":"https://patchwork.libcamera.org/api/people/3/","name":"Jacopo Mondi","email":"jacopo@jmondi.org"},"content":"Hi Laurent,\n\nOn Sun, Oct 06, 2019 at 08:32:23AM +0300, Laurent Pinchart wrote:\n> Starting or stopping a timer from a different thread than the one it\n> belongs to is inherently racy. Disallow it.\n>\n\nLooks good\nReviewed-by: Jacopo Mondi <jacopo@jmondi.org>\n\nThanks\n   j\n\n> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n> ---\n>  src/libcamera/timer.cpp | 24 +++++++++++++++++++++---\n>  1 file changed, 21 insertions(+), 3 deletions(-)\n>\n> diff --git a/src/libcamera/timer.cpp b/src/libcamera/timer.cpp\n> index 5d4e52713e6e..8749d66c8662 100644\n> --- a/src/libcamera/timer.cpp\n> +++ b/src/libcamera/timer.cpp\n> @@ -36,6 +36,11 @@ LOG_DEFINE_CATEGORY(Timer)\n>   * Once started the timer will run until it times out. It can be stopped with\n>   * stop(), and once it times out or is stopped, can be started again with\n>   * start().\n> + *\n> + * Timers run in the thread they belong to, and thus emit the \\a ref timeout\n> + * signal from that thread. To avoid race conditions they must not be started\n> + * or stopped from a different thread, attempts to do so will be rejected and\n> + * logged, and may cause undefined behaviour.\n>   */\n>\n>  /**\n> @@ -57,17 +62,24 @@ Timer::~Timer()\n>   * \\brief Start or restart the timer with a timeout of \\a msec\n>   * \\param[in] msec The timer duration in milliseconds\n>   *\n> - * If the timer is already running it will be stopped and restarted.\n> + * This method shall be called from the thread the timer is associated with. If\n> + * the timer is already running it will be stopped and restarted.\n>   */\n>\n>  /**\n>   * \\brief Start or restart the timer with a timeout of \\a duration\n>   * \\param[in] duration The timer duration in milliseconds\n>   *\n> - * If the timer is already running it will be stopped and restarted.\n> + * This method shall be called from the thread the timer is associated with. If\n> + * the timer is already running it will be stopped and restarted.\n>   */\n>  void Timer::start(std::chrono::milliseconds duration)\n>  {\n> +\tif (Thread::current() != thread()) {\n> +\t\tLOG(Timer, Error) << \"Timer can't be started from another thread\";\n> +\t\treturn;\n> +\t}\n> +\n>  \tdeadline_ = utils::clock::now() + duration;\n>\n>  \tLOG(Timer, Debug)\n> @@ -87,13 +99,19 @@ void Timer::start(std::chrono::milliseconds duration)\n>   * After this function returns the timer is guaranteed not to emit the\n>   * \\ref timeout signal.\n>   *\n> - * If the timer is not running this function performs no operation.\n> + * This method shall be called from the thread the timer is associated with. If\n> + * the timer is not running this function performs no operation.\n>   */\n>  void Timer::stop()\n>  {\n>  \tif (!isRunning())\n>  \t\treturn;\n>\n> +\tif (Thread::current() != thread()) {\n> +\t\tLOG(Timer, Error) << \"Timer can't be stopped from another thread\";\n> +\t\treturn;\n> +\t}\n> +\n>  \tunregisterTimer();\n>  }\n>\n> --\n> Regards,\n>\n> Laurent Pinchart\n>\n> _______________________________________________\n> libcamera-devel mailing list\n> libcamera-devel@lists.libcamera.org\n> https://lists.libcamera.org/listinfo/libcamera-devel","headers":{"Return-Path":"<jacopo@jmondi.org>","Received":["from relay10.mail.gandi.net (relay10.mail.gandi.net\n\t[217.70.178.230])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 5FAE060E1E\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tSun,  6 Oct 2019 21:30:14 +0200 (CEST)","from uno.localdomain (2-224-242-101.ip172.fastwebnet.it\n\t[2.224.242.101]) (Authenticated sender: jacopo@jmondi.org)\n\tby relay10.mail.gandi.net (Postfix) with ESMTPSA id CD6F6240006;\n\tSun,  6 Oct 2019 19:30:13 +0000 (UTC)"],"Date":"Sun, 6 Oct 2019 21:31:59 +0200","From":"Jacopo Mondi <jacopo@jmondi.org>","To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","Cc":"libcamera-devel@lists.libcamera.org","Message-ID":"<20191006193159.6m7jdswkgq7nyn5x@uno.localdomain>","References":"<20191006053226.8976-1-laurent.pinchart@ideasonboard.com>\n\t<20191006053226.8976-7-laurent.pinchart@ideasonboard.com>","MIME-Version":"1.0","Content-Type":"multipart/signed; micalg=pgp-sha256;\n\tprotocol=\"application/pgp-signature\"; boundary=\"yulczd4ni7xojyng\"","Content-Disposition":"inline","In-Reply-To":"<20191006053226.8976-7-laurent.pinchart@ideasonboard.com>","User-Agent":"NeoMutt/20180716","Subject":"Re: [libcamera-devel] [PATCH 6/9] libcamera: timer: Forbid starting\n\tor stopping timer from another thread","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","X-List-Received-Date":"Sun, 06 Oct 2019 19:30:14 -0000"}}]