diff --git a/include/quill/Logger.h b/include/quill/Logger.h index 649d8068..4e045149 100644 --- a/include/quill/Logger.h +++ b/include/quill/Logger.h @@ -368,8 +368,8 @@ class LoggerImpl : public detail::LoggerBase { // MSVC doesn't like the template keyword, but every other compiler requires it #if defined(_MSC_VER) - return thread_context->get_spsc_queue().prepare_write( - total_size); + return thread_context->get_spsc_queue().prepare_write( + total_size, frontend_options_t::queue_type); #else return thread_context->get_spsc_queue() .template prepare_write(total_size); diff --git a/include/quill/core/UnboundedSPSCQueue.h b/include/quill/core/UnboundedSPSCQueue.h index 8af5dcfe..deb2ded3 100644 --- a/include/quill/core/UnboundedSPSCQueue.h +++ b/include/quill/core/UnboundedSPSCQueue.h @@ -106,8 +106,13 @@ class UnboundedSPSCQueue * making it visible to the consumer. * @return a valid point to the buffer */ +#if defined(_MSC_VER) + // MSVC doesn't like this as template when called from Logger, while it compiles on MSVC there will be false positives from clang-tidy + QUILL_NODISCARD QUILL_ATTRIBUTE_HOT std::byte* prepare_write(size_t nbytes, QueueType queue_type) +#else template QUILL_NODISCARD QUILL_ATTRIBUTE_HOT std::byte* prepare_write(size_t nbytes) +#endif { // Try to reserve the bounded queue std::byte* write_pos = _producer->bounded_queue.prepare_write(nbytes); @@ -117,7 +122,11 @@ class UnboundedSPSCQueue return write_pos; } +#if defined(_MSC_VER) + return _handle_full_queue(nbytes, queue_type); +#else return _handle_full_queue(nbytes); +#endif } /** @@ -200,8 +209,12 @@ class UnboundedSPSCQueue private: /***/ +#if defined(_MSC_VER) + QUILL_NODISCARD std::byte* _handle_full_queue(size_t nbytes, QueueType queue_type) +#else template QUILL_NODISCARD std::byte* _handle_full_queue(size_t nbytes) +#endif { // Then it means the queue doesn't have enough size size_t capacity = _producer->bounded_queue.capacity() * 2ull; @@ -210,7 +223,11 @@ class UnboundedSPSCQueue capacity = capacity * 2ull; } +#if defined(_MSC_VER) + if ((queue_type == QueueType::UnboundedBlocking) || (queue_type == QueueType::UnboundedDropping)) +#else if constexpr ((queue_type == QueueType::UnboundedBlocking) || (queue_type == QueueType::UnboundedDropping)) +#endif { size_t constexpr max_bounded_queue_size = 2ull * 1024 * 1024 * 1024; // 2 GB diff --git a/test/unit_tests/UnboundedQueueLimitTest.cpp b/test/unit_tests/UnboundedQueueLimitTest.cpp index 6ddc7765..73913364 100644 --- a/test/unit_tests/UnboundedQueueLimitTest.cpp +++ b/test/unit_tests/UnboundedQueueLimitTest.cpp @@ -16,26 +16,46 @@ TEST_CASE("unbounded_queue_max_limit") constexpr static uint64_t half_gb = 500u * 1024u * 1024u; constexpr static uint64_t two_gb = 2u * 1024u * 1024u * 1024u - 1; +#if defined(_MSC_VER) + auto* write_buffer_a = buffer.prepare_write(half_gb, quill::QueueType::UnboundedUnlimited); +#else auto* write_buffer_a = buffer.prepare_write(half_gb); +#endif REQUIRE(write_buffer_a); buffer.finish_write(half_gb); buffer.commit_write(); +#if defined(_MSC_VER) + auto* write_buffer_b = buffer.prepare_write(two_gb, quill::QueueType::UnboundedUnlimited); +#else auto* write_buffer_b = buffer.prepare_write(two_gb); +#endif REQUIRE(write_buffer_b); buffer.finish_write(two_gb); buffer.commit_write(); // Buffer is filled with two GB here, we can try to reserve more to allocate another queue +#if defined(_MSC_VER) + auto* write_buffer_c = buffer.prepare_write(two_gb, quill::QueueType::UnboundedBlocking); +#else auto* write_buffer_c = buffer.prepare_write(two_gb); +#endif REQUIRE_FALSE(write_buffer_c); +#if defined(_MSC_VER) + write_buffer_c = buffer.prepare_write(two_gb, quill::QueueType::UnboundedDropping); +#else write_buffer_c = buffer.prepare_write(two_gb); +#endif REQUIRE_FALSE(write_buffer_c); // Buffer is filled with two GB here, we can try to reserve more to allocate another queue // for the UnboundedLimit queue +#if defined(_MSC_VER) + write_buffer_c = buffer.prepare_write(two_gb, quill::QueueType::UnboundedUnlimited); +#else write_buffer_c = buffer.prepare_write(two_gb); +#endif REQUIRE(write_buffer_c); buffer.finish_write(two_gb); buffer.commit_write(); diff --git a/test/unit_tests/UnboundedQueueTest.cpp b/test/unit_tests/UnboundedQueueTest.cpp index 95708667..b6899291 100644 --- a/test/unit_tests/UnboundedQueueTest.cpp +++ b/test/unit_tests/UnboundedQueueTest.cpp @@ -20,12 +20,20 @@ TEST_CASE("unbounded_queue_read_write_multithreaded_plain_ints") { for (uint32_t i = 0; i < 8192; ++i) { +#if defined(_MSC_VER) + auto* write_buffer = buffer.prepare_write(sizeof(uint32_t), quill::QueueType::UnboundedBlocking); +#else auto* write_buffer = buffer.prepare_write(sizeof(uint32_t)); +#endif while (!write_buffer) { std::this_thread::sleep_for(std::chrono::microseconds{2}); +#if defined(_MSC_VER) + write_buffer = buffer.prepare_write(sizeof(uint32_t), quill::QueueType::UnboundedBlocking); +#else write_buffer = buffer.prepare_write(sizeof(uint32_t)); +#endif } std::memcpy(write_buffer, &i, sizeof(uint32_t));