mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-27 01:51:59 +00:00
dbms: fixed race condition (still messy) [#METR-11765].
This commit is contained in:
parent
71935f7916
commit
cdbff6e120
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <queue>
|
#include <queue>
|
||||||
|
#include <atomic>
|
||||||
|
|
||||||
#include <Poco/Thread.h>
|
#include <Poco/Thread.h>
|
||||||
|
|
||||||
@ -37,8 +38,7 @@ class UnionBlockInputStream : public IProfilingBlockInputStream
|
|||||||
public:
|
public:
|
||||||
UnionBlockInputStream(BlockInputStreams inputs_, unsigned max_threads_ = 1)
|
UnionBlockInputStream(BlockInputStreams inputs_, unsigned max_threads_ = 1)
|
||||||
: max_threads(std::min(inputs_.size(), static_cast<size_t>(max_threads_))),
|
: max_threads(std::min(inputs_.size(), static_cast<size_t>(max_threads_))),
|
||||||
output_queue(max_threads), exhausted_inputs(0), finish(false),
|
output_queue(max_threads)
|
||||||
pushed_end_of_output_queue(false), all_read(false), log(&Logger::get("UnionBlockInputStream"))
|
|
||||||
{
|
{
|
||||||
children.insert(children.end(), inputs_.begin(), inputs_.end());
|
children.insert(children.end(), inputs_.begin(), inputs_.end());
|
||||||
|
|
||||||
@ -223,6 +223,9 @@ private:
|
|||||||
|
|
||||||
if (exception)
|
if (exception)
|
||||||
{
|
{
|
||||||
|
/// Отдаём эксепшен в основной поток.
|
||||||
|
parent.output_queue.push(exception);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
parent.cancel();
|
parent.cancel();
|
||||||
@ -234,9 +237,6 @@ private:
|
|||||||
* - то пофиг.
|
* - то пофиг.
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Отдаём эксепшен в основной поток.
|
|
||||||
parent.output_queue.push(exception);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -292,16 +292,11 @@ private:
|
|||||||
|
|
||||||
if (parent.finish)
|
if (parent.finish)
|
||||||
{
|
{
|
||||||
Poco::ScopedLock<Poco::FastMutex> lock(parent.mutex);
|
/// Отдаём в основной поток пустой блок, что означает, что данных больше нет; только один раз.
|
||||||
|
if (false == parent.pushed_end_of_output_queue.exchange(true))
|
||||||
/// Отдаём в основной поток пустой блок, что означает, что данных больше нет.
|
|
||||||
if (!parent.pushed_end_of_output_queue)
|
|
||||||
{
|
|
||||||
parent.pushed_end_of_output_queue = true;
|
|
||||||
parent.output_queue.push(OutputData());
|
parent.output_queue.push(OutputData());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
UnionBlockInputStream & parent;
|
UnionBlockInputStream & parent;
|
||||||
@ -334,19 +329,20 @@ private:
|
|||||||
typedef ConcurrentBoundedQueue<OutputData> OutputQueue;
|
typedef ConcurrentBoundedQueue<OutputData> OutputQueue;
|
||||||
OutputQueue output_queue;
|
OutputQueue output_queue;
|
||||||
|
|
||||||
/// Для операций с очередями.
|
/// Для операций с input_queue.
|
||||||
Poco::FastMutex mutex;
|
Poco::FastMutex mutex;
|
||||||
|
|
||||||
/// Сколько источников иссякло.
|
/// Сколько источников иссякло.
|
||||||
size_t exhausted_inputs;
|
size_t exhausted_inputs = 0;
|
||||||
|
|
||||||
/// Завершить работу потоков (раньше, чем иссякнут источники).
|
/// Завершить работу потоков (раньше, чем иссякнут источники).
|
||||||
volatile bool finish;
|
std::atomic<bool> finish { false };
|
||||||
/// Положили ли в output_queue пустой блок.
|
/// Положили ли в output_queue пустой блок.
|
||||||
volatile bool pushed_end_of_output_queue;
|
std::atomic<bool> pushed_end_of_output_queue { false };
|
||||||
bool all_read;
|
|
||||||
|
|
||||||
Logger * log;
|
bool all_read { false };
|
||||||
|
|
||||||
|
Logger * log = &Logger::get("UnionBlockInputStream");
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user