Permalink
Browse files

SERVER-28613: Fixed memory leak while fetching a timelib_time.

  • Loading branch information...
derickr committed Jun 30, 2017
1 parent 9fb03a7 commit fbcf295fff8fe1723120345126be90a49d7b6d14
Showing with 25 additions and 13 deletions.
  1. +17 −12 src/mongo/db/query/datetime/date_time_support.cpp
  2. +8 −1 src/mongo/db/query/datetime/date_time_support.h
@@ -231,31 +231,36 @@ void TimeZone::TimelibTZInfoDeleter::operator()(timelib_tzinfo* tzInfo) {
TimeZone::TimeZone(timelib_tzinfo* tzInfo) : _tzInfo(tzInfo, TimelibTZInfoDeleter()) {}
timelib_time TimeZone::getTimelibTime(Date_t date) const {
timelib_time time{};
void TimeZone::TimelibTimeDeleter::operator()(timelib_time* time) {
timelib_time_dtor(time);
}
std::unique_ptr<timelib_time, TimeZone::TimelibTimeDeleter> TimeZone::getTimelibTime(
Date_t date) const {
std::unique_ptr<timelib_time, TimeZone::TimelibTimeDeleter> time(timelib_time_ctor());
if (_tzInfo) {
timelib_set_timezone(&time, _tzInfo.get());
timelib_unixtime2local(&time, seconds(date));
timelib_set_timezone(time.get(), _tzInfo.get());
timelib_unixtime2local(time.get(), seconds(date));
} else {
timelib_unixtime2gmt(&time, seconds(date));
timelib_unixtime2gmt(time.get(), seconds(date));
}
return time;
}
TimeZone::Iso8601DateParts TimeZone::dateIso8601Parts(Date_t date) const {
auto time = getTimelibTime(date);
return Iso8601DateParts(time, date);
return Iso8601DateParts(*time, date);
}
TimeZone::DateParts TimeZone::dateParts(Date_t date) const {
auto time = getTimelibTime(date);
return DateParts(time, date);
return DateParts(*time, date);
}
int TimeZone::dayOfWeek(Date_t date) const {
auto time = getTimelibTime(date);
// timelib_day_of_week() returns a number in the range [0,6], we want [1,7], so add one.
return timelib_day_of_week(time.y, time.m, time.d) + 1;
return timelib_day_of_week(time->y, time->m, time->d) + 1;
}
int TimeZone::week(Date_t date) const {
@@ -274,27 +279,27 @@ int TimeZone::week(Date_t date) const {
int TimeZone::dayOfYear(Date_t date) const {
auto time = getTimelibTime(date);
// timelib_day_of_year() returns a number in the range [0,365], we want [1,366], so add one.
return timelib_day_of_year(time.y, time.m, time.d) + 1;
return timelib_day_of_year(time->y, time->m, time->d) + 1;
}
int TimeZone::isoDayOfWeek(Date_t date) const {
auto time = getTimelibTime(date);
return timelib_iso_day_of_week(time.y, time.m, time.d);
return timelib_iso_day_of_week(time->y, time->m, time->d);
}
int TimeZone::isoWeek(Date_t date) const {
auto time = getTimelibTime(date);
long long isoWeek;
long long isoYear;
timelib_isoweek_from_date(time.y, time.m, time.d, &isoWeek, &isoYear);
timelib_isoweek_from_date(time->y, time->m, time->d, &isoWeek, &isoYear);
return isoWeek;
}
long long TimeZone::isoYear(Date_t date) const {
auto time = getTimelibTime(date);
long long isoWeek;
long long isoYear;
timelib_isoweek_from_date(time.y, time.m, time.d, &isoWeek, &isoYear);
timelib_isoweek_from_date(time->y, time->m, time->d, &isoWeek, &isoYear);
return isoYear;
}
@@ -79,6 +79,13 @@ class TimeZone {
int millisecond;
};
/**
* A custom-deleter which destructs a timelib_time* when it goes out of scope.
*/
struct TimelibTimeDeleter {
TimelibTimeDeleter() = default;
void operator()(timelib_time* time);
};
explicit TimeZone(timelib_tzinfo* tzInfo);
TimeZone() = default;
@@ -230,7 +237,7 @@ class TimeZone {
static void validateFormat(StringData format);
private:
timelib_time getTimelibTime(Date_t) const;
std::unique_ptr<timelib_time, TimelibTimeDeleter> getTimelibTime(Date_t) const;
/**
* Only works with 1 <= spaces <= 4 and 0 <= number <= 9999. If spaces is less than the digit

0 comments on commit fbcf295

Please sign in to comment.