}
}
-DoneRunning doneRunning;
+DoneRunning g_doneRunning;
int main(int argc, char** argv)
{
ret = serviceMain(startupLog);
{
- std::lock_guard lock(doneRunning.mutex);
- doneRunning.done = true;
- doneRunning.condVar.notify_one();
+ std::lock_guard lock(g_doneRunning.mutex);
+ g_doneRunning.done = true;
+ g_doneRunning.condVar.notify_one();
}
RecThreadInfo::joinThread0();
}
std::condition_variable condVar;
std::atomic<bool> done{false};
};
-extern DoneRunning doneRunning;
+extern DoneRunning g_doneRunning;
// you can ask this class for a UDP socket to send a query from
// this socket is not yours, don't even think about deleting it
#include "namespaces.hh"
+/* g++ defines __SANITIZE_THREAD__
+ clang++ supports the nice __has_feature(thread_sanitizer),
+ let's merge them */
+#if defined(__has_feature)
+#if __has_feature(thread_sanitizer)
+#define __SANITIZE_THREAD__ 1
+#endif
+#if __has_feature(address_sanitizer)
+#define __SANITIZE_ADDRESS__ 1
+#endif
+#endif
+
std::atomic<bool> RecursorControlChannel::stop = false;
RecursorControlChannel::RecursorControlChannel()
const time_t start = time(nullptr);
waitForRead(fd, timeout, start);
- int err;
- if (::recv(fd, &err, sizeof(err), 0) != sizeof(err)) {
+ int err{};
+ auto ret = ::recv(fd, &err, sizeof(err), 0);
+ if (ret == 0) {
+#if defined(__SANITIZE_THREAD__)
+ return {0, "bye nicely\n"}; // Hack because TSAN enabled build justs _exits on quit-nicely
+#endif
+ throw PDNSException("Unable to receive status over control connection: EOF");
+ }
+ if (ret != sizeof(err)) {
throw PDNSException("Unable to receive return status over control channel: " + stringerror());
}
if (nicely) {
RecursorControlChannel::stop = true;
{
- std::unique_lock lock(doneRunning.mutex);
- doneRunning.condVar.wait(lock, [] { return doneRunning.done.load(); });
+ std::unique_lock lock(g_doneRunning.mutex);
+ g_doneRunning.condVar.wait(lock, [] { return g_doneRunning.done.load(); });
}
// g_rcc.~RecursorControlChannel() do not call, caller still needs it!
}