File indexing completed on 2025-06-30 08:17:12
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #ifndef BOOST_INTERPROCESS_DETAIL_TIMED_UTILS_HPP
0014 #define BOOST_INTERPROCESS_DETAIL_TIMED_UTILS_HPP
0015
0016 #ifndef BOOST_CONFIG_HPP
0017 # include <boost/config.hpp>
0018 #endif
0019 #
0020 #if defined(BOOST_HAS_PRAGMA_ONCE)
0021 # pragma once
0022 #endif
0023
0024 #include <boost/interprocess/detail/config_begin.hpp>
0025 #include <boost/interprocess/detail/workaround.hpp>
0026 #include <boost/interprocess/detail/mpl.hpp>
0027 #include <boost/interprocess/detail/type_traits.hpp>
0028 #include <boost/intrusive/detail/mpl.hpp>
0029
0030 #include <ctime>
0031 #include <boost/cstdint.hpp>
0032
0033
0034 #ifdef BOOST_HAS_GETTIMEOFDAY
0035 #include <sys/time.h>
0036 #endif
0037
0038 #ifdef BOOST_HAS_FTIME
0039 #include <time.h>
0040 #include <boost/winapi/time.hpp>
0041 #endif
0042
0043 namespace boost {
0044 namespace interprocess {
0045
0046 class ustime;
0047 class usduration;
0048
0049 namespace ipcdetail {
0050
0051 BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(time_duration_type)
0052 BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(clock)
0053 BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(rep_type)
0054 BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(rep)
0055
0056 template<class T>
0057 struct enable_if_ptime
0058 : enable_if_c< BOOST_INTRUSIVE_HAS_TYPE(boost::interprocess::ipcdetail::, T, time_duration_type) >
0059 {};
0060
0061 template<class T>
0062 struct disable_if_ptime
0063 : enable_if_c< ! BOOST_INTRUSIVE_HAS_TYPE(boost::interprocess::ipcdetail::, T, time_duration_type) >
0064 {};
0065
0066 template<class T>
0067 struct enable_if_ptime_duration
0068 : enable_if_c< BOOST_INTRUSIVE_HAS_TYPE(boost::interprocess::ipcdetail::, T, rep_type) >
0069 {};
0070
0071 template<class T>
0072 struct enable_if_time_point
0073 : enable_if_c< BOOST_INTRUSIVE_HAS_TYPE(boost::interprocess::ipcdetail::, T, clock) >
0074 {};
0075
0076 template<class T>
0077 struct enable_if_duration
0078 : enable_if_c< BOOST_INTRUSIVE_HAS_TYPE(boost::interprocess::ipcdetail::, T, rep) >
0079 {};
0080
0081 template<class T>
0082 struct enable_if_ustime
0083 : enable_if_c< is_same<T, ustime>::value >
0084 {};
0085
0086 template<class T>
0087 struct enable_if_usduration
0088 : enable_if_c< is_same<T, usduration>::value >
0089 {};
0090
0091 #if defined(BOOST_INTERPROCESS_HAS_REENTRANT_STD_FUNCTIONS)
0092
0093 inline std::tm* interprocess_gmtime(const std::time_t* t, std::tm* result)
0094 {
0095
0096 #if defined(__VMS) && __INITIAL_POINTER_SIZE == 64
0097 std::tm tmp;
0098 if(!gmtime_r(t,&tmp))
0099 result = 0;
0100 else
0101 *result = tmp;
0102 #else
0103 result = gmtime_r(t, result);
0104 #endif
0105 return result;
0106 }
0107
0108 #else
0109
0110 #if defined(__clang__)
0111 # pragma clang diagnostic push
0112 # pragma clang diagnostic ignored "-Wdeprecated-declarations"
0113 #elif (defined(_MSC_VER) && (_MSC_VER >= 1400))
0114 # pragma warning(push)
0115 # pragma warning(disable : 4996)
0116 #endif
0117
0118 inline std::tm* interprocess_gmtime(const std::time_t* t, std::tm* result)
0119 {
0120 result = std::gmtime(t);
0121 return result;
0122 }
0123
0124 #if defined(__clang__)
0125 # pragma clang diagnostic pop
0126 #elif (defined(_MSC_VER) && (_MSC_VER >= 1400))
0127 # pragma warning(pop)
0128 #endif
0129
0130 #endif
0131
0132 #if defined(BOOST_HAS_FTIME)
0133
0134
0135
0136
0137
0138 inline boost::uint64_t file_time_to_microseconds(const boost::winapi::FILETIME_ & ft)
0139 {
0140
0141
0142 const boost::uint64_t shift = 116444736000000000ULL;
0143
0144
0145 boost::uint64_t ft_as_integer = (static_cast< boost::uint64_t >(ft.dwHighDateTime) << 32) | static_cast< boost::uint64_t >(ft.dwLowDateTime);
0146
0147 ft_as_integer -= shift;
0148 return (ft_as_integer / 10U);
0149 }
0150 #endif
0151
0152 inline boost::uint64_t universal_time_u64_us()
0153 {
0154 #ifdef BOOST_HAS_GETTIMEOFDAY
0155 timeval tv;
0156 gettimeofday(&tv, 0);
0157 boost::uint64_t micros = boost::uint64_t(tv.tv_sec)*1000000u;
0158 micros += (boost::uint64_t)tv.tv_usec;
0159 #elif defined(BOOST_HAS_FTIME)
0160 boost::winapi::FILETIME_ ft;
0161 boost::winapi::GetSystemTimeAsFileTime(&ft);
0162 boost::uint64_t micros = file_time_to_microseconds(ft);
0163
0164 #else
0165 #error "Unsupported date-time error: neither gettimeofday nor FILETIME support is detected"
0166 #endif
0167 return micros;
0168 }
0169
0170
0171 template<class TimeType, class Enable = void>
0172 class microsec_clock;
0173
0174 template<class TimeType>
0175 class microsec_clock<TimeType, typename enable_if_ptime<TimeType>::type>
0176 {
0177 private:
0178 typedef typename TimeType::date_type date_type;
0179 typedef typename TimeType::time_duration_type time_duration_type;
0180 typedef typename time_duration_type::rep_type resolution_traits_type;
0181
0182 public:
0183 typedef TimeType time_point;
0184
0185 static time_point universal_time()
0186 {
0187 #ifdef BOOST_HAS_GETTIMEOFDAY
0188 timeval tv;
0189 gettimeofday(&tv, 0);
0190 std::time_t t = tv.tv_sec;
0191 boost::uint32_t sub_sec = static_cast<boost::uint32_t>(tv.tv_usec);
0192 #elif defined(BOOST_HAS_FTIME)
0193 boost::winapi::FILETIME_ ft;
0194 boost::winapi::GetSystemTimeAsFileTime(&ft);
0195 boost::uint64_t micros = file_time_to_microseconds(ft);
0196
0197 std::time_t t = static_cast<std::time_t>(micros / 1000000UL);
0198
0199 boost::uint32_t sub_sec = static_cast<boost::uint32_t>(micros % 1000000UL);
0200 #else
0201 #error "Unsupported date-time error: neither gettimeofday nor FILETIME support is detected"
0202 #endif
0203
0204 std::tm curr;
0205 std::tm* curr_ptr = interprocess_gmtime(&t, &curr);
0206 date_type d(static_cast< typename date_type::year_type::value_type >(curr_ptr->tm_year + 1900),
0207 static_cast< typename date_type::month_type::value_type >(curr_ptr->tm_mon + 1),
0208 static_cast< typename date_type::day_type::value_type >(curr_ptr->tm_mday));
0209
0210
0211
0212
0213
0214 unsigned adjust = static_cast< unsigned >(resolution_traits_type::res_adjust() / 1000000);
0215
0216 time_duration_type td(static_cast< typename time_duration_type::hour_type >(curr_ptr->tm_hour),
0217 static_cast< typename time_duration_type::min_type >(curr_ptr->tm_min),
0218 static_cast< typename time_duration_type::sec_type >(curr_ptr->tm_sec),
0219 static_cast< typename time_duration_type::fractional_seconds_type >(sub_sec * adjust)
0220 );
0221 return time_point(d,td);
0222 }
0223 };
0224
0225 template<class TimePoint>
0226 class microsec_clock<TimePoint, typename enable_if_time_point<TimePoint>::type>
0227 {
0228 public:
0229 typedef typename TimePoint::clock::time_point time_point;
0230
0231 static time_point universal_time()
0232 { return TimePoint::clock::now(); }
0233 };
0234
0235
0236 template<class TimePoint>
0237 inline bool is_pos_infinity(const TimePoint &abs_time, typename enable_if_ptime<TimePoint>::type* = 0)
0238 {
0239 return abs_time.is_pos_infinity();
0240 }
0241
0242 template<class TimePoint>
0243 inline bool is_pos_infinity(const TimePoint &, typename disable_if_ptime<TimePoint>::type* = 0)
0244 {
0245 return false;
0246 }
0247
0248
0249
0250 template<class Duration>
0251 inline boost::uint64_t duration_to_milliseconds(const Duration &abs_time, typename enable_if_ptime_duration<Duration>::type* = 0)
0252 {
0253 return static_cast<boost::uint64_t>(abs_time.total_milliseconds());
0254 }
0255
0256 template<class Duration>
0257 inline boost::uint64_t duration_to_milliseconds(const Duration &d, typename enable_if_duration<Duration>::type* = 0)
0258 {
0259 const double factor = double(Duration::period::num)*1000.0/double(Duration::period::den);
0260 return static_cast<boost::uint64_t>(double(d.count())*factor);
0261 }
0262
0263 template<class Duration>
0264 inline boost::uint64_t duration_to_milliseconds(const Duration&d, typename enable_if_usduration<Duration>::type* = 0)
0265 {
0266 return d.get_microsecs()/1000u;
0267 }
0268
0269 }
0270 }
0271 }
0272
0273 #include <boost/interprocess/detail/config_end.hpp>
0274
0275 #endif
0276