got rid of all the absolute paths in the fitpc code
Previously, there were 2 places (BinaryLogReader and the HTTP file server) that
had "/home/driver/" hard coded. I changed both of those to use paths relative to
the location of the executable (retrieved from /proc/self/exe).
git-svn-id: https://robotics.mvla.net/svn/frc971/2013/trunk/src@4162 f308d9b7-e957-4cde-b6ac-9a88185e7312
diff --git a/aos/common/once.h b/aos/common/once.h
new file mode 100644
index 0000000..026b1bd
--- /dev/null
+++ b/aos/common/once.h
@@ -0,0 +1,69 @@
+#ifndef AOS_COMMON_ONCE_H_
+#define AOS_COMMON_ONCE_H_
+
+#include <stdint.h>
+
+#include "aos/common/gtest_prod.h"
+
+namespace aos {
+namespace testing {
+
+FORWARD_DECLARE_TEST_CASE(OnceTest, MemoryClearing);
+
+} // namespace testing
+
+// Designed for the same thing as pthread_once: to run something exactly 1 time.
+//
+// Intended use case:
+// const char *CalculateSomethingCool() {
+// static ::aos::Once<const char> once(DoCalculateSomethingCool);
+// return once.Get();
+// }
+//
+// IMPORTANT: Instances _must_ be placed in memory that gets 0-initialized
+// automatically or Reset() must be called exactly once!!
+// The expected use case is to use one of these as a static variable, and those
+// do get 0-initialized under the C++ standard. Global variables are treated the
+// same way by the C++ Standard.
+// Placing an instance in shared memory (and using Reset()) is also supported.
+// The constructor does not initialize all of the member variables!
+// This is because initializing them in the constructor creates a race condition
+// if initialization of static variables isn't thread safe.
+template<typename T>
+class Once {
+ public:
+ typedef T *(*Function)();
+ explicit Once(Function function);
+
+ // Returns the result of calling function_. The first call will actually run
+ // it and then any other ones will block (if necessary) until it's finished
+ // and then return the same thing.
+ T *Get();
+
+ // Will clear out all the member variables. If this is going to be used
+ // instead of creating an instance in 0-initialized memory, then this method
+ // must be called exactly once before Get() is called anywhere.
+ // This method can also be called to run the function again the next time
+ // Get() is called. However, calling it again is not thread safe.
+ void Reset();
+
+ private:
+ // The function to run to calculate result_.
+ Function function_;
+ // Whether or not it is running. Gets atomically swapped from 0 to 1 by the
+ // thread that actually runs function_.
+ volatile int run_;
+ // Whether or not it is done. Gets set to true after the thread that is
+ // running function_ finishes running it and storing the result in result_.
+ volatile bool done_;
+ // What function_ returned when it was executed.
+ T *result_;
+
+ FRIEND_TEST_NAMESPACE(OnceTest, MemoryClearing, testing);
+};
+
+} // namespace aos
+
+#include "aos/common/once-tmpl.h"
+
+#endif // AOS_COMMON_ONCE_H_