summaryrefslogtreecommitdiff
path: root/src/mongo/util
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/util')
-rw-r--r--src/mongo/util/net/ssl_expiration.cpp25
-rw-r--r--src/mongo/util/net/ssl_manager.cpp2
-rw-r--r--src/mongo/util/signal_handlers_synchronous.cpp2
-rw-r--r--src/mongo/util/time_support.cpp80
-rw-r--r--src/mongo/util/time_support.h104
-rw-r--r--src/mongo/util/time_support_test.cpp10
6 files changed, 192 insertions, 31 deletions
diff --git a/src/mongo/util/net/ssl_expiration.cpp b/src/mongo/util/net/ssl_expiration.cpp
index 9f1d6ef9676..d05462ce442 100644
--- a/src/mongo/util/net/ssl_expiration.cpp
+++ b/src/mongo/util/net/ssl_expiration.cpp
@@ -32,14 +32,15 @@
#include <string>
#include "mongo/util/log.h"
+#include "mongo/util/time_support.h"
namespace mongo {
- static const unsigned long long dayInMillis = 24 * 60 * 60 * 1000;
+ static const auto oneDay = stdx::chrono::hours(24);
CertificateExpirationMonitor::CertificateExpirationMonitor(Date_t date)
: _certExpiration(date)
- , _lastCheckTime(Date_t(curTimeMillis64())) {
+ , _lastCheckTime(Date_t::now()) {
}
std::string CertificateExpirationMonitor::taskName() const {
@@ -47,30 +48,28 @@ namespace mongo {
}
void CertificateExpirationMonitor::taskDoWork() {
- const unsigned long long timeSinceLastCheck =
- curTimeMillis64() - _lastCheckTime.millis;
+ const Milliseconds timeSinceLastCheck = Date_t::now() - _lastCheckTime;
- if (timeSinceLastCheck < dayInMillis)
+ if (timeSinceLastCheck < oneDay)
return;
- const Date_t now = Date_t(curTimeMillis64());
+ const Date_t now = Date_t::now();
_lastCheckTime = now;
- if (_certExpiration.millis <= now.millis) {
+ if (_certExpiration <= now) {
// The certificate has expired.
warning() << "Server certificate is now invalid. It expired on "
- << dateToCtimeString(_certExpiration);
+ << dateToISOStringUTC(_certExpiration);
return;
}
- const unsigned long long remainingValidMillis =
- _certExpiration.millis - now.millis;
+ const auto remainingValidDuration = _certExpiration - now;
- if (remainingValidMillis / dayInMillis <= 30) {
+ if (remainingValidDuration <= 30 * oneDay) {
// The certificate will expire in the next 30 days.
warning() << "Server certificate will expire on "
- << dateToCtimeString(_certExpiration) << " in "
- << (remainingValidMillis / dayInMillis)
+ << dateToISOStringUTC(_certExpiration) << " in "
+ << durationCount<stdx::chrono::hours>(remainingValidDuration) / 24
<< " days.";
}
}
diff --git a/src/mongo/util/net/ssl_manager.cpp b/src/mongo/util/net/ssl_manager.cpp
index 6f9be1a1c03..652807e7e71 100644
--- a/src/mongo/util/net/ssl_manager.cpp
+++ b/src/mongo/util/net/ssl_manager.cpp
@@ -699,7 +699,7 @@ namespace mongo {
"The provided SSL certificate is expired or not yet valid.");
}
- *serverCertificateExpirationDate = Date_t(notAfterMillis);
+ *serverCertificateExpirationDate = Date_t::fromMillisSinceEpoch(notAfterMillis);
}
return true;
diff --git a/src/mongo/util/signal_handlers_synchronous.cpp b/src/mongo/util/signal_handlers_synchronous.cpp
index e28d2796fd5..e0d69350203 100644
--- a/src/mongo/util/signal_handlers_synchronous.cpp
+++ b/src/mongo/util/signal_handlers_synchronous.cpp
@@ -114,7 +114,7 @@ namespace {
// must hold streamMutex to call
void writeMallocFreeStreamToLog() {
logger::globalLogDomain()->append(
- logger::MessageEventEphemeral(curTimeMillis64(),
+ logger::MessageEventEphemeral(Date_t::now(),
logger::LogSeverity::Severe(),
getThreadName(),
mallocFreeOStream.str()));
diff --git a/src/mongo/util/time_support.cpp b/src/mongo/util/time_support.cpp
index 69369582058..a850e7fceac 100644
--- a/src/mongo/util/time_support.cpp
+++ b/src/mongo/util/time_support.cpp
@@ -41,6 +41,7 @@
#include "mongo/bson/util/builder.h"
#include "mongo/platform/cstdint.h"
#include "mongo/util/assert_util.h"
+#include "mongo/util/mongoutils/str.h"
#ifdef _WIN32
#include <boost/date_time/filetime_functions.hpp>
@@ -64,12 +65,73 @@ timegm(struct tm *const tmp);
namespace mongo {
+namespace {
+ template <typename Stream> Stream& streamPut(Stream& os, Microseconds us) {
+ return os << us.count() << "\xce\xbcs";
+ }
+
+ template <typename Stream> Stream& streamPut(Stream& os, Milliseconds ms) {
+ return os << ms.count() << "ms";
+ }
+
+ template <typename Stream> Stream& streamPut(Stream& os, Seconds s) {
+ return os << s.count() << 's';
+ }
+} // namespace
+
+ std::ostream& operator<<(std::ostream& os, Microseconds us) {
+ return streamPut(os, us);
+ }
+
+ std::ostream& operator<<(std::ostream& os, Milliseconds ms) {
+ return streamPut(os, ms);
+ }
+ std::ostream& operator<<(std::ostream& os, Seconds s) {
+ return streamPut(os, s);
+ }
+
+ template <typename Allocator>
+ StringBuilderImpl<Allocator>& operator<<(StringBuilderImpl<Allocator>& os, Microseconds us) {
+ return streamPut(os, us);
+ }
+
+ template <typename Allocator>
+ StringBuilderImpl<Allocator>& operator<<(StringBuilderImpl<Allocator>& os, Milliseconds ms) {
+ return streamPut(os, ms);
+ }
+
+ template <typename Allocator>
+ StringBuilderImpl<Allocator>& operator<<(StringBuilderImpl<Allocator>& os, Seconds s) {
+ return streamPut(os, s);
+ }
+
+ template StringBuilderImpl<StackAllocator>& operator<<(StringBuilderImpl<StackAllocator>&,
+ Microseconds);
+ template StringBuilderImpl<StackAllocator>& operator<<(StringBuilderImpl<StackAllocator>&,
+ Milliseconds);
+ template StringBuilderImpl<StackAllocator>& operator<<(StringBuilderImpl<StackAllocator>&,
+ Seconds);
+ template StringBuilderImpl<TrivialAllocator>& operator<<(StringBuilderImpl<TrivialAllocator>&,
+ Microseconds);
+ template StringBuilderImpl<TrivialAllocator>& operator<<(StringBuilderImpl<TrivialAllocator>&,
+ Milliseconds);
+ template StringBuilderImpl<TrivialAllocator>& operator<<(StringBuilderImpl<TrivialAllocator>&,
+ Seconds);
+
+ Date_t Date_t::max() {
+ return fromMillisSinceEpoch(std::numeric_limits<long long>::max());
+ }
+
+ Date_t Date_t::now() {
+ return fromMillisSinceEpoch(curTimeMillis64());
+ }
+
bool Date_t::isFormatable() const {
if (sizeof(time_t) == sizeof(int32_t)) {
- return millis < 2147483647000ULL; // "2038-01-19T03:14:07Z"
+ return millis < 2147483647000LL; // "2038-01-19T03:14:07Z"
}
else {
- return millis < 32535215999000ULL; // "3000-12-31T23:59:59Z"
+ return millis < 32535215999000LL; // "3000-12-31T23:59:59Z"
}
}
@@ -690,7 +752,11 @@ namespace {
resultMillis += (tzAdjSecs * 1000);
- return StatusWith<Date_t>(resultMillis);
+ if (resultMillis > static_cast<unsigned long long>(std::numeric_limits<long long>::max())) {
+ return {ErrorCodes::BadValue,
+ str::stream() << dateString << " is too far in the future"};
+ }
+ return Date_t::fromMillisSinceEpoch(static_cast<long long>(resultMillis));
}
#undef MONGO_ISO_DATE_FMT_NO_TZ
@@ -976,11 +1042,11 @@ namespace {
return ((unsigned long long)tv.tv_sec) * 1000 + tv.tv_usec / 1000;
}
Date_t jsTime() {
- timeval tv;
- gettimeofday(&tv, NULL);
- unsigned long long t = tv.tv_usec / 1000;
- return ((unsigned long long) tv.tv_sec * 1000) + t + getJSTimeVirtualSkew() + getJSTimeVirtualThreadSkew();
+ return Date_t::now() +
+ Milliseconds(getJSTimeVirtualThreadSkew()) +
+ Milliseconds(getJSTimeVirtualSkew());
}
+
unsigned long long curTimeMicros64() {
timeval tv;
gettimeofday(&tv, NULL);
diff --git a/src/mongo/util/time_support.h b/src/mongo/util/time_support.h
index 81db17cbd76..988453f6c39 100644
--- a/src/mongo/util/time_support.h
+++ b/src/mongo/util/time_support.h
@@ -37,30 +37,116 @@
#include <boost/version.hpp>
#include "mongo/base/status_with.h"
+#include "mongo/stdx/chrono.h"
namespace mongo {
- typedef boost::posix_time::milliseconds Milliseconds;
- typedef boost::posix_time::seconds Seconds;
+ template <typename Allocator> class StringBuilderImpl;
+
+ using Microseconds = stdx::chrono::microseconds;
+ using Milliseconds = stdx::chrono::milliseconds;
+ using Seconds = stdx::chrono::seconds;
+ using Minutes = stdx::chrono::minutes;
+ using stdx::chrono::duration_cast;
void time_t_to_Struct(time_t t, struct tm * buf , bool local = false );
std::string time_t_to_String(time_t t);
std::string time_t_to_String_short(time_t t);
- struct Date_t {
- // TODO: make signed (and look for related TODO's)
- unsigned long long millis;
+ //
+ // Operators for putting durations to streams.
+ //
+
+ std::ostream& operator<<(std::ostream& os, Microseconds us);
+ std::ostream& operator<<(std::ostream& os, Milliseconds ms);
+ std::ostream& operator<<(std::ostream& os, Seconds s);
+
+ template <typename Allocator>
+ StringBuilderImpl<Allocator>& operator<<(StringBuilderImpl<Allocator>& os, Microseconds us);
+
+ template <typename Allocator>
+ StringBuilderImpl<Allocator>& operator<<(StringBuilderImpl<Allocator>& os, Milliseconds ms);
+
+ template <typename Allocator>
+ StringBuilderImpl<Allocator>& operator<<(StringBuilderImpl<Allocator>& os, Seconds s);
+
+ /**
+ * Convenience method for reading the count of a duration with specified units.
+ *
+ * Use when logging or comparing to integers, to ensure that you're using
+ * the units you intend.
+ *
+ * E.g., log() << durationCount<Seconds>(some duration) << " seconds";
+ */
+ template <typename DOut, typename DIn> long long durationCount(DIn d) {
+ return duration_cast<DOut>(d).count();
+ }
+
+ class Date_t {
+ public:
+ static Date_t max();
+ static Date_t now();
+
+ static Date_t fromMillisSinceEpoch(long long m) {
+ return Date_t(m);
+ }
+
+ template <typename Duration>
+ static Date_t fromDurationSinceEpoch(Duration d) {
+ return fromMillisSinceEpoch(durationCount<Milliseconds>(d));
+ }
+
Date_t(): millis(0) {}
- Date_t(unsigned long long m): millis(m) {}
- operator unsigned long long&() { return millis; }
- operator const unsigned long long&() const { return millis; }
+
void toTm (tm *buf);
std::string toString() const;
time_t toTimeT() const;
int64_t asInt64() const {
- return static_cast<int64_t>(millis);
+ return toMillisSinceEpoch();
}
+ unsigned long long toULL() const { return static_cast<unsigned long long>(asInt64()); }
+ Milliseconds toDurationSinceEpoch() const { return Milliseconds(toMillisSinceEpoch()); }
+ long long toMillisSinceEpoch() const { return static_cast<long long>(millis); }
bool isFormatable() const;
+
+ template <typename Duration>
+ Date_t operator+(Duration d) const {
+ return { millis + duration_cast<Milliseconds>(d).count() };
+ }
+
+ template <typename Duration>
+ Date_t operator-(Duration d) const {
+ return *this + (-d);
+ }
+
+ Milliseconds operator-(Date_t other) const { return Milliseconds(millis - other.millis); }
+
+ bool operator==(Date_t other) const {
+ return toDurationSinceEpoch() == other.toDurationSinceEpoch();
+ }
+
+ bool operator!=(Date_t other) const { return !(*this == other); }
+
+ bool operator<(Date_t other) const {
+ return toDurationSinceEpoch() < other.toDurationSinceEpoch();
+ }
+
+ bool operator>(Date_t other) const {
+ return toDurationSinceEpoch() > other.toDurationSinceEpoch();
+ }
+
+ bool operator<=(Date_t other) const {
+ return !(*this > other);
+ }
+
+ bool operator>=(Date_t other) const {
+ return !(*this < other);
+ }
+
+ private:
+ Date_t(long long m): millis(m) {}
+
+ long long millis;
};
// uses ISO 8601 dates without trailing Z
diff --git a/src/mongo/util/time_support_test.cpp b/src/mongo/util/time_support_test.cpp
index 0580584c62e..dc367e61647 100644
--- a/src/mongo/util/time_support_test.cpp
+++ b/src/mongo/util/time_support_test.cpp
@@ -813,5 +813,15 @@ namespace {
}
}
+ TEST(TimeFormatting, DurationFormatting) {
+ ASSERT_EQUALS("52\xce\xbcs", static_cast<std::string>(str::stream() << Microseconds(52)));
+ ASSERT_EQUALS("52ms", static_cast<std::string>(str::stream() << Milliseconds(52)));
+ ASSERT_EQUALS("52s", static_cast<std::string>(str::stream() << Seconds(52)));
+
+ std::ostringstream os;
+ os << Milliseconds(52) << Microseconds(52) << Seconds(52);
+ ASSERT_EQUALS("52ms52\xce\xbcs52s", os.str());
+ }
+
} // namespace
} // namespace mongo