Os: add Nanosleep()
Add Nanosleep(), so that upper layers of wifilogd can
briefly suspend execution after a transient error.
Bug: 32454491
Test: ./runtest.sh (on angler)
Change-Id: I85e95ddf4139ae10ab95a40c46ed2a424e2a28ad
diff --git a/os.cpp b/os.cpp
index ab178c1..b9093e7 100644
--- a/os.cpp
+++ b/os.cpp
@@ -14,10 +14,10 @@
* limitations under the License.
*/
-#include <errno.h>
-
#include <algorithm>
+#include <cerrno>
#include <cstdint>
+#include <cstring>
#include "android-base/logging.h"
@@ -70,6 +70,26 @@
return now_timestamp;
}
+void Os::Nanosleep(uint32_t sleep_time_nsec) {
+ struct timespec sleep_timespec = {
+ 0, // tv_sec
+ SAFELY_CLAMP(sleep_time_nsec, decltype(timespec::tv_nsec), 0, kMaxNanos)};
+
+ int failed = 0;
+ do {
+ struct timespec remaining_timespec;
+ failed = raw_os_->Nanosleep(&sleep_timespec, &remaining_timespec);
+ sleep_timespec = remaining_timespec;
+ } while (failed && errno == EINTR && sleep_timespec.tv_nsec > 0);
+
+ if (failed && errno != EINTR) {
+ // The only other documented errors for the underlying nanosleep() call are
+ // EFAULT and EINVAL. But we always pass valid pointers, and the values in
+ // |sleep_timespec| are always valid.
+ LOG(FATAL) << "Unexpected error: " << std::strerror(errno);
+ }
+}
+
std::tuple<size_t, Os::Errno> Os::ReceiveDatagram(int fd, void* buf,
size_t buflen) {
// recv() takes a size_t, but returns an ssize_t. That means that the largest