refactor(tvix/libutil): Mark single-argument constructors explicit

This is the clang-tidy lint 'google-explicit-constructor'.

There's a whole bunch of breakage that was introduced by this, and we
had to opt out a few types of this (esp. the string formatting crap).

In some cases minor other changes have been done to keep the code
working, instead of converting between types (e.g. an explicit
comparison operator implementation for nix::Pid).

Change-Id: I12e1ca51a6bc2c882dba81a2526b9729d26988e7
Reviewed-on: https://cl.tvl.fyi/c/depot/+/1832
Tested-by: BuildkiteCI
Reviewed-by: kanepyork <rikingcoding@gmail.com>
Reviewed-by: glittershark <grfn@gws.fyi>
This commit is contained in:
Vincent Ambo 2020-08-21 04:00:55 +01:00 committed by tazjin
parent 1443298657
commit 1cf11317ca
34 changed files with 309 additions and 272 deletions

View file

@ -80,13 +80,14 @@ void BinaryCacheStore::getFile(
void BinaryCacheStore::getFile(const std::string& path, Sink& sink) {
std::promise<std::shared_ptr<std::string>> promise;
getFile(path, {[&](std::future<std::shared_ptr<std::string>> result) {
try {
promise.set_value(result.get());
} catch (...) {
promise.set_exception(std::current_exception());
}
}});
getFile(path, Callback<std::shared_ptr<std::string>>{
[&](std::future<std::shared_ptr<std::string>> result) {
try {
promise.set_value(result.get());
} catch (...) {
promise.set_exception(std::current_exception());
}
}});
auto data = promise.get_future().get();
sink(reinterpret_cast<unsigned char*>(data->data()), data->size());
}
@ -280,23 +281,25 @@ void BinaryCacheStore::queryPathInfoUncached(
auto callbackPtr = std::make_shared<decltype(callback)>(std::move(callback));
getFile(narInfoFile, {[=](std::future<std::shared_ptr<std::string>> fut) {
try {
auto data = fut.get();
getFile(narInfoFile,
Callback<std::shared_ptr<std::string>>(
[=](std::future<std::shared_ptr<std::string>> fut) {
try {
auto data = fut.get();
if (!data) {
return (*callbackPtr)(nullptr);
}
if (!data) {
return (*callbackPtr)(nullptr);
}
stats.narInfoRead++;
stats.narInfoRead++;
(*callbackPtr)(std::shared_ptr<ValidPathInfo>(
std::make_shared<NarInfo>(*this, *data, narInfoFile)));
(*callbackPtr)(std::shared_ptr<ValidPathInfo>(
std::make_shared<NarInfo>(*this, *data, narInfoFile)));
} catch (...) {
callbackPtr->rethrow();
}
}});
} catch (...) {
callbackPtr->rethrow();
}
}));
}
Path BinaryCacheStore::addToStore(const std::string& name, const Path& srcPath,

View file

@ -574,8 +574,8 @@ UserLock::UserLock() {
}
try {
AutoCloseFD fd =
open(fnUserLock.c_str(), O_RDWR | O_CREAT | O_CLOEXEC, 0600);
AutoCloseFD fd(
open(fnUserLock.c_str(), O_RDWR | O_CREAT | O_CLOEXEC, 0600));
if (!fd) {
throw SysError(format("opening user lock '%1%'") % fnUserLock);
}
@ -698,8 +698,8 @@ HookInstance::HookInstance() {
});
pid.setSeparatePG(true);
fromHook.writeSide = -1;
toHook.readSide = -1;
fromHook.writeSide = AutoCloseFD(-1);
toHook.readSide = AutoCloseFD(-1);
sink = FdSink(toHook.writeSide.get());
std::map<std::string, Config::SettingInfo> settings;
@ -712,8 +712,8 @@ HookInstance::HookInstance() {
HookInstance::~HookInstance() {
try {
toHook.writeSide = -1;
if (pid != -1) {
toHook.writeSide = AutoCloseFD(-1);
if (pid != Pid(-1)) {
pid.kill();
}
} catch (...) {
@ -1056,7 +1056,7 @@ DerivationGoal::~DerivationGoal() {
inline bool DerivationGoal::needsHashRewrite() { return !useChroot; }
void DerivationGoal::killChild() {
if (pid != -1) {
if (pid != Pid(-1)) {
worker.childTerminated(this);
if (buildUser) {
@ -1066,14 +1066,14 @@ void DerivationGoal::killChild() {
it won't be killed, and we'll potentially lock up in
pid.wait(). So also send a conventional kill to the
child. */
::kill(-pid, SIGKILL); /* ignore the result */
::kill(-static_cast<pid_t>(pid), SIGKILL); /* ignore the result */
buildUser->kill();
pid.wait();
} else {
pid.kill();
}
assert(pid == -1);
assert(pid == Pid(-1));
}
hook.reset();
@ -1572,10 +1572,10 @@ void DerivationGoal::buildDone() {
/* Close the read side of the logger pipe. */
if (hook) {
hook->builderOut.readSide = -1;
hook->fromHook.readSide = -1;
hook->builderOut.readSide = AutoCloseFD(-1);
hook->fromHook.readSide = AutoCloseFD(-1);
} else {
builderOut.readSide = -1;
builderOut.readSide = AutoCloseFD(-1);
}
/* Close the log file. */
@ -1830,7 +1830,7 @@ HookReply DerivationGoal::tryBuildHook() {
hook->sink << missingPaths;
hook->sink = FdSink();
hook->toHook.writeSide = -1;
hook->toHook.writeSide = AutoCloseFD(-1);
/* Create the log file and pipe. */
Path logFile = openLogFile();
@ -2268,7 +2268,7 @@ void DerivationGoal::startBuilder() {
/* Create a pipe to get the output of the builder. */
// builderOut.create();
builderOut.readSide = posix_openpt(O_RDWR | O_NOCTTY);
builderOut.readSide = AutoCloseFD(posix_openpt(O_RDWR | O_NOCTTY));
if (!builderOut.readSide) {
throw SysError("opening pseudoterminal master");
}
@ -2300,7 +2300,8 @@ void DerivationGoal::startBuilder() {
throw SysError("unlocking pseudoterminal");
}
builderOut.writeSide = open(slaveName.c_str(), O_RDWR | O_NOCTTY);
builderOut.writeSide =
AutoCloseFD(open(slaveName.c_str(), O_RDWR | O_NOCTTY));
if (!builderOut.writeSide) {
throw SysError("opening pseudoterminal slave");
}
@ -2364,7 +2365,7 @@ void DerivationGoal::startBuilder() {
userNamespaceSync.create();
Pid helper = startProcess(
Pid helper(startProcess(
[&]() {
/* Drop additional groups here because we can't do it
after we've created the new user namespace. FIXME:
@ -2421,7 +2422,7 @@ void DerivationGoal::startBuilder() {
writeFull(builderOut.writeSide.get(), std::to_string(child) + "\n");
_exit(0);
},
options);
options));
int res = helper.wait();
if (res != 0 && settings.sandboxFallback) {
@ -2432,7 +2433,7 @@ void DerivationGoal::startBuilder() {
throw Error("unable to start build process");
}
userNamespaceSync.readSide = -1;
userNamespaceSync.readSide = AutoCloseFD(-1);
pid_t tmp;
if (!absl::SimpleAtoi(readLine(builderOut.readSide.get()), &tmp)) {
@ -2446,18 +2447,19 @@ void DerivationGoal::startBuilder() {
uid_t hostUid = buildUser ? buildUser->getUID() : getuid();
uid_t hostGid = buildUser ? buildUser->getGID() : getgid();
writeFile("/proc/" + std::to_string(pid) + "/uid_map",
writeFile("/proc/" + std::to_string(static_cast<pid_t>(pid)) + "/uid_map",
(format("%d %d 1") % sandboxUid % hostUid).str());
writeFile("/proc/" + std::to_string(pid) + "/setgroups", "deny");
writeFile("/proc/" + std::to_string(static_cast<pid_t>(pid)) + "/setgroups",
"deny");
writeFile("/proc/" + std::to_string(pid) + "/gid_map",
writeFile("/proc/" + std::to_string(static_cast<pid_t>(pid)) + "/gid_map",
(format("%d %d 1") % sandboxGid % hostGid).str());
/* Signal the builder that we've updated its user
namespace. */
writeFull(userNamespaceSync.writeSide.get(), "1");
userNamespaceSync.writeSide = -1;
userNamespaceSync.writeSide = AutoCloseFD(-1);
} else
#endif
@ -2468,7 +2470,7 @@ void DerivationGoal::startBuilder() {
/* parent */
pid.setSeparatePG(true);
builderOut.writeSide = -1;
builderOut.writeSide = AutoCloseFD(-1);
worker.childStarted(shared_from_this(), {builderOut.readSide.get()}, true,
true);
@ -2837,13 +2839,13 @@ void DerivationGoal::runChild() {
#if __linux__
if (useChroot) {
userNamespaceSync.writeSide = -1;
userNamespaceSync.writeSide = AutoCloseFD(-1);
if (drainFD(userNamespaceSync.readSide.get()) != "1") {
throw Error("user namespace initialisation failed");
}
userNamespaceSync.readSide = -1;
userNamespaceSync.readSide = AutoCloseFD(-1);
if (privateNetwork) {
/* Initialise the loopback interface. */
@ -3738,8 +3740,8 @@ Path DerivationGoal::openLogFile() {
Path logFileName = fmt("%s/%s%s", dir, std::string(baseName, 2),
settings.compressLog ? ".bz2" : "");
fdLogFile =
open(logFileName.c_str(), O_CREAT | O_WRONLY | O_TRUNC | O_CLOEXEC, 0666);
fdLogFile = AutoCloseFD(open(logFileName.c_str(),
O_CREAT | O_WRONLY | O_TRUNC | O_CLOEXEC, 0666));
if (!fdLogFile) {
throw SysError(format("creating log file '%1%'") % logFileName);
}
@ -3765,7 +3767,7 @@ void DerivationGoal::closeLogFile() {
logFileSink->flush();
}
logSink = logFileSink = nullptr;
fdLogFile = -1;
fdLogFile = AutoCloseFD(-1);
}
void DerivationGoal::deleteTmpDir(bool force) {
@ -4163,7 +4165,7 @@ void SubstitutionGoal::tryToRun() {
thr = std::thread([this]() {
try {
/* Wake up the worker loop when we're done. */
Finally updateStats([this]() { outPipe.writeSide = -1; });
Finally updateStats([this]() { outPipe.writeSide = AutoCloseFD(-1); });
copyStorePath(ref<Store>(sub),
ref<Store>(worker.store.shared_from_this()), storePath,

View file

@ -744,13 +744,15 @@ ref<Downloader> makeDownloader() { return make_ref<CurlDownloader>(); }
std::future<DownloadResult> Downloader::enqueueDownload(
const DownloadRequest& request) {
auto promise = std::make_shared<std::promise<DownloadResult>>();
enqueueDownload(request, {[promise](std::future<DownloadResult> fut) {
try {
promise->set_value(fut.get());
} catch (...) {
promise->set_exception(std::current_exception());
}
}});
enqueueDownload(
request,
Callback<DownloadResult>([promise](std::future<DownloadResult> fut) {
try {
promise->set_value(fut.get());
} catch (...) {
promise->set_exception(std::current_exception());
}
}));
return promise->get_future();
}
@ -807,17 +809,18 @@ void Downloader::download(DownloadRequest&& request, Sink& sink) {
state->avail.notify_one();
};
enqueueDownload(request, {[_state](std::future<DownloadResult> fut) {
auto state(_state->lock());
state->quit = true;
try {
fut.get();
} catch (...) {
state->exc = std::current_exception();
}
state->avail.notify_one();
state->request.notify_one();
}});
enqueueDownload(request, Callback<DownloadResult>(
[_state](std::future<DownloadResult> fut) {
auto state(_state->lock());
state->quit = true;
try {
fut.get();
} catch (...) {
state->exc = std::current_exception();
}
state->avail.notify_one();
state->request.notify_one();
}));
while (true) {
checkInterrupt();

View file

@ -35,8 +35,9 @@ AutoCloseFD LocalStore::openGCLock(LockType lockType) {
DLOG(INFO) << "acquiring global GC lock " << fnGCLock;
AutoCloseFD fdGCLock =
open(fnGCLock.c_str(), O_RDWR | O_CREAT | O_CLOEXEC, 0600);
AutoCloseFD fdGCLock(
open(fnGCLock.c_str(), O_RDWR | O_CREAT | O_CLOEXEC, 0600));
if (!fdGCLock) {
throw SysError(format("opening global GC lock '%1%'") % fnGCLock);
}
@ -160,7 +161,7 @@ void LocalStore::addTempRoot(const Path& path) {
state->fdTempRoots = openLockFile(fnTempRoots, true);
fdGCLock = -1;
fdGCLock = AutoCloseFD(-1);
DLOG(INFO) << "acquiring read lock on " << fnTempRoots;
lockFile(state->fdTempRoots.get(), ltRead, true);
@ -886,7 +887,7 @@ void LocalStore::collectGarbage(const GCOptions& options, GCResults& results) {
}
/* Allow other processes to add to the store from here on. */
fdGCLock = -1;
fdGCLock = AutoCloseFD(-1);
fds.clear();
/* Delete the trash directory. */

View file

@ -135,20 +135,22 @@ class HttpBinaryCacheStore : public BinaryCacheStore {
std::make_shared<decltype(callback)>(std::move(callback));
getDownloader()->enqueueDownload(
request, {[callbackPtr, this](std::future<DownloadResult> result) {
try {
(*callbackPtr)(result.get().data);
} catch (DownloadError& e) {
if (e.error == Downloader::NotFound ||
e.error == Downloader::Forbidden) {
return (*callbackPtr)(std::shared_ptr<std::string>());
}
maybeDisable();
callbackPtr->rethrow();
} catch (...) {
callbackPtr->rethrow();
}
}});
request,
Callback<DownloadResult>{
[callbackPtr, this](std::future<DownloadResult> result) {
try {
(*callbackPtr)(result.get().data);
} catch (DownloadError& e) {
if (e.error == Downloader::NotFound ||
e.error == Downloader::Forbidden) {
return (*callbackPtr)(std::shared_ptr<std::string>());
}
maybeDisable();
callbackPtr->rethrow();
} catch (...) {
callbackPtr->rethrow();
}
}});
}
};

View file

@ -135,8 +135,8 @@ LocalStore::LocalStore(const Params& params)
struct stat st;
if (stat(reservedPath.c_str(), &st) == -1 ||
st.st_size != settings.reservedSize) {
AutoCloseFD fd =
open(reservedPath.c_str(), O_WRONLY | O_CREAT | O_CLOEXEC, 0600);
AutoCloseFD fd(
open(reservedPath.c_str(), O_WRONLY | O_CREAT | O_CLOEXEC, 0600));
int res = -1;
#if HAVE_POSIX_FALLOCATE
res = posix_fallocate(fd.get(), 0, settings.reservedSize);
@ -288,7 +288,7 @@ LocalStore::~LocalStore() {
try {
auto state(_state.lock());
if (state->fdTempRoots) {
state->fdTempRoots = -1;
state->fdTempRoots = AutoCloseFD(-1);
unlink(fnTempRoots.c_str());
}
} catch (...) {
@ -1278,7 +1278,7 @@ bool LocalStore::verifyStore(bool checkContents, RepairFlag repair) {
PathSet validPaths;
PathSet done;
fdGCLock = -1;
fdGCLock = AutoCloseFD(-1);
for (auto& i : validPaths2) {
verifyPath(i, store, done, validPaths, repair, errors);

View file

@ -38,74 +38,76 @@ void Store::computeFSClosure(const PathSet& startPaths, PathSet& paths_,
}
queryPathInfo(
path, {[&, path](std::future<ref<ValidPathInfo>> fut) {
// FIXME: calls to isValidPath() should be async
path,
Callback<ref<ValidPathInfo>>(
[&, path](std::future<ref<ValidPathInfo>> fut) {
// FIXME: calls to isValidPath() should be async
try {
auto info = fut.get();
try {
auto info = fut.get();
if (flipDirection) {
PathSet referrers;
queryReferrers(path, referrers);
for (auto& ref : referrers) {
if (ref != path) {
enqueue(ref);
}
}
if (flipDirection) {
PathSet referrers;
queryReferrers(path, referrers);
for (auto& ref : referrers) {
if (ref != path) {
enqueue(ref);
}
}
if (includeOutputs) {
for (auto& i : queryValidDerivers(path)) {
enqueue(i);
}
}
if (includeOutputs) {
for (auto& i : queryValidDerivers(path)) {
enqueue(i);
}
}
if (includeDerivers && isDerivation(path)) {
for (auto& i : queryDerivationOutputs(path)) {
if (isValidPath(i) && queryPathInfo(i)->deriver == path) {
enqueue(i);
if (includeDerivers && isDerivation(path)) {
for (auto& i : queryDerivationOutputs(path)) {
if (isValidPath(i) && queryPathInfo(i)->deriver == path) {
enqueue(i);
}
}
}
} else {
for (auto& ref : info->references) {
if (ref != path) {
enqueue(ref);
}
}
if (includeOutputs && isDerivation(path)) {
for (auto& i : queryDerivationOutputs(path)) {
if (isValidPath(i)) {
enqueue(i);
}
}
}
if (includeDerivers && isValidPath(info->deriver)) {
enqueue(info->deriver);
}
}
}
} else {
for (auto& ref : info->references) {
if (ref != path) {
enqueue(ref);
}
}
if (includeOutputs && isDerivation(path)) {
for (auto& i : queryDerivationOutputs(path)) {
if (isValidPath(i)) {
enqueue(i);
{
auto state(state_.lock());
assert(state->pending);
if (--state->pending == 0u) {
done.notify_one();
}
}
}
if (includeDerivers && isValidPath(info->deriver)) {
enqueue(info->deriver);
}
}
{
auto state(state_.lock());
assert(state->pending);
if (--state->pending == 0u) {
done.notify_one();
}
}
} catch (...) {
auto state(state_.lock());
if (!state->exc) {
state->exc = std::current_exception();
}
assert(state->pending);
if (--state->pending == 0u) {
done.notify_one();
}
};
}});
} catch (...) {
auto state(state_.lock());
if (!state->exc) {
state->exc = std::current_exception();
}
assert(state->pending);
if (--state->pending == 0u) {
done.notify_one();
}
};
}));
};
for (auto& startPath : startPaths) {

View file

@ -15,9 +15,9 @@
namespace nix {
AutoCloseFD openLockFile(const Path& path, bool create) {
AutoCloseFD fd;
AutoCloseFD fd(
open(path.c_str(), O_CLOEXEC | O_RDWR | (create ? O_CREAT : 0), 0600));
fd = open(path.c_str(), O_CLOEXEC | O_RDWR | (create ? O_CREAT : 0), 0600);
if (!fd && (create || errno != ENOENT)) {
throw SysError(format("opening lock file '%1%'") % path);
}

View file

@ -70,7 +70,7 @@ std::pair<ref<FSAccessor>, Path> RemoteFSAccessor::fetch(const Path& path_) {
auto narAccessor = makeLazyNarAccessor(
listing, [cacheFile](uint64_t offset, uint64_t length) {
AutoCloseFD fd = open(cacheFile.c_str(), O_RDONLY | O_CLOEXEC);
AutoCloseFD fd(open(cacheFile.c_str(), O_RDONLY | O_CLOEXEC));
if (!fd) {
throw SysError("opening NAR cache file '%s'", cacheFile);
}

View file

@ -88,8 +88,8 @@ std::unique_ptr<SSHMaster::Connection> SSHMaster::startCommand(
},
options);
in.readSide = -1;
out.writeSide = -1;
in.readSide = AutoCloseFD(-1);
out.writeSide = AutoCloseFD(-1);
conn->out = std::move(out.readSide);
conn->in = std::move(in.writeSide);
@ -104,7 +104,7 @@ Path SSHMaster::startMaster() {
auto state(state_.lock());
if (state->sshMaster != -1) {
if (state->sshMaster != Pid(-1)) {
return state->socketPath;
}
@ -142,7 +142,7 @@ Path SSHMaster::startMaster() {
},
options);
out.writeSide = -1;
out.writeSide = AutoCloseFD(-1);
std::string reply;
try {

View file

@ -392,7 +392,10 @@ Path Store::computeStorePathForText(const std::string& name,
}
Store::Store(const Params& params)
: Config(params), state({(size_t)pathInfoCacheSize}) {}
: Config(params),
state(Sync<State>{
State{LRUCache<std::string, std::shared_ptr<ValidPathInfo>>(
(size_t)pathInfoCacheSize)}}) {}
std::string Store::getUri() { return ""; }
@ -446,13 +449,15 @@ bool Store::isValidPathUncached(const Path& path) {
ref<const ValidPathInfo> Store::queryPathInfo(const Path& storePath) {
std::promise<ref<ValidPathInfo>> promise;
queryPathInfo(storePath, {[&](std::future<ref<ValidPathInfo>> result) {
try {
promise.set_value(result.get());
} catch (...) {
promise.set_exception(std::current_exception());
}
}});
queryPathInfo(
storePath,
Callback<ref<ValidPathInfo>>([&](std::future<ref<ValidPathInfo>> result) {
try {
promise.set_value(result.get());
} catch (...) {
promise.set_exception(std::current_exception());
}
}));
return promise.get_future().get();
}
@ -503,31 +508,33 @@ void Store::queryPathInfo(const Path& storePath,
auto callbackPtr = std::make_shared<decltype(callback)>(std::move(callback));
queryPathInfoUncached(
storePath, {[this, storePath, hashPart, callbackPtr](
std::future<std::shared_ptr<ValidPathInfo>> fut) {
try {
auto info = fut.get();
storePath,
Callback<std::shared_ptr<ValidPathInfo>>{
[this, storePath, hashPart,
callbackPtr](std::future<std::shared_ptr<ValidPathInfo>> fut) {
try {
auto info = fut.get();
if (diskCache) {
diskCache->upsertNarInfo(getUri(), hashPart, info);
}
if (diskCache) {
diskCache->upsertNarInfo(getUri(), hashPart, info);
}
{
auto state_(state.lock());
state_->pathInfoCache.upsert(hashPart, info);
}
{
auto state_(state.lock());
state_->pathInfoCache.upsert(hashPart, info);
}
if (!info || (info->path != storePath &&
!storePathToName(storePath).empty())) {
stats.narInfoMissing++;
throw InvalidPath("path '%s' is not valid", storePath);
}
if (!info || (info->path != storePath &&
!storePathToName(storePath).empty())) {
stats.narInfoMissing++;
throw InvalidPath("path '%s' is not valid", storePath);
}
(*callbackPtr)(ref<ValidPathInfo>(info));
} catch (...) {
callbackPtr->rethrow();
}
}});
(*callbackPtr)(ref<ValidPathInfo>(info));
} catch (...) {
callbackPtr->rethrow();
}
}});
}
PathSet Store::queryValidPaths(const PathSet& paths,
@ -545,21 +552,22 @@ PathSet Store::queryValidPaths(const PathSet& paths,
auto doQuery = [&](const Path& path) {
checkInterrupt();
queryPathInfo(
path, {[path, &state_, &wakeup](std::future<ref<ValidPathInfo>> fut) {
auto state(state_.lock());
try {
auto info = fut.get();
state->valid.insert(path);
} catch (InvalidPath&) {
} catch (...) {
state->exc = std::current_exception();
}
assert(state->left);
if (--state->left == 0u) {
wakeup.notify_one();
}
}});
queryPathInfo(path, Callback<ref<ValidPathInfo>>(
[path, &state_,
&wakeup](std::future<ref<ValidPathInfo>> fut) {
auto state(state_.lock());
try {
auto info = fut.get();
state->valid.insert(path);
} catch (InvalidPath&) {
} catch (...) {
state->exc = std::current_exception();
}
assert(state->left);
if (--state->left == 0u) {
wakeup.notify_one();
}
}));
};
for (auto& path : paths) {