mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-21 23:21:59 +00:00
Add writeRetry helper
This commit is contained in:
parent
b9c869871b
commit
8ec874dc33
@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
#include <Common/StringUtils/StringUtils.h>
|
#include <Common/StringUtils/StringUtils.h>
|
||||||
#include <Common/getHashOfLoadedBinary.h>
|
#include <Common/getHashOfLoadedBinary.h>
|
||||||
|
#include <Common/IO.h>
|
||||||
|
|
||||||
#include <common/phdr_cache.h>
|
#include <common/phdr_cache.h>
|
||||||
#include <ext/scope_guard.h>
|
#include <ext/scope_guard.h>
|
||||||
@ -172,11 +173,11 @@ enum class InstructionFail
|
|||||||
AVX512 = 8
|
AVX512 = 8
|
||||||
};
|
};
|
||||||
|
|
||||||
std::pair<const char *, size_t> instructionFailToString(InstructionFail fail)
|
auto instructionFailToString(InstructionFail fail)
|
||||||
{
|
{
|
||||||
switch (fail)
|
switch (fail)
|
||||||
{
|
{
|
||||||
#define ret(x) return std::make_pair(x, ARRAY_SIZE(x) - 1)
|
#define ret(x) return std::make_tuple(STDERR_FILENO, x, ARRAY_SIZE(x) - 1)
|
||||||
case InstructionFail::NONE:
|
case InstructionFail::NONE:
|
||||||
ret("NONE");
|
ret("NONE");
|
||||||
case InstructionFail::SSE3:
|
case InstructionFail::SSE3:
|
||||||
@ -260,28 +261,12 @@ void checkRequiredInstructionsImpl(volatile InstructionFail & fail)
|
|||||||
fail = InstructionFail::NONE;
|
fail = InstructionFail::NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This function is safe to use in static initializers.
|
|
||||||
void writeErrorLen(const char * data, size_t size)
|
|
||||||
{
|
|
||||||
while (size != 0)
|
|
||||||
{
|
|
||||||
ssize_t res = ::write(STDERR_FILENO, data, size);
|
|
||||||
|
|
||||||
if ((-1 == res || 0 == res) && errno != EINTR)
|
|
||||||
_Exit(1);
|
|
||||||
|
|
||||||
if (res > 0)
|
|
||||||
{
|
|
||||||
data += res;
|
|
||||||
size -= res;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/// Macros to avoid using strlen(), since it may fail if SSE is not supported.
|
/// Macros to avoid using strlen(), since it may fail if SSE is not supported.
|
||||||
#define writeError(data) do \
|
#define writeError(data) do \
|
||||||
{ \
|
{ \
|
||||||
static_assert(__builtin_constant_p(data)); \
|
static_assert(__builtin_constant_p(data)); \
|
||||||
writeErrorLen(data, ARRAY_SIZE(data) - 1); \
|
if (!writeRetry(STDERR_FILENO, data, ARRAY_SIZE(data) - 1)) \
|
||||||
|
_Exit(1); \
|
||||||
} while (false)
|
} while (false)
|
||||||
|
|
||||||
/// Check SSE and others instructions availability. Calls exit on fail.
|
/// Check SSE and others instructions availability. Calls exit on fail.
|
||||||
@ -310,7 +295,8 @@ void checkRequiredInstructions()
|
|||||||
if (sigsetjmp(jmpbuf, 1))
|
if (sigsetjmp(jmpbuf, 1))
|
||||||
{
|
{
|
||||||
writeError("Instruction check fail. The CPU does not support ");
|
writeError("Instruction check fail. The CPU does not support ");
|
||||||
std::apply(writeErrorLen, instructionFailToString(fail));
|
if (!std::apply(writeRetry, instructionFailToString(fail)))
|
||||||
|
_Exit(1);
|
||||||
writeError(" instruction set.\n");
|
writeError(" instruction set.\n");
|
||||||
_Exit(1);
|
_Exit(1);
|
||||||
}
|
}
|
||||||
|
27
src/Common/IO.cpp
Normal file
27
src/Common/IO.cpp
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
#include <Common/IO.h>
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
|
bool writeRetry(int fd, const char * data, size_t size)
|
||||||
|
{
|
||||||
|
if (!size)
|
||||||
|
size = strlen(data);
|
||||||
|
|
||||||
|
while (size != 0)
|
||||||
|
{
|
||||||
|
ssize_t res = ::write(fd, data, size);
|
||||||
|
|
||||||
|
if ((-1 == res || 0 == res) && errno != EINTR)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (res > 0)
|
||||||
|
{
|
||||||
|
data += res;
|
||||||
|
size -= res;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
13
src/Common/IO.h
Normal file
13
src/Common/IO.h
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstddef>
|
||||||
|
|
||||||
|
/// IO helpers
|
||||||
|
|
||||||
|
/// Write loop with EINTR handling.
|
||||||
|
///
|
||||||
|
/// This function is safe to use in static initializers.
|
||||||
|
///
|
||||||
|
/// @param size - len of @data or 0 to use strlen()
|
||||||
|
/// @return true if write was succeed, otherwise false.
|
||||||
|
bool writeRetry(int fd, const char * data, size_t size = 0);
|
@ -46,6 +46,7 @@ SRCS(
|
|||||||
ExternalLoaderStatus.cpp
|
ExternalLoaderStatus.cpp
|
||||||
FieldVisitors.cpp
|
FieldVisitors.cpp
|
||||||
FileChecker.cpp
|
FileChecker.cpp
|
||||||
|
IO.cpp
|
||||||
IPv6ToBinary.cpp
|
IPv6ToBinary.cpp
|
||||||
IntervalKind.cpp
|
IntervalKind.cpp
|
||||||
JSONBuilder.cpp
|
JSONBuilder.cpp
|
||||||
|
Loading…
Reference in New Issue
Block a user