From 9e51b553f7266d6faf42d73da76026caa9681e89 Mon Sep 17 00:00:00 2001 From: Roman Elizarov Date: Wed, 3 Jun 2026 18:58:39 +0300 Subject: [PATCH] Code style: don't patch expressions/statements with conditional compilation --- core/libc_include_fixes/errno.h | 10 +- core/libc_include_fixes/pthread.h | 10 +- core/src/clients/dns/net_resolver.cpp | 9 +- core/src/dist_lock/dist_lock_test.cpp | 6 +- .../src/engine/ev/watcher/io_watcher_test.cpp | 6 +- core/src/engine/io/fd_control.hpp | 15 +- core/src/engine/io/poller_test.cpp | 5 +- core/src/engine/io/socket.cpp | 59 ++++--- .../server/http/http_response_cookie_test.cpp | 18 +- kafka/tests/producer_kafkatest.cpp | 9 +- .../proto_server_reflection.cpp | 36 ++-- .../src/storages/mongo/cdriver/pool_impl.cpp | 28 +-- postgresql/pq-extra/pq_portal_funcs.c | 118 +++++++------ postgresql/pq-extra/pq_workaround.c | 165 +++++++++--------- .../postgres/detail/pg_connection_wrapper.cpp | 8 +- universal/include/userver/compiler/select.hpp | 5 +- .../include/userver/utils/from_string.hpp | 13 +- universal/src/crypto/ssl_ctx.cpp | 11 +- .../utest/current_process_open_files_test.cpp | 6 +- ydb/src/ydb/response.cpp | 18 +- 20 files changed, 320 insertions(+), 235 deletions(-) diff --git a/core/libc_include_fixes/errno.h b/core/libc_include_fixes/errno.h index ce4f94b2b212..88d814662e9a 100644 --- a/core/libc_include_fixes/errno.h +++ b/core/libc_include_fixes/errno.h @@ -15,11 +15,15 @@ extern "C" { #endif -extern int* __errno_location(void) #ifdef __THROW - __THROW +#define USERVER_IMPL_LIBC_INCLUDE_FIXES_THROW __THROW +#else +#define USERVER_IMPL_LIBC_INCLUDE_FIXES_THROW #endif - ; + +extern int* __errno_location(void) USERVER_IMPL_LIBC_INCLUDE_FIXES_THROW; + +#undef USERVER_IMPL_LIBC_INCLUDE_FIXES_THROW #ifdef __cplusplus } diff --git a/core/libc_include_fixes/pthread.h b/core/libc_include_fixes/pthread.h index 917bba7c35f7..4faec55c85bb 100644 --- a/core/libc_include_fixes/pthread.h +++ b/core/libc_include_fixes/pthread.h @@ -15,11 +15,15 @@ extern "C" { #endif -extern pthread_t pthread_self(void) #ifdef __THROW - __THROW +#define USERVER_IMPL_LIBC_INCLUDE_FIXES_THROW __THROW +#else +#define USERVER_IMPL_LIBC_INCLUDE_FIXES_THROW #endif - ; + +extern pthread_t pthread_self(void) USERVER_IMPL_LIBC_INCLUDE_FIXES_THROW; + +#undef USERVER_IMPL_LIBC_INCLUDE_FIXES_THROW #ifdef __cplusplus } diff --git a/core/src/clients/dns/net_resolver.cpp b/core/src/clients/dns/net_resolver.cpp index bd9decd87d5c..33eab7d2d91e 100644 --- a/core/src/clients/dns/net_resolver.cpp +++ b/core/src/clients/dns/net_resolver.cpp @@ -236,11 +236,14 @@ class NetResolver::Impl { } void InitChannel() { - constexpr int kOptmask = - ARES_OPT_FLAGS | ARES_OPT_TIMEOUTMS | ARES_OPT_TRIES | ARES_OPT_DOMAINS | + constexpr int kSockStateCbOptmask = #if ARES_VERSION < 0x011400 - ARES_OPT_SOCK_STATE_CB | + ARES_OPT_SOCK_STATE_CB; +#else + 0; #endif + constexpr int kOptmask = + ARES_OPT_FLAGS | ARES_OPT_TIMEOUTMS | ARES_OPT_TRIES | ARES_OPT_DOMAINS | kSockStateCbOptmask | ARES_OPT_LOOKUPS; struct ares_options options {}; options.flags = diff --git a/core/src/dist_lock/dist_lock_test.cpp b/core/src/dist_lock/dist_lock_test.cpp index 5c2d1d12c907..f4d1e0a31c08 100644 --- a/core/src/dist_lock/dist_lock_test.cpp +++ b/core/src/dist_lock/dist_lock_test.cpp @@ -234,10 +234,12 @@ UTEST_MT(LockedWorker, OkAfterFail, 3) { // TODO: TAXICOMMON-1059 #if defined(__APPLE__) || defined(BSD) -UTEST_MT(LockedWorker, DISABLED_OkFailOk, 3) { +#define USERVER_IMPL_LOCKED_WORKER_OK_FAIL_OK DISABLED_OkFailOk #else -UTEST_MT(LockedWorker, OkFailOk, 3) { +#define USERVER_IMPL_LOCKED_WORKER_OK_FAIL_OK OkFailOk #endif + +UTEST_MT(LockedWorker, USERVER_IMPL_LOCKED_WORKER_OK_FAIL_OK, 3) { auto strategy = MakeMockStrategy(); DistLockWorkload work; dist_lock::DistLockedWorker locked_worker(kWorkerName, [&] { work.Work(); }, strategy, MakeSettings()); diff --git a/core/src/engine/ev/watcher/io_watcher_test.cpp b/core/src/engine/ev/watcher/io_watcher_test.cpp index 84b0f7459355..d42900e6ac82 100644 --- a/core/src/engine/ev/watcher/io_watcher_test.cpp +++ b/core/src/engine/ev/watcher/io_watcher_test.cpp @@ -10,10 +10,12 @@ USERVER_NAMESPACE_BEGIN #if defined(BSD) && !defined(__APPLE__) -UTEST(IoWatcher, DISABLED_DevNull) { +#define USERVER_IMPL_IO_WATCHER_DEV_NULL DISABLED_DevNull #else -UTEST(IoWatcher, DevNull) { +#define USERVER_IMPL_IO_WATCHER_DEV_NULL DevNull #endif + +UTEST(IoWatcher, USERVER_IMPL_IO_WATCHER_DEV_NULL) { LOG_DEBUG() << "Opening /dev/null"; engine::ev::Thread thread{"test_thread"}; engine::ev::ThreadControl thread_control(thread); diff --git a/core/src/engine/io/fd_control.hpp b/core/src/engine/io/fd_control.hpp index c60d936f63d3..d3b9f76cd700 100644 --- a/core/src/engine/io/fd_control.hpp +++ b/core/src/engine/io/fd_control.hpp @@ -41,6 +41,14 @@ enum class ErrorMode { kFatal, ///< break execute operation }; +constexpr bool IsRetryableIoError(int error_code) noexcept { +#if EWOULDBLOCK != EAGAIN + return error_code == EWOULDBLOCK || error_code == EAGAIN; +#else + return error_code == EWOULDBLOCK; +#endif +} + class FdControl; class Direction final { @@ -166,12 +174,7 @@ ErrorMode Direction::TryHandleError( ) { if (error_code == EINTR) { return ErrorMode::kProcessed; - } else if (error_code == EWOULDBLOCK -#if EWOULDBLOCK != EAGAIN - || error_code == EAGAIN -#endif - ) - { + } else if (IsRetryableIoError(error_code)) { if (processed_bytes != 0 && mode != TransferMode::kWhole) { return ErrorMode::kFatal; } diff --git a/core/src/engine/io/poller_test.cpp b/core/src/engine/io/poller_test.cpp index 95431c986f9c..ad59512cb00a 100644 --- a/core/src/engine/io/poller_test.cpp +++ b/core/src/engine/io/poller_test.cpp @@ -222,10 +222,11 @@ UTEST(Poller, ReadWriteMultipleTorture) { // Disabled for mac, see https://st.yandex-team.ru/TAXICOMMON-4196 #ifdef BSD -UTEST(Poller, DISABLED_AwaitedEventsChange) { +#define USERVER_IMPL_POLLER_AWAITED_EVENTS_CHANGE DISABLED_AwaitedEventsChange #else -UTEST(Poller, AwaitedEventsChange) { +#define USERVER_IMPL_POLLER_AWAITED_EVENTS_CHANGE AwaitedEventsChange #endif +UTEST(Poller, USERVER_IMPL_POLLER_AWAITED_EVENTS_CHANGE) { TcpListener listener; auto socket_pair = listener.MakeSocketPair(engine::Deadline::FromDuration(utest::kMaxTestWaitTime)); diff --git a/core/src/engine/io/socket.cpp b/core/src/engine/io/socket.cpp index 490ed5f8234d..a7d4b0fcf907 100644 --- a/core/src/engine/io/socket.cpp +++ b/core/src/engine/io/socket.cpp @@ -26,17 +26,41 @@ namespace { constexpr size_t kMaxStackSizeVector = 32; // MAC_COMPAT: does not accept flags in type -impl::FdControlHolder MakeSocket(AddrDomain domain, SocketType type) { - return impl::FdControl::Adopt(utils::CheckSyscallCustomException( - ::socket( - static_cast(domain), +constexpr int kSockNonblockFlag = #ifdef SOCK_NONBLOCK - SOCK_NONBLOCK | + SOCK_NONBLOCK; +#else + 0; #endif + +constexpr int kSockCloexecFlag = #ifdef SOCK_CLOEXEC - SOCK_CLOEXEC | + SOCK_CLOEXEC; +#else + 0; +#endif + +// MAC_COMPAT: does not support MSG_NOSIGNAL +constexpr int kMsgNosignalFlag = +#ifdef MSG_NOSIGNAL + MSG_NOSIGNAL; +#else + 0; +#endif + +bool IsWouldBlock() noexcept { +#if EAGAIN != EWOULDBLOCK + return errno == EAGAIN || errno == EWOULDBLOCK; +#else + return errno == EAGAIN; #endif - static_cast(type), +} + +impl::FdControlHolder MakeSocket(AddrDomain domain, SocketType type) { + return impl::FdControl::Adopt(utils::CheckSyscallCustomException( + ::socket( + static_cast(domain), + kSockNonblockFlag | kSockCloexecFlag | static_cast(type), /* protocol=*/0 ), "creating socket" @@ -68,11 +92,7 @@ Sockaddr& MemoizeAddr( fd, buf, len, -// MAC_COMPAT: does not support MSG_NOSIGNAL -#ifdef MSG_NOSIGNAL - MSG_NOSIGNAL | -#endif - 0 + kMsgNosignalFlag ); } @@ -106,11 +126,7 @@ class SendToWrapper { fd, buf, len, -// MAC_COMPAT: does not support MSG_NOSIGNAL -#ifdef MSG_NOSIGNAL - MSG_NOSIGNAL | -#endif - 0, + kMsgNosignalFlag, dest_addr_.Data(), dest_addr_.Size() ); @@ -275,14 +291,9 @@ std::optional Socket::RecvNoblock(void* buf, size_t len) { const auto bytes_read = RecvWrapper(fd_control_->Fd(), buf, len); if (bytes_read >= 0) { return {bytes_read}; - } else if ( -#if EAGAIN != EWOULDBLOCK - EWOULDBLOCK == errno -#else - EAGAIN == errno -#endif - ) + } else if (IsWouldBlock()) { return {}; + } throw IoException("Attempt to RecvNoblock from closed socket"); } diff --git a/core/src/server/http/http_response_cookie_test.cpp b/core/src/server/http/http_response_cookie_test.cpp index 179978ca5b21..b39d0b9a7983 100644 --- a/core/src/server/http/http_response_cookie_test.cpp +++ b/core/src/server/http/http_response_cookie_test.cpp @@ -7,6 +7,12 @@ USERVER_NAMESPACE_BEGIN +#if defined(BSD) && !defined(__APPLE__) +#define USERVER_IMPL_HTTP_COOKIE_TIMEZONE "UTC; " +#else +#define USERVER_IMPL_HTTP_COOKIE_TIMEZONE "GMT; " +#endif + TEST(HttpCookie, Simple) { server::http::Cookie cookie{"name1", "value1"}; EXPECT_EQ(cookie.ToString(), "name1=value1"); @@ -27,11 +33,7 @@ TEST(HttpCookie, Simple) { const auto* const expected = "name1=value1; Domain=domain.com; Path=/; Expires=Wed, 12 Jun 2019 " "16:51:45 " -#if defined(BSD) && !defined(__APPLE__) - "UTC; " -#else - "GMT; " -#endif + USERVER_IMPL_HTTP_COOKIE_TIMEZONE "Max-Age=3600; Secure; HttpOnly"; EXPECT_EQ(cookie.ToString(), expected); @@ -39,11 +41,7 @@ TEST(HttpCookie, Simple) { const auto* const expected2 = "name1=value1; Domain=domain.com; Path=/; Expires=Wed, 12 Jun 2019 " "16:51:45 " -#if defined(BSD) && !defined(__APPLE__) - "UTC; " -#else - "GMT; " -#endif + USERVER_IMPL_HTTP_COOKIE_TIMEZONE "Max-Age=3600; Secure; SameSite=None; HttpOnly"; EXPECT_EQ(cookie.ToString(), expected2); diff --git a/kafka/tests/producer_kafkatest.cpp b/kafka/tests/producer_kafkatest.cpp index 60432f67e299..fe6085707083 100644 --- a/kafka/tests/producer_kafkatest.cpp +++ b/kafka/tests/producer_kafkatest.cpp @@ -252,13 +252,14 @@ UTEST_F(ProducerTest, MessageTimeout) { } } +// Test flaps on GithubCI #ifndef ARCADIA_ROOT - // Test flaps on GithubCI - GTEST_SKIP() +#define USERVER_IMPL_KAFKA_TRIGGER_FAILURES_RESULT GTEST_SKIP() #else - FAIL() +#define USERVER_IMPL_KAFKA_TRIGGER_FAILURES_RESULT FAIL() #endif - << "Failed to trigger failures after " << kMaxRetries << " retries."; + + USERVER_IMPL_KAFKA_TRIGGER_FAILURES_RESULT << "Failed to trigger failures after " << kMaxRetries << " retries."; } UTEST_F(ProducerTest, FullQueueBulk) { diff --git a/libraries/grpc-reflection/src/grpc-reflection/proto_server_reflection.cpp b/libraries/grpc-reflection/src/grpc-reflection/proto_server_reflection.cpp index ad1f631fb76f..ed8c41fdca8e 100644 --- a/libraries/grpc-reflection/src/grpc-reflection/proto_server_reflection.cpp +++ b/libraries/grpc-reflection/src/grpc-reflection/proto_server_reflection.cpp @@ -22,6 +22,7 @@ #include #include +#include #include #include @@ -36,6 +37,18 @@ USERVER_NAMESPACE_BEGIN namespace grpc_reflection { +namespace { + +auto ToDescriptorLookupName(std::string_view name) { +#if GOOGLE_PROTOBUF_VERSION >= 4022000 + return name; +#else + return std::string{name}; +#endif +} + +} // namespace + ProtoServerReflection::ProtoServerReflection() : descriptor_pool_(grpc::protobuf::DescriptorPool::generated_pool()) {} void ProtoServerReflection::AddService(std::string_view service) { @@ -115,12 +128,9 @@ ProtoServerReflection::GetFileByName(std::string_view file_name, proto_reflectio return ::grpc::Status::CANCELLED; } - const grpc::protobuf::FileDescriptor* file_desc = -#if GOOGLE_PROTOBUF_VERSION >= 4022000 - descriptor_pool_->FindFileByName(file_name); -#else - descriptor_pool_->FindFileByName(std::string{file_name}); -#endif + const grpc::protobuf::FileDescriptor* file_desc = descriptor_pool_->FindFileByName( + ToDescriptorLookupName(file_name) + ); if (file_desc == nullptr) { return ::grpc::Status(::grpc::StatusCode::NOT_FOUND, "File not found."); } @@ -137,11 +147,9 @@ ::grpc::Status ProtoServerReflection::GetFileContainingSymbol( return ::grpc::Status::CANCELLED; } -#if GOOGLE_PROTOBUF_VERSION >= 4022000 - const grpc::protobuf::FileDescriptor* file_desc = descriptor_pool_->FindFileContainingSymbol(symbol); -#else - const grpc::protobuf::FileDescriptor* file_desc = descriptor_pool_->FindFileContainingSymbol(std::string{symbol}); -#endif + const grpc::protobuf::FileDescriptor* file_desc = descriptor_pool_->FindFileContainingSymbol( + ToDescriptorLookupName(symbol) + ); if (file_desc == nullptr) { return ::grpc::Status(::grpc::StatusCode::NOT_FOUND, "Symbol not found."); } @@ -181,11 +189,7 @@ ::grpc::Status ProtoServerReflection::GetAllExtensionNumbers( return ::grpc::Status::CANCELLED; } -#if GOOGLE_PROTOBUF_VERSION >= 4022000 - const grpc::protobuf::Descriptor* desc = descriptor_pool_->FindMessageTypeByName(type); -#else - const grpc::protobuf::Descriptor* desc = descriptor_pool_->FindMessageTypeByName(std::string{type}); -#endif + const grpc::protobuf::Descriptor* desc = descriptor_pool_->FindMessageTypeByName(ToDescriptorLookupName(type)); if (desc == nullptr) { return ::grpc::Status(::grpc::StatusCode::NOT_FOUND, "Type not found."); } diff --git a/mongo/src/storages/mongo/cdriver/pool_impl.cpp b/mongo/src/storages/mongo/cdriver/pool_impl.cpp index 7e8ef95d3389..f3ff270d37b9 100644 --- a/mongo/src/storages/mongo/cdriver/pool_impl.cpp +++ b/mongo/src/storages/mongo/cdriver/pool_impl.cpp @@ -215,6 +215,22 @@ void HeartbeatFailed(const mongoc_apm_server_heartbeat_failed_t* event) { HeartbeatFinished(stats); } +bool HasReadableServer(const mongoc_topology_description_t* td, mongoc_read_prefs_t* prefs) { +#if MONGOC_CHECK_VERSION(1, 17, 0) + return mongoc_topology_description_has_readable_server(td, prefs); +#else + return mongoc_topology_description_has_readable_server(const_cast(td), prefs); +#endif +} + +bool HasWritableServer(const mongoc_topology_description_t* td) { +#if MONGOC_CHECK_VERSION(1, 17, 0) + return mongoc_topology_description_has_writable_server(td); +#else + return mongoc_topology_description_has_writable_server(const_cast(td)); +#endif +} + std::string CreateTopologyChangeMessage(const mongoc_apm_topology_changed_t* event) { const mongoc_topology_description_t* prev_td = mongoc_apm_topology_changed_get_previous_description(event); const mongoc_topology_description_t* new_td = mongoc_apm_topology_changed_get_new_description(event); @@ -261,21 +277,13 @@ std::string CreateTopologyChangeMessage(const mongoc_apm_topology_changed_t* eve mongoc_read_prefs_t* prefs = mongoc_read_prefs_new(MONGOC_READ_SECONDARY); const utils::FastScopeGuard prefs_guard{[&prefs]() noexcept { mongoc_read_prefs_destroy(prefs); }}; -#if MONGOC_CHECK_VERSION(1, 17, 0) - if (mongoc_topology_description_has_readable_server(new_td, prefs)) { -#else - if (mongoc_topology_description_has_readable_server(const_cast(new_td), prefs)) { -#endif + if (HasReadableServer(new_td, prefs)) { topology_msg.append("\nSecondary AVAILABLE\n"); } else { topology_msg.append("\nSecondary UNAVAILABLE\n"); } -#if MONGOC_CHECK_VERSION(1, 17, 0) - if (mongoc_topology_description_has_writable_server(new_td)) { -#else - if (mongoc_topology_description_has_writable_server(const_cast(new_td))) { -#endif + if (HasWritableServer(new_td)) { topology_msg.append("Primary AVAILABLE"); } else { topology_msg.append("Primary UNAVAILABLE"); diff --git a/postgresql/pq-extra/pq_portal_funcs.c b/postgresql/pq-extra/pq_portal_funcs.c index 4524ed79dd35..f86b27187bf0 100644 --- a/postgresql/pq-extra/pq_portal_funcs.c +++ b/postgresql/pq-extra/pq_portal_funcs.c @@ -48,6 +48,60 @@ static int pqxPutMsgStart3(char msg_type, PGconn* conn) { } #endif +#if PG_VERSION_NUM < 140000 +typedef struct PGcmdQueueEntry PGcmdQueueEntry; +#endif + +static int PqxAnotherCommandInProgress(PGconn* conn) { +#if PG_VERSION_NUM >= 140000 + return conn->asyncStatus != PGASYNC_IDLE && + conn->pipelineStatus == PQ_PIPELINE_OFF; +#else + return conn->asyncStatus != PGASYNC_IDLE; +#endif +} + +static int PqxTransactionIsNeeded(PGconn* conn) { +#if PG_VERSION_NUM >= 140000 + return conn->xactStatus != PQTRANS_INTRANS && + (conn->pipelineStatus == PQ_PIPELINE_OFF || + conn->asyncStatus == PGASYNC_IDLE); +#else + return conn->xactStatus != PQTRANS_INTRANS; +#endif +} + +static int PqxShouldSendSync(PGconn* conn) { +#if PG_VERSION_NUM >= 140000 + return conn->pipelineStatus == PQ_PIPELINE_OFF; +#else + (void)conn; + return 1; +#endif +} + +static int PqxFlush(PGconn* conn) { +#if PG_VERSION_NUM >= 140000 + return pqPipelineFlush(conn); +#else + return pqFlush(conn); +#endif +} + +static void PqxInitAsyncResult(PGconn* conn) { + pqClearAsyncResult(conn); + conn->singleRowMode = false; +} + +static void PqxRecycleCmdQueueEntry(PGconn* conn, PGcmdQueueEntry* entry) { +#if PG_VERSION_NUM >= 140000 + pqRecycleCmdQueueEntry(conn, entry); +#else + (void)conn; + (void)entry; +#endif +} + /* * Common startup code for PQsendQuery and sibling routines * @@ -76,11 +130,7 @@ static bool PQXsendQueryStart(PGconn* conn) { } /* Can't send while already busy, either, unless enqueuing for later */ - if (conn->asyncStatus != PGASYNC_IDLE -#if PG_VERSION_NUM >= 140000 - && conn->pipelineStatus == PQ_PIPELINE_OFF -#endif - ) { + if (PqxAnotherCommandInProgress(conn)) { updatePQXExpBufferStr( &conn->errorMessage, libpq_gettext("another command is already in progress\n")); @@ -119,18 +169,11 @@ static bool PQXsendQueryStart(PGconn* conn) { return false; } } else { + PqxInitAsyncResult(conn); + } #else - { + PqxInitAsyncResult(conn); #endif - /* - * This command's results will come in immediately. Initialize async - * result-accumulation state - */ - pqClearAsyncResult(conn); - - /* reset single-row processing mode */ - conn->singleRowMode = false; - } /* ready to send command message */ return true; } @@ -169,20 +212,15 @@ int PQXSendPortalBind(PGconn* conn, const char* stmt_name, * used in transaction blocks. If that is not the case, the portal will not be * created and the exception will be thrown on an attempt to fetch data. */ - if (conn->xactStatus != PQTRANS_INTRANS -#if PG_VERSION_NUM >= 140000 - && (conn->pipelineStatus == PQ_PIPELINE_OFF || - conn->asyncStatus == PGASYNC_IDLE) -#endif - ) { + if (PqxTransactionIsNeeded(conn)) { updatePQXExpBufferStr(&conn->errorMessage, "a transaction is needed for a portal to work\n"); return 0; } -#if PG_VERSION_NUM >= 140000 - PGcmdQueueEntry* entry; + PGcmdQueueEntry* entry = NULL; +#if PG_VERSION_NUM >= 140000 entry = pqAllocCmdQueueEntry(conn); if (entry == NULL) return 0; /* error msg already set */ #endif @@ -237,10 +275,7 @@ int PQXSendPortalBind(PGconn* conn, const char* stmt_name, if (pqPutMsgEnd(conn) < 0) goto sendFailed; /* construct the Sync message if not in pipeline mode */ -#if PG_VERSION_NUM >= 140000 - if (conn->pipelineStatus == PQ_PIPELINE_OFF) -#endif - { + if (PqxShouldSendSync(conn)) { if (pqxPutMsgStart3('S', conn) < 0 || pqPutMsgEnd(conn) < 0) goto sendFailed; } @@ -261,11 +296,7 @@ int PQXSendPortalBind(PGconn* conn, const char* stmt_name, * threshold). In nonblock mode, don't complain if we're unable to send * it all; PQgetResult() will do any additional flushing needed. */ -#if PG_VERSION_NUM >= 140000 - if (pqPipelineFlush(conn) < 0) -#else - if (pqFlush(conn) < 0) -#endif + if (PqxFlush(conn) < 0) goto sendFailed; /* OK, it's launched! */ @@ -277,9 +308,7 @@ int PQXSendPortalBind(PGconn* conn, const char* stmt_name, return 1; sendFailed: -#if PG_VERSION_NUM >= 140000 - pqRecycleCmdQueueEntry(conn, entry); -#endif + PqxRecycleCmdQueueEntry(conn, entry); /* error message should be set up already */ return 0; } @@ -303,9 +332,9 @@ int PQXSendPortalExecute(PGconn* conn, const char* portal_name, int n_rows) { return 0; } -#if PG_VERSION_NUM >= 140000 - PGcmdQueueEntry* entry; + PGcmdQueueEntry* entry = NULL; +#if PG_VERSION_NUM >= 140000 entry = pqAllocCmdQueueEntry(conn); if (entry == NULL) return 0; /* error msg already set */ #endif @@ -321,10 +350,7 @@ int PQXSendPortalExecute(PGconn* conn, const char* portal_name, int n_rows) { goto sendFailed; /* construct the Sync message if not in pipeline mode */ -#if PG_VERSION_NUM >= 140000 - if (conn->pipelineStatus == PQ_PIPELINE_OFF) -#endif - { + if (PqxShouldSendSync(conn)) { if (pqxPutMsgStart3('S', conn) < 0 || pqPutMsgEnd(conn) < 0) goto sendFailed; } @@ -345,11 +371,7 @@ int PQXSendPortalExecute(PGconn* conn, const char* portal_name, int n_rows) { * threshold). In nonblock mode, don't complain if we're unable to send * it all; PQgetResult() will do any additional flushing needed. */ -#if PG_VERSION_NUM >= 140000 - if (pqPipelineFlush(conn) < 0) -#else - if (pqFlush(conn) < 0) -#endif + if (PqxFlush(conn) < 0) goto sendFailed; /* OK, it's launched! */ @@ -361,9 +383,7 @@ int PQXSendPortalExecute(PGconn* conn, const char* portal_name, int n_rows) { return 1; sendFailed: -#if PG_VERSION_NUM >= 140000 - pqRecycleCmdQueueEntry(conn, entry); -#endif + PqxRecycleCmdQueueEntry(conn, entry); /* error message should be set up already */ return 0; } diff --git a/postgresql/pq-extra/pq_workaround.c b/postgresql/pq-extra/pq_workaround.c index 597390da4a21..9f3f0eef0ece 100644 --- a/postgresql/pq-extra/pq_workaround.c +++ b/postgresql/pq-extra/pq_workaround.c @@ -144,6 +144,82 @@ static int getParameterStatus(PGconn* conn) { return 0; } +static int PqxShouldReturnOnIdlePipeline(PGconn* conn) { +#if PG_VERSION_NUM >= 140000 && PG_VERSION_NUM < 140005 + return conn->pipelineStatus != PQ_PIPELINE_OFF && + conn->cmd_queue_head != NULL; +#else + (void)conn; + return 0; +#endif +} + +static int PqxCurrentQueryClassIs(PGconn* conn, int queryclass) { +#if PG_VERSION_NUM >= 140000 + return conn->cmd_queue_head && + conn->cmd_queue_head->queryclass == queryclass; +#else + return conn->queryclass == queryclass; +#endif +} + +static int PqxRowDescriptionIsDescribe(PGconn* conn) { +#if PG_VERSION_NUM >= 140000 + return !conn->cmd_queue_head || + conn->cmd_queue_head->queryclass == PGQUERY_DESCRIBE; +#else + return conn->queryclass == PGQUERY_DESCRIBE; +#endif +} + +static void PqxHandleSyncResponse(PGconn* conn) { +#if PG_VERSION_NUM >= 140000 + if (conn->pipelineStatus != PQ_PIPELINE_OFF) { + conn->result = PQmakeEmptyPGresult(conn, PGRES_PIPELINE_SYNC); + if (!conn->result) { + appendPQExpBufferStr(&conn->errorMessage, + libpq_gettext("out of memory")); + pqSaveErrorResult(conn); + } else { + conn->pipelineStatus = PQ_PIPELINE_ON; + conn->asyncStatus = PGASYNC_READY; + } + return; + } + + /* Advance the command queue and set us idle */ + pqCommandQueueAdvanceGlue(conn, true, false); +#endif + conn->asyncStatus = PGASYNC_IDLE; +} + +static void PqxMaybeHandleBindComplete(PGconn* conn) { +#if PG_VERSION_NUM >= 140000 + if (conn->cmd_queue_head && + conn->cmd_queue_head->queryclass == PGXQUERY_BIND) { + pqCommandQueueAdvanceGlue(conn, false, false); + if (conn->pipelineStatus != PQ_PIPELINE_OFF) { +#if PG_VERSION_NUM >= 140005 + conn->asyncStatus = PGASYNC_PIPELINE_IDLE; +#else + conn->asyncStatus = PGASYNC_IDLE; +#endif + } + } +#else + (void)conn; +#endif +} + +static void PqxTraceOutputMessage(PGconn* conn) { +#if PG_VERSION_NUM >= 140000 + if (conn->Pfdebug) + pqTraceOutputMessage(conn, conn->inBuffer + conn->inStart, false); +#else + (void)conn; +#endif +} + /* * This is copy-paste of pqParseInput3 from fe-protocol3.c, with added * handling of `portal suspended` server message @@ -234,7 +310,6 @@ static void pqxParseInput3(PGconn* conn, const PGresult* description) { /* If not IDLE state, just wait ... */ if (conn->asyncStatus != PGASYNC_IDLE) return; -#if PG_VERSION_NUM >= 140000 && PG_VERSION_NUM < 140005 /* * We're also notionally not-IDLE when in pipeline mode the state * says "idle" (so we have completed receiving the results of one @@ -243,10 +318,8 @@ static void pqxParseInput3(PGconn* conn, const PGresult* description) { * that they can initiate processing of the next query in the * queue. */ - if (conn->pipelineStatus != PQ_PIPELINE_OFF && - conn->cmd_queue_head != NULL) + if (PqxShouldReturnOnIdlePipeline(conn)) return; -#endif /* * Unexpected message in IDLE state; need to recover somehow. @@ -304,25 +377,7 @@ static void pqxParseInput3(PGconn* conn, const PGresult* description) { case 'Z': /* sync response, backend is ready for new * query */ if (getReadyForQuery(conn)) return; -#if PG_VERSION_NUM >= 140000 - if (conn->pipelineStatus != PQ_PIPELINE_OFF) { - conn->result = PQmakeEmptyPGresult(conn, PGRES_PIPELINE_SYNC); - if (!conn->result) { - appendPQExpBufferStr(&conn->errorMessage, - libpq_gettext("out of memory")); - pqSaveErrorResult(conn); - } else { - conn->pipelineStatus = PQ_PIPELINE_ON; - conn->asyncStatus = PGASYNC_READY; - } - } else { - /* Advance the command queue and set us idle */ - pqCommandQueueAdvanceGlue(conn, true, false); -#else - { -#endif - conn->asyncStatus = PGASYNC_IDLE; - } + PqxHandleSyncResponse(conn); break; case 'I': /* empty query */ if (conn->result == NULL) { @@ -337,12 +392,7 @@ static void pqxParseInput3(PGconn* conn, const PGresult* description) { break; case '1': /* Parse Complete */ /* If we're doing PQprepare, we're done; else ignore */ -#if PG_VERSION_NUM >= 140000 - if (conn->cmd_queue_head && - conn->cmd_queue_head->queryclass == PGQUERY_PREPARE) { -#else - if (conn->queryclass == PGQUERY_PREPARE) { -#endif + if (PqxCurrentQueryClassIs(conn, PGQUERY_PREPARE)) { if (conn->result == NULL) { conn->result = PQmakeEmptyPGresult(conn, PGRES_COMMAND_OK); if (!conn->result) { @@ -355,26 +405,7 @@ static void pqxParseInput3(PGconn* conn, const PGresult* description) { } break; case '2': /* Bind Complete */ -#if PG_VERSION_NUM >= 140000 - if (conn->cmd_queue_head && - conn->cmd_queue_head->queryclass == PGXQUERY_BIND) { - pqCommandQueueAdvanceGlue(conn, false, false); -#else - if (conn->queryclass == PGXQUERY_BIND) { -#endif - /* - In case of portal bind, only in pipeline mode - the query ends here without a result - */ -#if PG_VERSION_NUM >= 140000 - if (conn->pipelineStatus != PQ_PIPELINE_OFF) -#if PG_VERSION_NUM >= 140005 - conn->asyncStatus = PGASYNC_PIPELINE_IDLE; -#else - conn->asyncStatus = PGASYNC_IDLE; -#endif -#endif - } + PqxMaybeHandleBindComplete(conn); break; case '3': /* Close Complete */ #if PG_VERSION_NUM >= 140005 @@ -419,12 +450,7 @@ static void pqxParseInput3(PGconn* conn, const PGresult* description) { */ conn->inCursor += msgLength; } else if (conn->result == NULL || -#if PG_VERSION_NUM >= 140000 - (conn->cmd_queue_head && - conn->cmd_queue_head->queryclass == PGQUERY_DESCRIBE)) { -#else - conn->queryclass == PGQUERY_DESCRIBE) { -#endif + PqxCurrentQueryClassIs(conn, PGQUERY_DESCRIBE)) { /* First 'T' in a query sequence */ if (getRowDescriptions(conn, msgLength)) return; } else { @@ -451,12 +477,7 @@ static void pqxParseInput3(PGconn* conn, const PGresult* description) { * instead of PGRES_TUPLES_OK. Otherwise we can just * ignore this message. */ -#if PG_VERSION_NUM >= 140000 - if (conn->cmd_queue_head && - conn->cmd_queue_head->queryclass == PGQUERY_DESCRIBE) { -#else - if (conn->queryclass == PGQUERY_DESCRIBE) { -#endif + if (PqxCurrentQueryClassIs(conn, PGQUERY_DESCRIBE)) { if (conn->result == NULL) { conn->result = PQmakeEmptyPGresult(conn, PGRES_COMMAND_OK); if (!conn->result) { @@ -568,11 +589,8 @@ static void pqxParseInput3(PGconn* conn, const PGresult* description) { } /* Successfully consumed this message */ if (conn->inCursor == conn->inStart + 5 + msgLength) { -#if PG_VERSION_NUM >= 140000 /* trace server-to-client message */ - if (conn->Pfdebug) - pqTraceOutputMessage(conn, conn->inBuffer + conn->inStart, false); -#endif + PqxTraceOutputMessage(conn); /* Normal case: parsing agrees with specified length */ conn->inStart = conn->inCursor; } else { @@ -1067,13 +1085,7 @@ static int getRowDescriptions(PGconn* conn, int msgLength) { * PGresult created by getParamDescriptions, and we should fill data into * that. Otherwise, create a new, empty PGresult. */ -#if PG_VERSION_NUM >= 140000 - if (!conn->cmd_queue_head || - (conn->cmd_queue_head && - conn->cmd_queue_head->queryclass == PGQUERY_DESCRIBE)) { -#else - if (conn->queryclass == PGQUERY_DESCRIBE) { -#endif + if (PqxRowDescriptionIsDescribe(conn)) { if (conn->result) result = conn->result; else @@ -1156,13 +1168,7 @@ static int getRowDescriptions(PGconn* conn, int msgLength) { * If we're doing a Describe, we're done, and ready to pass the result * back to the client. */ -#if PG_VERSION_NUM >= 140000 - if ((!conn->cmd_queue_head) || - (conn->cmd_queue_head && - conn->cmd_queue_head->queryclass == PGQUERY_DESCRIBE)) { -#else - if (conn->queryclass == PGQUERY_DESCRIBE) { -#endif + if (PqxRowDescriptionIsDescribe(conn)) { conn->asyncStatus = PGASYNC_READY; return 0; } @@ -1784,4 +1790,3 @@ int PQXpipelinePutSync(PGconn* conn) { return 0; } #endif - diff --git a/postgresql/src/storages/postgres/detail/pg_connection_wrapper.cpp b/postgresql/src/storages/postgres/detail/pg_connection_wrapper.cpp index 868ad01835b0..fae618c78da2 100644 --- a/postgresql/src/storages/postgres/detail/pg_connection_wrapper.cpp +++ b/postgresql/src/storages/postgres/detail/pg_connection_wrapper.cpp @@ -573,9 +573,13 @@ ResultSet PGConnectionWrapper::WaitResult(Deadline deadline, tracing::ScopeTime& const auto status = PQresultStatus(pg_res); if (status == PGRES_PIPELINE_SYNC) { HandlePipelineSync(); - } else if (status != PGRES_PIPELINE_ABORTED) -#endif + } + if (status != PGRES_PIPELINE_SYNC && status != PGRES_PIPELINE_ABORTED) { handle = std::move(next_handle); + } +#else + handle = std::move(next_handle); +#endif } // There is an issue with libpq when db shuts down we may receive an error // instead of PGRES_PIPELINE_SYNC and never get out of this cycle, hence diff --git a/universal/include/userver/compiler/select.hpp b/universal/include/userver/compiler/select.hpp index 5922cf586417..4d70db3d467c 100644 --- a/universal/include/userver/compiler/select.hpp +++ b/universal/include/userver/compiler/select.hpp @@ -65,11 +65,10 @@ class SelectValue final { constexpr auto kBits = (sizeof(void*) == 8 ? Bits::k64 : Bits::k32); constexpr auto kLib = #if defined(_LIBCPP_VERSION) - StdLibs::kCpp + StdLibs::kCpp; #else - StdLibs::kStdCpp + StdLibs::kStdCpp; #endif - ; if (bits == kBits) { if (lib == kLib) { diff --git a/universal/include/userver/utils/from_string.hpp b/universal/include/userver/utils/from_string.hpp index a147a493687b..ea3c4c10fb37 100644 --- a/universal/include/userver/utils/from_string.hpp +++ b/universal/include/userver/utils/from_string.hpp @@ -69,15 +69,18 @@ class FromStringException : public std::runtime_error { namespace impl { template -concept IsFromCharsConvertible = - requires(T& v) { std::from_chars(std::declval(), std::declval(), v); } && +concept IsFromCharsCorrectlySupported = #if defined(_GLIBCXX_RELEASE) && _GLIBCXX_RELEASE < 13 // libstdc++ before 13.1 parse long double incorrectly - !std::same_as + !std::same_as; #else - true + true; #endif - ; + +template +concept IsFromCharsConvertible = + requires(T& v) { std::from_chars(std::declval(), std::declval(), v); } && + IsFromCharsCorrectlySupported; [[noreturn]] void ThrowFromStringException( FromStringErrorCode code, diff --git a/universal/src/crypto/ssl_ctx.cpp b/universal/src/crypto/ssl_ctx.cpp index fa107971295b..116c72856d69 100644 --- a/universal/src/crypto/ssl_ctx.cpp +++ b/universal/src/crypto/ssl_ctx.cpp @@ -46,12 +46,15 @@ std::unique_ptr SslCtx::Impl::MakeSslCtx() { } #endif - constexpr auto options = - SSL_OP_ALL | SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_COMPRESSION + constexpr auto kSslOpNoRenegotiation = #if OPENSSL_VERSION_NUMBER >= 0x010100000L - | SSL_OP_NO_RENEGOTIATION + SSL_OP_NO_RENEGOTIATION; +#else + 0; #endif - ; + + constexpr auto options = + SSL_OP_ALL | SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_COMPRESSION | kSslOpNoRenegotiation; SSL_CTX_set_options(ssl_ctx, options); SSL_CTX_set_mode(ssl_ctx, SSL_MODE_ENABLE_PARTIAL_WRITE); SSL_CTX_clear_mode(ssl_ctx, SSL_MODE_AUTO_RETRY); diff --git a/universal/utest/src/utest/current_process_open_files_test.cpp b/universal/utest/src/utest/current_process_open_files_test.cpp index b50fcd751235..350e4b94acf4 100644 --- a/universal/utest/src/utest/current_process_open_files_test.cpp +++ b/universal/utest/src/utest/current_process_open_files_test.cpp @@ -21,10 +21,12 @@ constexpr std::string_view kTestFilePart = "test_files_listing_of_current_proc"; // non-closed file descriptors. #if defined(BSD) // /dev/fd/* are not symlinks -TEST(DISABLED_CurrentProcessOpenFiles, Basic) { +#define USERVER_IMPL_CURRENT_PROCESS_OPEN_FILES DISABLED_CurrentProcessOpenFiles #else -TEST(CurrentProcessOpenFiles, Basic) { +#define USERVER_IMPL_CURRENT_PROCESS_OPEN_FILES CurrentProcessOpenFiles #endif + +TEST(USERVER_IMPL_CURRENT_PROCESS_OPEN_FILES, Basic) { const auto file_guard = fs::blocking::TempFile::Create("/tmp", kTestFilePart); const auto& path = file_guard.GetPath(); diff --git a/ydb/src/ydb/response.cpp b/ydb/src/ydb/response.cpp index 9fe1fdafff8f..fbfa34b13061 100644 --- a/ydb/src/ydb/response.cpp +++ b/ydb/src/ydb/response.cpp @@ -27,15 +27,23 @@ ParseState::ParseState(const NYdb::TResultSet& result_set) //////////////////////////////////////////////////////////////////////////////// -Row::Row(impl::ParseState& parse_state) - : parse_state_(parse_state) +namespace { + +std::vector MakeConsumedColumns(impl::ParseState& parse_state) { #ifndef NDEBUG - , - consumed_columns_(parse_state_.parser.ColumnsCount(), false) + return std::vector(parse_state.parser.ColumnsCount(), false); +#else + (void)parse_state; + return {}; #endif -{ } +} // namespace + +Row::Row(impl::ParseState& parse_state) + : parse_state_(parse_state), + consumed_columns_(MakeConsumedColumns(parse_state_)) {} + NYdb::TValueParser& Row::GetColumn(std::size_t index) { return parse_state_.parser.ColumnParser(index); } NYdb::TValueParser& Row::GetColumn(std::string_view name) {