made sure everything's thread safe

Pretty much everything already was, but I tweaked a few things to make
sure they stay that way and added various comments about that fact. Also
cleaned up a few things along the way and removed SafeMessageBuilder
because it wasn't.
diff --git a/aos/linux_code/configuration.cc b/aos/linux_code/configuration.cc
index 55fff84..e4d5d80 100644
--- a/aos/linux_code/configuration.cc
+++ b/aos/linux_code/configuration.cc
@@ -44,6 +44,7 @@
   unique_c_ptr<ifaddrs, freeifaddrs> addrs_deleter(addrs);
 
   for (; addrs != nullptr; addrs = addrs->ifa_next) {
+    // ifa_addr tends to be nullptr on CAN interfaces.
     if (addrs->ifa_addr != nullptr && addrs->ifa_addr->sa_family == AF_INET) {
       if (strcmp(kLinuxNetInterface, addrs->ifa_name) == 0) {
         static const in_addr r =
diff --git a/aos/linux_code/core.cc b/aos/linux_code/core.cc
index 5b580ef..189df1d 100644
--- a/aos/linux_code/core.cc
+++ b/aos/linux_code/core.cc
@@ -13,7 +13,7 @@
 // Initializes shared memory. This is the only file that will create the shared
 // memory file if it doesn't already exist (and set everything up).
 //
-// Will also create the file given as a first argument.
+// Will also touch the file given as a first argument.
 
 int main(int argc, char **argv) {
   aos::InitCreate();
diff --git a/aos/linux_code/init.cc b/aos/linux_code/init.cc
index 05004a2..d8864fe 100644
--- a/aos/linux_code/init.cc
+++ b/aos/linux_code/init.cc
@@ -44,7 +44,7 @@
   WriteCoreDumps();
 }
 
-int LockAllMemory() {
+void LockAllMemory() {
   InitStart();
   if (mlockall(MCL_CURRENT | MCL_FUTURE) == -1) {
     PDie("%s-init: mlockall failed", program_invocation_short_name);
@@ -55,8 +55,6 @@
   uint8_t data[4096 * 8];
   // Not 0 because linux might optimize that to a 0-filled page.
   memset(data, 1, sizeof(data));
-
-  return 0;
 }
 
 // Do the initialization code that is necessary for both realtime and
@@ -76,11 +74,14 @@
 void Init(int relative_priority) {
   if (getenv(kNoRealtimeEnvironmentVariable) == NULL) {  // if nobody set it
     LockAllMemory();
+
     // Only let rt processes run for 3 seconds straight.
     SetSoftRLimit(RLIMIT_RTTIME, 3000000, true);
+
     // Allow rt processes up to priority 40.
     SetSoftRLimit(RLIMIT_RTPRIO, 40, false);
-    // Set our process to priority 40.
+
+    // Set our process to the appropriate priority.
     struct sched_param param;
     param.sched_priority = 30 + relative_priority;
     if (sched_setscheduler(0, SCHED_FIFO, &param) != 0) {
diff --git a/aos/linux_code/init.h b/aos/linux_code/init.h
index c2b2635..538684e 100644
--- a/aos/linux_code/init.h
+++ b/aos/linux_code/init.h
@@ -3,6 +3,10 @@
 
 namespace aos {
 
+// In order to use shared memory, one of the Init* functions must be called in
+// exactly 1 thread per process. It is OK to keep going without calling one of
+// them again after fork(2)ing.
+
 // Does the non-realtime parts of the initialization process.
 void InitNRT();
 // Initializes everything, including the realtime stuff.
@@ -17,7 +21,8 @@
 void Cleanup();
 
 // Sets up this process to write core dump files.
-// This is called by Init*.
+// This is called by Init*, but it's here for other files that want this
+// behavior without calling Init*.
 void WriteCoreDumps();
 
 }  // namespace aos
diff --git a/aos/linux_code/ipc_lib/shared_mem.c b/aos/linux_code/ipc_lib/shared_mem.c
index a132233..e0be160 100644
--- a/aos/linux_code/ipc_lib/shared_mem.c
+++ b/aos/linux_code/ipc_lib/shared_mem.c
@@ -8,6 +8,7 @@
 #include <sys/types.h>
 #include <errno.h>
 #include <stdlib.h>
+#include <assert.h>
 
 #include "aos/linux_code/ipc_lib/core_lib.h"
 #include "aos/common/logging/logging.h"
@@ -39,6 +40,7 @@
 
 // TODO(brians): madvise(2) it to put this shm in core dumps.
 void aos_core_create_shared_mem(enum aos_core_create to_create) {
+  assert(global_core == NULL);
   static struct aos_core global_core_data;
   global_core = &global_core_data;
 
diff --git a/aos/linux_code/ipc_lib/shared_mem.h b/aos/linux_code/ipc_lib/shared_mem.h
index 6968df7..33cb607 100644
--- a/aos/linux_code/ipc_lib/shared_mem.h
+++ b/aos/linux_code/ipc_lib/shared_mem.h
@@ -47,6 +47,7 @@
   reference
 };
 struct aos_core {
+  // Non-0 if we "own" shared_mem and should shm_unlink(3) it when we're done.
   int owner;
   void *shared_mem;
   // How large the chunk of shared memory is.
diff --git a/aos/linux_code/logging/linux_interface.cc b/aos/linux_code/logging/linux_interface.cc
index 9889c07..cbc114e 100644
--- a/aos/linux_code/logging/linux_interface.cc
+++ b/aos/linux_code/logging/linux_interface.cc
@@ -42,7 +42,7 @@
 }  // namespace
 
 Context *Context::Get() {
-  if (my_context == NULL) {
+  if (__builtin_expect(my_context == NULL, 0)) {
     my_context = new Context();
     my_context->name = GetMyName();
     if (my_context->name.size() + 1 > sizeof(LogMessage::name)) {
diff --git a/aos/linux_code/queue-tmpl.h b/aos/linux_code/queue-tmpl.h
index 64121f3..522bf6b 100644
--- a/aos/linux_code/queue-tmpl.h
+++ b/aos/linux_code/queue-tmpl.h
@@ -28,138 +28,6 @@
   msg_ = msg;
 }
 
-// A SafeScopedMessagePtr<> manages a message pointer.
-// It frees it properly when the ScopedMessagePtr<> goes out of scope or gets
-// sent.  By design, there is no way to get the ScopedMessagePtr to release the
-// message pointer.  When the message gets sent, it allocates a queue message,
-// copies the data into it, and then sends it.  Copies copy the message.
-template <class T>
-class SafeScopedMessagePtr {
- public:
-  // Returns a pointer to the message.
-  // This stays valid until Send or the destructor have been called.
-  T *get() { return msg_; }
-
-  T &operator*() {
-    T *msg = get();
-    assert(msg != NULL);
-    return *msg;
-  }
-
-  T *operator->() {
-    T *msg = get();
-    assert(msg != NULL);
-    return msg;
-  }
-
-  operator bool() {
-    return msg_ != NULL;
-  }
-
-  const T *get() const { return msg_; }
-
-  const T &operator*() const {
-    const T *msg = get();
-    assert(msg != NULL);
-    return *msg;
-  }
-
-  const T *operator->() const {
-    const T *msg = get();
-    assert(msg != NULL);
-    return msg;
-  }
-
-  // Sends the message and removes our reference to it.
-  // If the queue is full, over-rides the oldest message in it with our new
-  // message.
-  // Returns true on success, and false otherwise.
-  // The message will be freed.
-  bool Send() {
-    assert(msg_ != NULL);
-    assert(queue_ != NULL);
-    msg_->SetTimeToNow();
-    T *shm_msg = static_cast<T *>(queue_->GetMessage());
-    if (shm_msg == NULL) {
-      return false;
-    }
-    *shm_msg = *msg_;
-    bool return_value = queue_->WriteMessage(shm_msg, RawQueue::kOverride);
-    reset();
-    return return_value;
-  }
-
-  // Sends the message and removes our reference to it.
-  // If the queue is full, blocks until it is no longer full.
-  // Returns true on success, and false otherwise.
-  // Frees the message.
-  bool SendBlocking() {
-    assert(msg_ != NULL);
-    assert(queue_ != NULL);
-    msg_->SetTimeToNow();
-    T *shm_msg = static_cast<T *>(queue_->GetMessage());
-    if (shm_msg == NULL) {
-      return false;
-    }
-    *shm_msg = *msg_;
-    bool return_value = queue_->WriteMessage(shm_msg, RawQueue::kBlock);
-    reset();
-    return return_value;
-  }
-
-  // Frees the contained message.
-  ~SafeScopedMessagePtr() {
-    reset();
-  }
-
-  // Implements a move constructor to take the message pointer from the
-  // temporary object to save work.
-  SafeScopedMessagePtr(SafeScopedMessagePtr<T> &&ptr)
-    : queue_(ptr.queue_),
-      msg_(ptr.msg_) {
-    ptr.msg_ = NULL;
-  }
-
-  // Copy constructor actually copies the data.
-  SafeScopedMessagePtr(const SafeScopedMessagePtr<T> &ptr)
-      : queue_(ptr.queue_),
-        msg_(NULL) {
-    reset(new T(*ptr.get()));
-  }
-  // Equal operator copies the data.
-  void operator=(const SafeScopedMessagePtr<T> &ptr) {
-    queue_ = ptr.queue_;
-    reset(new T(*ptr.get()));
-  }
-
- private:
-  // Provide access to private constructor.
-  friend class aos::Queue<typename std::remove_const<T>::type>;
-  friend class aos::SafeMessageBuilder<T>;
-
-  // Only Queue should be able to build a message pointer.
-  SafeScopedMessagePtr(RawQueue *queue)
-      : queue_(queue), msg_(new T()) {}
-
-  // Sets the pointer to msg, freeing the old value if it was there.
-  // This is private because nobody should be able to get a pointer to a message
-  // that needs to be scoped without using the queue.
-  void reset(T *msg = NULL) {
-    if (msg_) {
-      delete msg_;
-    }
-    msg_ = msg;
-  }
-
-  // Sets the queue that owns this message.
-  void set_queue(RawQueue *queue) { queue_ = queue; }
-
-  // The queue that the message is a part of.
-  RawQueue *queue_;
-  // The message or NULL.
-  T *msg_;
-};
-
 template <class T>
 void Queue<T>::Init() {
   if (queue_ == NULL) {
@@ -223,14 +91,6 @@
 }
 
 template <class T>
-SafeScopedMessagePtr<T> Queue<T>::SafeMakeMessage() {
-  Init();
-  SafeScopedMessagePtr<T> safe_msg(queue_);
-  safe_msg->Zero();
-  return safe_msg;
-}
-
-template <class T>
 ScopedMessagePtr<T> Queue<T>::MakeMessage() {
   Init();
   return ScopedMessagePtr<T>(queue_, MakeRawMessage());
@@ -249,21 +109,4 @@
   return aos::MessageBuilder<T>(queue_, MakeRawMessage());
 }
 
-
-// This builder uses the safe message pointer so that it can be safely copied
-// in places where it could be leaked.
-template <class T>
-class SafeMessageBuilder {
- public:
-  typedef T Message;
-  bool Send();
-};
-
-template <class T>
-aos::SafeMessageBuilder<T> Queue<T>::SafeMakeWithBuilder() {
-  Init();
-  return aos::SafeMessageBuilder<T>(queue_);
-}
-
-
 }  // namespace aos