1 // Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
2 // This source code is licensed under both the GPLv2 (found in the
3 // COPYING file in the root directory) and Apache 2.0 License
4 // (found in the LICENSE.Apache file in the root directory).
6 // Copyright (c) 2011 The LevelDB Authors. All rights reserved.
7 // Use of this source code is governed by a BSD-style license that can be
8 // found in the LICENSE file. See the AUTHORS file for names of contributors.
10 #if !defined(OS_WIN) && !defined(WIN32) && !defined(_WIN32)
11 #error Windows Specific Code
14 #include "port/win/port_win.h"
17 #include "port/port_dirent.h"
18 #include "port/sys_time.h"
29 #ifdef ROCKSDB_WINDOWS_UTF8_FILENAMES
36 #include "util/logging.h"
40 extern const bool kDefaultToAdaptiveMutex
= false;
44 #ifdef ROCKSDB_WINDOWS_UTF8_FILENAMES
45 std::string
utf16_to_utf8(const std::wstring
& utf16
) {
46 std::wstring_convert
<std::codecvt_utf8_utf16
<wchar_t>,wchar_t> convert
;
47 return convert
.to_bytes(utf16
);
50 std::wstring
utf8_to_utf16(const std::string
& utf8
) {
51 std::wstring_convert
<std::codecvt_utf8_utf16
<wchar_t>> converter
;
52 return converter
.from_bytes(utf8
);
56 void gettimeofday(struct timeval
* tv
, struct timezone
* /* tz */) {
57 using namespace std::chrono
;
60 duration_cast
<microseconds
>(system_clock::now().time_since_epoch()));
62 seconds
secNow(duration_cast
<seconds
>(usNow
));
64 tv
->tv_sec
= static_cast<long>(secNow
.count());
65 tv
->tv_usec
= static_cast<long>(usNow
.count() -
66 duration_cast
<microseconds
>(secNow
).count());
71 CondVar::~CondVar() {}
73 void CondVar::Wait() {
74 // Caller must ensure that mutex is held prior to calling this method
75 std::unique_lock
<std::mutex
> lk(mu_
->getLock(), std::adopt_lock
);
83 // Release ownership of the lock as we don't want it to be unlocked when
84 // it goes out of scope (as we adopted the lock and didn't lock it ourselves)
88 bool CondVar::TimedWait(uint64_t abs_time_us
) {
90 using namespace std::chrono
;
92 // MSVC++ library implements wait_until in terms of wait_for so
93 // we need to convert absolute wait into relative wait.
94 microseconds
usAbsTime(abs_time_us
);
97 duration_cast
<microseconds
>(system_clock::now().time_since_epoch()));
98 microseconds relTimeUs
=
99 (usAbsTime
> usNow
) ? (usAbsTime
- usNow
) : microseconds::zero();
101 // Caller must ensure that mutex is held prior to calling this method
102 std::unique_lock
<std::mutex
> lk(mu_
->getLock(), std::adopt_lock
);
104 mu_
->locked_
= false;
106 std::cv_status cvStatus
= cv_
.wait_for(lk
, relTimeUs
);
110 // Release ownership of the lock as we don't want it to be unlocked when
111 // it goes out of scope (as we adopted the lock and didn't lock it ourselves)
114 if (cvStatus
== std::cv_status::timeout
) {
121 void CondVar::Signal() { cv_
.notify_one(); }
123 void CondVar::SignalAll() { cv_
.notify_all(); }
125 int PhysicalCoreID() { return GetCurrentProcessorNumber(); }
127 void InitOnce(OnceType
* once
, void (*initializer
)()) {
128 std::call_once(once
->flag_
, initializer
);
131 // Private structure, exposed only by pointer
135 RX_WIN32_FIND_DATA data_
;
138 DIR() : handle_(INVALID_HANDLE_VALUE
),
141 DIR(const DIR&) = delete;
142 DIR& operator=(const DIR&) = delete;
145 if (INVALID_HANDLE_VALUE
!= handle_
) {
146 ::FindClose(handle_
);
151 DIR* opendir(const char* name
) {
152 if (!name
|| *name
== 0) {
157 std::string
pattern(name
);
158 pattern
.append("\\").append("*");
160 std::unique_ptr
<DIR> dir(new DIR);
162 dir
->handle_
= RX_FindFirstFileEx(RX_FN(pattern
).c_str(),
163 FindExInfoBasic
, // Do not want alternative name
165 FindExSearchNameMatch
,
166 NULL
, // lpSearchFilter
169 if (dir
->handle_
== INVALID_HANDLE_VALUE
) {
173 RX_FILESTRING
x(dir
->data_
.cFileName
, RX_FNLEN(dir
->data_
.cFileName
));
174 strcpy_s(dir
->entry_
.d_name
, sizeof(dir
->entry_
.d_name
),
175 FN_TO_RX(x
).c_str());
177 return dir
.release();
180 struct dirent
* readdir(DIR* dirp
) {
181 if (!dirp
|| dirp
->handle_
== INVALID_HANDLE_VALUE
) {
186 if (dirp
->firstread_
) {
187 dirp
->firstread_
= false;
188 return &dirp
->entry_
;
191 auto ret
= RX_FindNextFile(dirp
->handle_
, &dirp
->data_
);
197 RX_FILESTRING
x(dirp
->data_
.cFileName
, RX_FNLEN(dirp
->data_
.cFileName
));
198 strcpy_s(dirp
->entry_
.d_name
, sizeof(dirp
->entry_
.d_name
),
199 FN_TO_RX(x
).c_str());
201 return &dirp
->entry_
;
204 int closedir(DIR* dirp
) {
209 int truncate(const char* path
, int64_t length
) {
210 if (path
== nullptr) {
214 return rocksdb::port::Truncate(path
, length
);
217 int Truncate(std::string path
, int64_t len
) {
225 RX_CreateFile(RX_FN(path
).c_str(), GENERIC_READ
| GENERIC_WRITE
,
226 FILE_SHARE_READ
| FILE_SHARE_WRITE
| FILE_SHARE_DELETE
,
227 NULL
, // Security attrs
228 OPEN_EXISTING
, // Truncate existing file only
229 FILE_ATTRIBUTE_NORMAL
, NULL
);
231 if (INVALID_HANDLE_VALUE
== hFile
) {
232 auto lastError
= GetLastError();
233 if (lastError
== ERROR_FILE_NOT_FOUND
) {
235 } else if (lastError
== ERROR_ACCESS_DENIED
) {
244 FILE_END_OF_FILE_INFO end_of_file
;
245 end_of_file
.EndOfFile
.QuadPart
= len
;
247 if (!SetFileInformationByHandle(hFile
, FileEndOfFileInfo
, &end_of_file
,
248 sizeof(FILE_END_OF_FILE_INFO
))) {
257 void Crash(const std::string
& srcfile
, int srcline
) {
258 fprintf(stdout
, "Crashing at %s:%d\n", srcfile
.c_str(), srcline
);
263 int GetMaxOpenFiles() { return -1; }
266 } // namespace rocksdb