Skip to content

Commit 7fb13a1

Browse files
committed
Merge branch 'master' of https://github.com/NixOS/nix into upstream/master
2 parents 484fb32 + 3ed8290 commit 7fb13a1

19 files changed

+322
-84
lines changed

src/libstore/build.cc

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2202,7 +2202,7 @@ void DerivationGoal::initEnv()
22022202
env["NIX_BUILD_CORES"] = (format("%d") % settings.buildCores).str();
22032203

22042204
/* In non-structured mode, add all bindings specified in the
2205-
derivation via the environments, except those listed in the
2205+
derivation via the environment, except those listed in the
22062206
passAsFile attribute. Those are passed as file names pointing
22072207
to temporary files containing the contents. Note that
22082208
passAsFile is ignored in structure mode because it's not
@@ -2258,6 +2258,11 @@ void DerivationGoal::initEnv()
22582258
Strings varNames = tokenizeString<Strings>(get(drv->env, "impureEnvVars"));
22592259
for (auto & i : varNames) env[i] = getEnv(i);
22602260
}
2261+
2262+
/* Currently structured log messages piggyback on stderr, but we
2263+
may change that in the future. So tell the builder which file
2264+
descriptor to use for that. */
2265+
env["NIX_LOG_FD"] = "2";
22612266
}
22622267

22632268

src/libstore/legacy-ssh-store.cc

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,13 @@ struct LegacySSHStore : public Store
105105
readLongLong(conn->from); // download size
106106
info->narSize = readLongLong(conn->from);
107107

108+
if (GET_PROTOCOL_MINOR(conn->remoteVersion) >= 4) {
109+
auto s = readString(conn->from);
110+
info->narHash = s.empty() ? Hash() : Hash(s);
111+
conn->from >> info->ca;
112+
info->sigs = readStrings<StringSet>(conn->from);
113+
}
114+
108115
auto s = readString(conn->from);
109116
assert(s == "");
110117

src/libstore/serve-protocol.hh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ namespace nix {
55
#define SERVE_MAGIC_1 0x390c9deb
66
#define SERVE_MAGIC_2 0x5452eecb
77

8-
#define SERVE_PROTOCOL_VERSION 0x203
8+
#define SERVE_PROTOCOL_VERSION 0x204
99
#define GET_PROTOCOL_MAJOR(x) ((x) & 0xff00)
1010
#define GET_PROTOCOL_MINOR(x) ((x) & 0x00ff)
1111

src/libstore/store-api.cc

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -593,23 +593,19 @@ void copyStorePath(ref<Store> srcStore, ref<Store> dstStore,
593593
MyStringSink sink(progress);
594594
srcStore->narFromPath({storePath}, sink);
595595

596-
if (!info->narHash && !checkSigs) {
596+
if (!info->narHash) {
597597
auto info2 = make_ref<ValidPathInfo>(*info);
598598
info2->narHash = hashString(htSHA256, *sink.s);
599599
if (!info->narSize) info2->narSize = sink.s->size();
600600
info = info2;
601601
}
602602

603-
assert(info->narHash);
604-
605603
if (info->ultimate) {
606604
auto info2 = make_ref<ValidPathInfo>(*info);
607605
info2->ultimate = false;
608606
info = info2;
609607
}
610608

611-
assert(info->narHash);
612-
613609
dstStore->addToStore(*info, sink.s, repair, checkSigs);
614610
}
615611

src/libutil/args.hh

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,19 @@ public:
8080
FlagMaker & arity(size_t arity) { flag->arity = arity; return *this; };
8181
FlagMaker & handler(std::function<void(Strings)> handler) { flag->handler = handler; return *this; };
8282
FlagMaker & category(const std::string & s) { flag->category = s; return *this; };
83+
84+
FlagMaker & dest(std::string * dest) {
85+
assert(flag->arity == 1);
86+
flag->handler = [=](Strings ss) { *dest = ss.front(); };
87+
return *this;
88+
};
89+
90+
template<class T>
91+
FlagMaker & set(T * dest, const T & val) {
92+
assert(flag->arity == 0);
93+
flag->handler = [=](Strings ss) { *dest = val; };
94+
return *this;
95+
};
8396
};
8497

8598
FlagMaker mkFlag();

src/libutil/thread-pool.cc

Lines changed: 56 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ ThreadPool::~ThreadPool()
2121
std::vector<std::thread> workers;
2222
{
2323
auto state(state_.lock());
24-
state->quit = true;
24+
quit = true;
2525
std::swap(workers, state->workers);
2626
}
2727

@@ -36,7 +36,7 @@ ThreadPool::~ThreadPool()
3636
void ThreadPool::enqueue(const work_t & t)
3737
{
3838
auto state(state_.lock());
39-
if (state->quit)
39+
if (quit)
4040
throw ThreadPoolShutDown("cannot enqueue a work item while the thread pool is shutting down");
4141
state->left.push(t);
4242
if (state->left.size() > state->workers.size() && state->workers.size() < maxThreads)
@@ -46,53 +46,84 @@ void ThreadPool::enqueue(const work_t & t)
4646

4747
void ThreadPool::process()
4848
{
49+
/* Loop until there are no active work items *and* there either
50+
are no queued items or there is an exception. The
51+
post-condition is that no new items will become active. */
4952
while (true) {
5053
auto state(state_.lock());
51-
if (state->exception)
52-
std::rethrow_exception(state->exception);
53-
if (state->left.empty() && !state->pending) break;
54+
if (!state->active) {
55+
if (state->exception)
56+
std::rethrow_exception(state->exception);
57+
if (state->left.empty())
58+
break;
59+
}
5460
state.wait(done);
5561
}
5662
}
5763

5864
void ThreadPool::workerEntry()
5965
{
66+
interruptCheck = [&]() { return (bool) quit; };
67+
6068
bool didWork = false;
69+
std::exception_ptr exc;
6170

6271
while (true) {
6372
work_t w;
6473
{
6574
auto state(state_.lock());
75+
76+
if (didWork) {
77+
assert(state->active);
78+
state->active--;
79+
80+
if (exc) {
81+
82+
if (!state->exception) {
83+
state->exception = exc;
84+
// Tell the other workers to quit.
85+
quit = true;
86+
work.notify_all();
87+
} else {
88+
/* Print the exception, since we can't
89+
propagate it. */
90+
try {
91+
std::rethrow_exception(exc);
92+
} catch (std::exception & e) {
93+
if (!dynamic_cast<Interrupted*>(&e) &&
94+
!dynamic_cast<ThreadPoolShutDown*>(&e))
95+
ignoreException();
96+
} catch (...) {
97+
}
98+
}
99+
}
100+
}
101+
102+
/* Wait until a work item is available or another thread
103+
had an exception or we're asked to quit. */
66104
while (true) {
67-
if (state->quit || state->exception) return;
68-
if (didWork) {
69-
assert(state->pending);
70-
state->pending--;
71-
didWork = false;
105+
if (quit) {
106+
if (!state->active)
107+
done.notify_one();
108+
return;
72109
}
73110
if (!state->left.empty()) break;
74-
if (!state->pending)
75-
done.notify_all();
111+
if (!state->active) {
112+
done.notify_one();
113+
return;
114+
}
76115
state.wait(work);
77116
}
78-
w = state->left.front();
117+
118+
w = std::move(state->left.front());
79119
state->left.pop();
80-
state->pending++;
120+
state->active++;
81121
}
82122

83123
try {
84124
w();
85-
} catch (std::exception & e) {
86-
auto state(state_.lock());
87-
if (state->exception) {
88-
if (!dynamic_cast<Interrupted*>(&e) &&
89-
!dynamic_cast<ThreadPoolShutDown*>(&e))
90-
printError(format("error: %s") % e.what());
91-
} else {
92-
state->exception = std::current_exception();
93-
work.notify_all();
94-
done.notify_all();
95-
}
125+
} catch (...) {
126+
exc = std::current_exception();
96127
}
97128

98129
didWork = true;

src/libutil/thread-pool.hh

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include <functional>
88
#include <thread>
99
#include <map>
10+
#include <atomic>
1011

1112
namespace nix {
1213

@@ -44,12 +45,13 @@ private:
4445
struct State
4546
{
4647
std::queue<work_t> left;
47-
size_t pending = 0;
48+
size_t active = 0;
4849
std::exception_ptr exception;
4950
std::vector<std::thread> workers;
50-
bool quit = false;
5151
};
5252

53+
std::atomic_bool quit{false};
54+
5355
Sync<State> state_;
5456

5557
std::condition_variable work, done;

src/libutil/util.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1002,6 +1002,7 @@ void closeOnExec(int fd)
10021002
bool _isInterrupted = false;
10031003

10041004
static thread_local bool interruptThrown = false;
1005+
thread_local std::function<bool()> interruptCheck;
10051006

10061007
void setInterruptThrown()
10071008
{
@@ -1020,7 +1021,6 @@ void _interrupted()
10201021
}
10211022

10221023

1023-
10241024
//////////////////////////////////////////////////////////////////////
10251025

10261026

src/libutil/util.hh

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -273,13 +273,16 @@ void closeOnExec(int fd);
273273

274274
extern bool _isInterrupted;
275275

276+
extern thread_local std::function<bool()> interruptCheck;
277+
276278
void setInterruptThrown();
277279

278280
void _interrupted();
279281

280282
void inline checkInterrupt()
281283
{
282-
if (_isInterrupted) _interrupted();
284+
if (_isInterrupted || (interruptCheck && interruptCheck()))
285+
_interrupted();
283286
}
284287

285288
MakeError(Interrupted, BaseError)

src/nix-store/nix-store.cc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -858,6 +858,8 @@ static void opServe(Strings opFlags, Strings opArgs)
858858
// !!! Maybe we want compression?
859859
out << info->narSize // downloadSize
860860
<< info->narSize;
861+
if (GET_PROTOCOL_MINOR(clientVersion) >= 4)
862+
out << (info->narHash ? info->narHash.to_string() : "") << info->ca << info->sigs;
861863
} catch (InvalidPath &) {
862864
}
863865
}

0 commit comments

Comments
 (0)