SynchronousTask.h (2085B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #ifndef MOZILLA_GFX_SYNCHRONOUSTASK_H 8 #define MOZILLA_GFX_SYNCHRONOUSTASK_H 9 10 #include "mozilla/ReentrantMonitor.h" // for ReentrantMonitor, etc 11 12 namespace mozilla { 13 namespace layers { 14 15 // Helper that creates a monitor and a "done" flag, then enters the monitor. 16 class MOZ_STACK_CLASS SynchronousTask { 17 friend class AutoCompleteTask; 18 19 public: 20 explicit SynchronousTask(const char* name) : mMonitor(name), mDone(false) {} 21 22 nsresult Wait(PRIntervalTime aInterval = PR_INTERVAL_NO_TIMEOUT) { 23 ReentrantMonitorAutoEnter lock(mMonitor); 24 25 // For indefinite timeouts, wait in a while loop to handle spurious 26 // wakeups. 27 while (aInterval == PR_INTERVAL_NO_TIMEOUT && !mDone) { 28 mMonitor.Wait(); 29 } 30 31 // For finite timeouts, we only check once for completion, and otherwise 32 // rely on the ReentrantMonitor to manage the interval. If the monitor 33 // returns too early, we'll never know, but we can check if the mDone 34 // flag was set to true, indicating that the task finished successfully. 35 if (!mDone) { 36 // We ignore the return value from ReentrantMonitor::Wait, because it's 37 // always NS_OK, even in the case of timeout. 38 mMonitor.Wait(aInterval); 39 40 if (!mDone) { 41 return NS_ERROR_ABORT; 42 } 43 } 44 45 return NS_OK; 46 } 47 48 private: 49 void Complete() { 50 ReentrantMonitorAutoEnter lock(mMonitor); 51 mDone = true; 52 mMonitor.NotifyAll(); 53 } 54 55 private: 56 ReentrantMonitor mMonitor MOZ_UNANNOTATED; 57 bool mDone; 58 }; 59 60 class MOZ_STACK_CLASS AutoCompleteTask final { 61 public: 62 explicit AutoCompleteTask(SynchronousTask* aTask) : mTask(aTask) {} 63 ~AutoCompleteTask() { mTask->Complete(); } 64 65 private: 66 SynchronousTask* mTask; 67 }; 68 69 } // namespace layers 70 } // namespace mozilla 71 72 #endif