Skip to content

Commit 7cf9cdc

Browse files
committed
Win32 fixes + US-EAST-1 fix
* Include port.h instead of port_posix.h * Undefine Win32 API to allow method overloads * Fix port_win.cc mutex and condition variable * Implement Win32 version of gettid * US-EAST-1 requires special handling at bucket creation
1 parent b2ad4ae commit 7cf9cdc

File tree

9 files changed

+131
-97
lines changed

9 files changed

+131
-97
lines changed

cloud/aws/aws_env.cc

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@
22
//
33
#include "cloud/aws/aws_env.h"
44

5-
#include <unistd.h>
6-
75
#include <chrono>
86
#include <cinttypes>
97
#include <fstream>
@@ -14,7 +12,7 @@
1412
#include "cloud/cloud_log_controller_impl.h"
1513
#include "cloud/cloud_storage_provider_impl.h"
1614
#include "cloud/filename.h"
17-
#include "port/port_posix.h"
15+
#include "port/port.h"
1816
#include "rocksdb/cloud/cloud_log_controller.h"
1917
#include "rocksdb/cloud/cloud_storage_provider.h"
2018
#include "rocksdb/env.h"
@@ -30,6 +28,10 @@
3028
#include "cloud/aws/aws_file.h"
3129
#include "cloud/db_cloud_impl.h"
3230

31+
#ifdef _WIN32_WINNT
32+
#undef GetObject
33+
#endif
34+
3335
namespace rocksdb {
3436

3537
static const std::unordered_map<std::string, AwsAccessType> AwsAccessTypeMap = {
@@ -119,8 +121,8 @@ Status AwsCloudAccessCredentials::GetCredentialsProvider(
119121
AwsAccessType aws_type = GetAccessType();
120122
Status status = CheckCredentials(aws_type);
121123
if (status.ok()) {
122-
switch (aws_type) {
123124
#ifdef USE_AWS
125+
switch (aws_type) {
124126
case AwsAccessType::kSimple: {
125127
const char* access_key =
126128
(access_key_id.empty() ? getenv("AWS_ACCESS_KEY_ID")
@@ -154,11 +156,13 @@ Status AwsCloudAccessCredentials::GetCredentialsProvider(
154156
// Use AWS SDK's default credential chain
155157
result->reset();
156158
break;
157-
#endif
158159
default:
159160
status = Status::NotSupported("AWS credentials type not supported");
160161
break; // not supported
161162
}
163+
#else
164+
status = Status::NotSupported("AWS credentials type not supported");
165+
#endif
162166
}
163167
return status;
164168
}
@@ -1257,6 +1261,16 @@ Status AwsEnv::NewAwsEnv(Env* base_env,
12571261
return status;
12581262
}
12591263

1264+
uint64_t AwsEnv::gettid() {
1265+
#ifdef _WIN32_WINNT
1266+
return static_cast<uint64_t>(::GetCurrentThreadId());
1267+
#else
1268+
static_assert(sizeof(pthread_t) <= sizeof(uint64_t),
1269+
"pthread_t is expected to be smaller or equal than 64-bit");
1270+
return static_cast<uint64_t>(pthread_self());
1271+
#endif
1272+
}
1273+
12601274
std::string AwsEnv::GetWALCacheDir() {
12611275
return cloud_env_options.cloud_log_controller->GetCacheDir();
12621276
}

cloud/aws/aws_env.h

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414

1515
#ifdef USE_AWS
1616

17+
#include <string.h>
18+
1719
#include <chrono>
1820
#include <list>
1921
#include <unordered_map>
@@ -186,10 +188,7 @@ class AwsEnv : public CloudEnvImpl {
186188
return base_env_->TimeToString(number);
187189
}
188190

189-
static uint64_t gettid() {
190-
assert(sizeof(pthread_t) <= sizeof(uint64_t));
191-
return (uint64_t)pthread_self();
192-
}
191+
static uint64_t gettid();
193192

194193
virtual uint64_t GetThreadID() const override { return AwsEnv::gettid(); }
195194

cloud/aws/aws_s3.cc

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,13 +44,18 @@
4444
#include "cloud/aws/aws_file.h"
4545
#include "cloud/cloud_storage_provider_impl.h"
4646
#include "cloud/filename.h"
47-
#include "port/port_posix.h"
47+
#include "port/port.h"
4848
#include "rocksdb/cloud/cloud_env_options.h"
4949
#include "rocksdb/cloud/cloud_storage_provider.h"
5050
#include "rocksdb/options.h"
5151
#include "util/stderr_logger.h"
5252
#include "util/string_util.h"
5353

54+
#ifdef _WIN32_WINNT
55+
#undef GetObject
56+
#undef GetMessage
57+
#endif
58+
5459
namespace rocksdb {
5560
#ifdef USE_AWS
5661
class CloudRequestCallbackGuard {
@@ -459,7 +464,11 @@ Status S3StorageProvider::CreateBucket(const std::string& bucket) {
459464
Aws::S3::Model::BucketLocationConstraint bucket_location = Aws::S3::Model::
460465
BucketLocationConstraintMapper::GetBucketLocationConstraintForName(
461466
ToAwsString(env_->GetCloudEnvOptions().dest_bucket.GetRegion()));
462-
if (bucket_location != Aws::S3::Model::BucketLocationConstraint::NOT_SET) {
467+
// to create a bucket in US-EAST-1 you must specify no constraint location for
468+
// legacy reasons
469+
if ((bucket_location != Aws::S3::Model::BucketLocationConstraint::NOT_SET) &&
470+
(bucket_location !=
471+
Aws::S3::Model::BucketLocationConstraint::us_east_1)) {
463472
// only set the location constraint if it's not not set
464473
conf.SetLocationConstraint(bucket_location);
465474
}

cloud/cloud_env.cc

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
// Copyright (c) 2017 Rockset.
22
#ifndef ROCKSDB_LITE
33

4+
#ifndef _WIN32_WINNT
45
#include <unistd.h>
6+
#else
7+
#include <windows.h>
8+
#endif
59

610
#include "cloud/aws/aws_env.h"
711
#include "cloud/cloud_env_impl.h"
@@ -67,7 +71,19 @@ void BucketOptions::TEST_Initialize(const std::string& bucket,
6771
if (!CloudEnvOptions::GetNameFromEnvironment("ROCKSDB_CLOUD_TEST_BUCKET_NAME",
6872
"ROCKSDB_CLOUD_BUCKET_NAME",
6973
&bucket_)) {
74+
#ifdef _MSC_VER
75+
char user_name[257]; // UNLEN + 1
76+
DWORD dwsize = sizeof(user_name);
77+
if (!::GetUserName(user_name, &dwsize)) {
78+
bucket_ = bucket_ + "unknown";
79+
} else {
80+
bucket_ =
81+
bucket_ +
82+
std::string(user_name, static_cast<std::string::size_type>(dwsize));
83+
}
84+
#else
7085
bucket_ = bucket + std::to_string(geteuid());
86+
#endif
7187
}
7288
if (CloudEnvOptions::GetNameFromEnvironment(
7389
"ROCKSDB_CLOUD_TEST_BUCKET_PREFIX", "ROCKSDB_CLOUD_BUCKET_PREFIX",

cloud/cloud_env_impl.cc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@
1919
#include "util/file_reader_writer.h"
2020
#include "util/xxhash.h"
2121

22+
#ifdef _MSC_VER
23+
#undef GetObject
24+
#endif
25+
2226
namespace rocksdb {
2327

2428
CloudEnvImpl::CloudEnvImpl(const CloudEnvOptions& opts, Env* base,

cloud/cloud_storage_provider.cc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@
1919
#include "util/stderr_logger.h"
2020
#include "util/string_util.h"
2121

22+
#ifdef _MSC_VER
23+
#undef GetObject
24+
#endif
25+
2226
namespace rocksdb {
2327

2428
/******************** Readablefile ******************/

port/win/port_win.cc

Lines changed: 61 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -13,24 +13,24 @@
1313

1414
#include "port/win/port_win.h"
1515

16+
#include <assert.h>
1617
#include <io.h>
17-
#include "port/port_dirent.h"
18-
#include "port/sys_time.h"
19-
20-
#include <cstdlib>
2118
#include <stdio.h>
22-
#include <assert.h>
2319
#include <string.h>
2420

25-
#include <memory>
26-
#include <exception>
2721
#include <chrono>
22+
#include <cstdlib>
23+
#include <exception>
24+
#include <memory>
25+
26+
#include "port/port_dirent.h"
27+
#include "port/sys_time.h"
2828

2929
#ifdef ROCKSDB_WINDOWS_UTF8_FILENAMES
3030
// utf8 <-> utf16
31-
#include <string>
32-
#include <locale>
3331
#include <codecvt>
32+
#include <locale>
33+
#include <string>
3434
#endif
3535

3636
#include "logging/logging.h"
@@ -43,7 +43,7 @@ namespace port {
4343

4444
#ifdef ROCKSDB_WINDOWS_UTF8_FILENAMES
4545
std::string utf16_to_utf8(const std::wstring& utf16) {
46-
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>,wchar_t> convert;
46+
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>, wchar_t> convert;
4747
return convert.to_bytes(utf16);
4848
}
4949

@@ -63,64 +63,77 @@ void gettimeofday(struct timeval* tv, struct timezone* /* tz */) {
6363

6464
tv->tv_sec = static_cast<long>(secNow.count());
6565
tv->tv_usec = static_cast<long>(usNow.count() -
66-
duration_cast<microseconds>(secNow).count());
66+
duration_cast<microseconds>(secNow).count());
67+
}
68+
69+
Mutex::Mutex(bool adaptive) { ::InitializeCriticalSection(&section_); }
70+
71+
Mutex::~Mutex() { ::DeleteCriticalSection(&section_); }
72+
73+
void Mutex::Lock() {
74+
::EnterCriticalSection(&section_);
75+
#ifndef NDEBUG
76+
locked_ = true;
77+
#endif
78+
}
79+
80+
void Mutex::Unlock() {
81+
#ifndef NDEBUG
82+
locked_ = false;
83+
#endif
84+
::LeaveCriticalSection(&section_);
85+
}
86+
87+
void Mutex::AssertHeld() {
88+
#ifndef NDEBUG
89+
assert(locked_);
90+
#endif
6791
}
6892

69-
Mutex::~Mutex() {}
93+
CondVar::CondVar(Mutex* mu) : mu_(mu) { ::InitializeConditionVariable(&cv_); }
7094

7195
CondVar::~CondVar() {}
7296

7397
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);
7698
#ifndef NDEBUG
7799
mu_->locked_ = false;
78100
#endif
79-
cv_.wait(lk);
101+
::SleepConditionVariableCS(&cv_, &(mu_->section_), INFINITE);
80102
#ifndef NDEBUG
81103
mu_->locked_ = true;
82104
#endif
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)
85-
lk.release();
86105
}
87106

88107
bool CondVar::TimedWait(uint64_t abs_time_us) {
89-
90108
using namespace std::chrono;
91109

92110
// MSVC++ library implements wait_until in terms of wait_for so
93111
// we need to convert absolute wait into relative wait.
94112
microseconds usAbsTime(abs_time_us);
95113

96114
microseconds usNow(
97-
duration_cast<microseconds>(system_clock::now().time_since_epoch()));
115+
duration_cast<microseconds>(system_clock::now().time_since_epoch()));
98116
microseconds relTimeUs =
99-
(usAbsTime > usNow) ? (usAbsTime - usNow) : microseconds::zero();
117+
(usAbsTime > usNow) ? (usAbsTime - usNow) : microseconds::zero();
118+
119+
const BOOL cvStatus = ::SleepConditionVariableCS(
120+
&cv_, &(mu_->section_),
121+
static_cast<DWORD>(duration_cast<milliseconds>(relTimeUs).count()));
100122

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);
103-
#ifndef NDEBUG
104-
mu_->locked_ = false;
105-
#endif
106-
std::cv_status cvStatus = cv_.wait_for(lk, relTimeUs);
107123
#ifndef NDEBUG
108124
mu_->locked_ = true;
109125
#endif
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)
112-
lk.release();
113126

114-
if (cvStatus == std::cv_status::timeout) {
127+
if ((!cvStatus) && (GetLastError() == ERROR_TIMEOUT)) {
115128
return true;
116129
}
117130

118131
return false;
119132
}
120133

121-
void CondVar::Signal() { cv_.notify_one(); }
134+
void CondVar::Signal() { ::WakeConditionVariable(&cv_); }
122135

123-
void CondVar::SignalAll() { cv_.notify_all(); }
136+
void CondVar::SignalAll() { WakeAllConditionVariable(&cv_); }
124137

125138
int PhysicalCoreID() { return GetCurrentProcessorNumber(); }
126139

@@ -130,13 +143,12 @@ void InitOnce(OnceType* once, void (*initializer)()) {
130143

131144
// Private structure, exposed only by pointer
132145
struct DIR {
133-
HANDLE handle_;
134-
bool firstread_;
146+
HANDLE handle_;
147+
bool firstread_;
135148
RX_WIN32_FIND_DATA data_;
136149
dirent entry_;
137150

138-
DIR() : handle_(INVALID_HANDLE_VALUE),
139-
firstread_(true) {}
151+
DIR() : handle_(INVALID_HANDLE_VALUE), firstread_(true) {}
140152

141153
DIR(const DIR&) = delete;
142154
DIR& operator=(const DIR&) = delete;
@@ -159,20 +171,19 @@ DIR* opendir(const char* name) {
159171

160172
std::unique_ptr<DIR> dir(new DIR);
161173

162-
dir->handle_ = RX_FindFirstFileEx(RX_FN(pattern).c_str(),
163-
FindExInfoBasic, // Do not want alternative name
164-
&dir->data_,
165-
FindExSearchNameMatch,
166-
NULL, // lpSearchFilter
167-
0);
174+
dir->handle_ =
175+
RX_FindFirstFileEx(RX_FN(pattern).c_str(),
176+
FindExInfoBasic, // Do not want alternative name
177+
&dir->data_, FindExSearchNameMatch,
178+
NULL, // lpSearchFilter
179+
0);
168180

169181
if (dir->handle_ == INVALID_HANDLE_VALUE) {
170182
return nullptr;
171183
}
172184

173185
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());
186+
strcpy_s(dir->entry_.d_name, sizeof(dir->entry_.d_name), FN_TO_RX(x).c_str());
176187

177188
return dir.release();
178189
}
@@ -195,7 +206,7 @@ struct dirent* readdir(DIR* dirp) {
195206
}
196207

197208
RX_FILESTRING x(dirp->data_.cFileName, RX_FNLEN(dirp->data_.cFileName));
198-
strcpy_s(dirp->entry_.d_name, sizeof(dirp->entry_.d_name),
209+
strcpy_s(dirp->entry_.d_name, sizeof(dirp->entry_.d_name),
199210
FN_TO_RX(x).c_str());
200211

201212
return &dirp->entry_;
@@ -215,18 +226,17 @@ int truncate(const char* path, int64_t length) {
215226
}
216227

217228
int Truncate(std::string path, int64_t len) {
218-
219229
if (len < 0) {
220230
errno = EINVAL;
221231
return -1;
222232
}
223233

224234
HANDLE hFile =
225235
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);
236+
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
237+
NULL, // Security attrs
238+
OPEN_EXISTING, // Truncate existing file only
239+
FILE_ATTRIBUTE_NORMAL, NULL);
230240

231241
if (INVALID_HANDLE_VALUE == hFile) {
232242
auto lastError = GetLastError();

0 commit comments

Comments
 (0)