libcutils: remove sched_set/getscheduler
am: bc41166d56

Change-Id: I5e18fdc4baf128ee4edfa83edfc4e4be585af9b4
diff --git a/base/include/android-base/properties.h b/base/include/android-base/properties.h
index 4de5e57..041586c 100644
--- a/base/include/android-base/properties.h
+++ b/base/include/android-base/properties.h
@@ -62,15 +62,14 @@
 // Waits for the system property `key` to have the value `expected_value`.
 // Times out after `relative_timeout`.
 // Returns true on success, false on timeout.
-bool WaitForProperty(const std::string& key,
-                     const std::string& expected_value,
-                     std::chrono::milliseconds relative_timeout);
+bool WaitForProperty(const std::string& key, const std::string& expected_value,
+                     std::chrono::milliseconds relative_timeout = std::chrono::milliseconds::max());
 
 // Waits for the system property `key` to be created.
 // Times out after `relative_timeout`.
 // Returns true on success, false on timeout.
-bool WaitForPropertyCreation(const std::string& key,
-                             std::chrono::milliseconds relative_timeout);
+bool WaitForPropertyCreation(const std::string& key, std::chrono::milliseconds relative_timeout =
+                                                         std::chrono::milliseconds::max());
 
 } // namespace base
 } // namespace android
diff --git a/base/properties.cpp b/base/properties.cpp
index 32c0128..816bca0 100644
--- a/base/properties.cpp
+++ b/base/properties.cpp
@@ -101,22 +101,24 @@
 }
 
 // TODO: chrono_utils?
-static void DurationToTimeSpec(timespec& ts, std::chrono::nanoseconds d) {
+static void DurationToTimeSpec(timespec& ts, const std::chrono::milliseconds d) {
   auto s = std::chrono::duration_cast<std::chrono::seconds>(d);
   auto ns = std::chrono::duration_cast<std::chrono::nanoseconds>(d - s);
   ts.tv_sec = s.count();
   ts.tv_nsec = ns.count();
 }
 
+// TODO: boot_clock?
 using AbsTime = std::chrono::time_point<std::chrono::steady_clock>;
 
-static void UpdateTimeSpec(timespec& ts,
-                           const AbsTime& timeout) {
+static void UpdateTimeSpec(timespec& ts, std::chrono::milliseconds relative_timeout,
+                           const AbsTime& start_time) {
   auto now = std::chrono::steady_clock::now();
-  auto remaining_timeout = std::chrono::duration_cast<std::chrono::nanoseconds>(timeout - now);
-  if (remaining_timeout < 0ns) {
+  auto time_elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(now - start_time);
+  if (time_elapsed >= relative_timeout) {
     ts = { 0, 0 };
   } else {
+    auto remaining_timeout = relative_timeout - time_elapsed;
     DurationToTimeSpec(ts, remaining_timeout);
   }
 }
@@ -127,11 +129,7 @@
 // Returns nullptr on timeout.
 static const prop_info* WaitForPropertyCreation(const std::string& key,
                                                 const std::chrono::milliseconds& relative_timeout,
-                                                AbsTime& absolute_timeout) {
-  // TODO: boot_clock?
-  auto now = std::chrono::steady_clock::now();
-  absolute_timeout = now + relative_timeout;
-
+                                                const AbsTime& start_time) {
   // Find the property's prop_info*.
   const prop_info* pi;
   unsigned global_serial = 0;
@@ -139,17 +137,16 @@
     // The property doesn't even exist yet.
     // Wait for a global change and then look again.
     timespec ts;
-    UpdateTimeSpec(ts, absolute_timeout);
+    UpdateTimeSpec(ts, relative_timeout, start_time);
     if (!__system_property_wait(nullptr, global_serial, &global_serial, &ts)) return nullptr;
   }
   return pi;
 }
 
-bool WaitForProperty(const std::string& key,
-                     const std::string& expected_value,
+bool WaitForProperty(const std::string& key, const std::string& expected_value,
                      std::chrono::milliseconds relative_timeout) {
-  AbsTime absolute_timeout;
-  const prop_info* pi = WaitForPropertyCreation(key, relative_timeout, absolute_timeout);
+  auto start_time = std::chrono::steady_clock::now();
+  const prop_info* pi = WaitForPropertyCreation(key, relative_timeout, start_time);
   if (pi == nullptr) return false;
 
   WaitForPropertyData data;
@@ -162,7 +159,7 @@
     if (data.done) return true;
 
     // It didn't, so wait for the property to change before checking again.
-    UpdateTimeSpec(ts, absolute_timeout);
+    UpdateTimeSpec(ts, relative_timeout, start_time);
     uint32_t unused;
     if (!__system_property_wait(pi, data.last_read_serial, &unused, &ts)) return false;
   }
@@ -170,8 +167,8 @@
 
 bool WaitForPropertyCreation(const std::string& key,
                              std::chrono::milliseconds relative_timeout) {
-  AbsTime absolute_timeout;
-  return (WaitForPropertyCreation(key, relative_timeout, absolute_timeout) != nullptr);
+  auto start_time = std::chrono::steady_clock::now();
+  return (WaitForPropertyCreation(key, relative_timeout, start_time) != nullptr);
 }
 
 }  // namespace base
diff --git a/base/properties_test.cpp b/base/properties_test.cpp
index 1bbe482..de5f3dc 100644
--- a/base/properties_test.cpp
+++ b/base/properties_test.cpp
@@ -151,6 +151,38 @@
   ASSERT_LT(std::chrono::duration_cast<std::chrono::milliseconds>(t1 - t0), 600ms);
 }
 
+TEST(properties, WaitForProperty_MaxTimeout) {
+  std::atomic<bool> flag{false};
+  std::thread thread([&]() {
+    android::base::SetProperty("debug.libbase.WaitForProperty_test", "a");
+    while (!flag) std::this_thread::yield();
+    std::this_thread::sleep_for(500ms);
+    android::base::SetProperty("debug.libbase.WaitForProperty_test", "b");
+  });
+
+  ASSERT_TRUE(android::base::WaitForProperty("debug.libbase.WaitForProperty_test", "a", 1s));
+  flag = true;
+  // Test that this does not immediately return false due to overflow issues with the timeout.
+  ASSERT_TRUE(android::base::WaitForProperty("debug.libbase.WaitForProperty_test", "b"));
+  thread.join();
+}
+
+TEST(properties, WaitForProperty_NegativeTimeout) {
+  std::atomic<bool> flag{false};
+  std::thread thread([&]() {
+    android::base::SetProperty("debug.libbase.WaitForProperty_test", "a");
+    while (!flag) std::this_thread::yield();
+    std::this_thread::sleep_for(500ms);
+    android::base::SetProperty("debug.libbase.WaitForProperty_test", "b");
+  });
+
+  ASSERT_TRUE(android::base::WaitForProperty("debug.libbase.WaitForProperty_test", "a", 1s));
+  flag = true;
+  // Assert that this immediately returns with a negative timeout
+  ASSERT_FALSE(android::base::WaitForProperty("debug.libbase.WaitForProperty_test", "b", -100ms));
+  thread.join();
+}
+
 TEST(properties, WaitForPropertyCreation) {
   std::thread thread([&]() {
     std::this_thread::sleep_for(100ms);
diff --git a/fs_mgr/fs_mgr_boot_config.cpp b/fs_mgr/fs_mgr_boot_config.cpp
index 5b2f218..cffa6ce 100644
--- a/fs_mgr/fs_mgr_boot_config.cpp
+++ b/fs_mgr/fs_mgr_boot_config.cpp
@@ -56,7 +56,7 @@
             return true;
         }
 
-        LERROR << "Error finding '" << key << "' in device tree";
+        LINFO << "Error finding '" << key << "' in device tree";
     }
 
     return false;
diff --git a/libcutils/canned_fs_config.c b/libcutils/canned_fs_config.c
index e0e6a34..96ca566 100644
--- a/libcutils/canned_fs_config.c
+++ b/libcutils/canned_fs_config.c
@@ -17,6 +17,7 @@
 #include <errno.h>
 #include <inttypes.h>
 #include <limits.h>
+#include <stdbool.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -41,7 +42,7 @@
 }
 
 int load_canned_fs_config(const char* fn) {
-    char line[PATH_MAX + 200];
+    char buf[PATH_MAX + 200];
     FILE* f;
 
     f = fopen(fn, "r");
@@ -50,17 +51,21 @@
         return -1;
     }
 
-    while (fgets(line, sizeof(line), f)) {
+    while (fgets(buf, sizeof(buf), f)) {
         Path* p;
         char* token;
+        char* line = buf;
+        bool rootdir;
 
         while (canned_used >= canned_alloc) {
             canned_alloc = (canned_alloc+1) * 2;
             canned_data = (Path*) realloc(canned_data, canned_alloc * sizeof(Path));
         }
         p = canned_data + canned_used;
-        p->path = strdup(strtok(line, " "));
-        p->uid = atoi(strtok(NULL, " "));
+        if (line[0] == '/') line++;
+        rootdir = line[0] == ' ';
+        p->path = strdup(rootdir ? "" : strtok(line, " "));
+        p->uid = atoi(strtok(rootdir ? line : NULL, " "));
         p->gid = atoi(strtok(NULL, " "));
         p->mode = strtol(strtok(NULL, " "), NULL, 8);   // mode is in octal
         p->capabilities = 0;
diff --git a/logd/LogBufferElement.cpp b/logd/LogBufferElement.cpp
index 81356fe..04a620c 100644
--- a/logd/LogBufferElement.cpp
+++ b/logd/LogBufferElement.cpp
@@ -235,7 +235,9 @@
     }
     iovec[1].iov_len = entry.len;
 
-    log_time retval = reader->sendDatav(iovec, 2) ? FLUSH_ERROR : mRealTime;
+    log_time retval = reader->sendDatav(iovec, 1 + (entry.len != 0))
+                          ? FLUSH_ERROR
+                          : mRealTime;
 
     if (buffer) free(buffer);