1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one
3  * or more contributor license agreements. See the NOTICE file
4  * distributed with this work for additional information
5  * regarding copyright ownership. The ASF licenses this file
6  * to you under the Apache License, Version 2.0 (the
7  * "License"); you may not use this file except in compliance
8  * with the License. You may obtain a copy of the License at
9  *
10  *   http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing,
13  * software distributed under the License is distributed on an
14  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15  * KIND, either express or implied. See the License for the
16  * specific language governing permissions and limitations
17  * under the License.
18  */
19 
20 #include <thrift/windows/GetTimeOfDay.h>
21 #include <thrift/thrift-config.h>
22 
23 // win32
24 #if defined(__MINGW32__)
25   #include <sys/time.h>
26 #endif
27 
28 #if !defined(__MINGW32__)
29 struct timezone {
30   int tz_minuteswest; /* minutes W of Greenwich */
31   int tz_dsttime;     /* type of dst correction */
32 };
33 #endif
34 
35 #if defined(__MINGW32__)
thrift_gettimeofday(struct timeval * tv,struct timezone * tz)36 int thrift_gettimeofday(struct timeval* tv, struct timezone* tz) {
37   return gettimeofday(tv,tz);
38 }
39 #else
40 #define WIN32_LEAN_AND_MEAN
41 #include <winsock2.h>
42 #include <cstdint>
43 #include <sstream>
44 #include <thrift/transport/TTransportException.h>
45 
46 // This code started from a "FREE implementation" posted to Stack Overflow at:
47 // https://stackoverflow.com/questions/10905892/equivalent-of-gettimeday-for-windows
48 // added: assert
49 // added: error handling
50 // added: C++ style casts
thrift_gettimeofday(struct timeval * tp,struct timezone * tzp)51 int thrift_gettimeofday(struct timeval * tp, struct timezone * tzp)
52 {
53     // We don't fill it in so prove nobody is looking for the data
54     assert(tzp == nullptr);
55 
56     // Note: some broken versions only have 8 trailing zero's, the correct epoch has 9 trailing zero's
57     // This magic number is the number of 100 nanosecond intervals since January 1, 1601 (UTC)
58     // until 00:00:00 January 1, 1970
59     static const uint64_t EPOCH = static_cast<uint64_t>(116444736000000000ULL);
60 
61     SYSTEMTIME  system_time;
62     FILETIME    file_time;
63     uint64_t    time;
64 
65     GetSystemTime( &system_time );
66     if (!SystemTimeToFileTime( &system_time, &file_time )) {
67       DWORD lastError = GetLastError();
68       std::stringstream ss;
69       ss << "SystemTimeToFileTime failed: 0x" << std::hex << lastError;
70       using apache::thrift::transport::TTransportException;
71       throw TTransportException(TTransportException::INTERNAL_ERROR, ss.str());
72     }
73     time =  static_cast<uint64_t>(file_time.dwLowDateTime )      ;
74     time += static_cast<uint64_t>(file_time.dwHighDateTime) << 32;
75 
76     tp->tv_sec  = static_cast<long>((time - EPOCH) / 10000000L);
77     tp->tv_usec = static_cast<long>(system_time.wMilliseconds * 1000);
78     return 0;
79 }
80 #endif
81 
thrift_sleep(unsigned int seconds)82 int thrift_sleep(unsigned int seconds) {
83   ::Sleep(seconds * 1000);
84   return 0;
85 }
thrift_usleep(unsigned int microseconds)86 int thrift_usleep(unsigned int microseconds) {
87   unsigned int milliseconds = (microseconds + 999) / 1000;
88   ::Sleep(milliseconds);
89   return 0;
90 }
91 
thrift_ctime_r(const time_t * _clock,char * _buf)92 char* thrift_ctime_r(const time_t* _clock, char* _buf) {
93   strcpy(_buf, ctime(_clock));
94   return _buf;
95 }
96