diff options
-rw-r--r-- | include/cru/common/Buffer.h | 4 | ||||
-rw-r--r-- | include/cru/common/PreConfig.h | 2 | ||||
-rw-r--r-- | include/cru/common/io/AutoReadStream.h | 9 | ||||
-rw-r--r-- | include/cru/common/platform/unix/PosixSpawnSubProcess.h | 6 | ||||
-rw-r--r-- | include/cru/ui/document/TextDocumentElement.h | 2 | ||||
-rw-r--r-- | include/cru/ui/render/MeasureRequirement.h | 5 | ||||
-rw-r--r-- | src/common/Buffer.cpp | 66 | ||||
-rw-r--r-- | src/common/String.cpp | 2 | ||||
-rw-r--r-- | src/common/io/AutoReadStream.cpp | 9 | ||||
-rw-r--r-- | src/common/io/BufferStream.cpp | 4 | ||||
-rw-r--r-- | src/common/io/Stream.cpp | 1 | ||||
-rw-r--r-- | src/common/log/Logger.cpp | 3 | ||||
-rw-r--r-- | src/common/platform/unix/PosixSpawnSubProcess.cpp | 16 | ||||
-rw-r--r-- | src/platform/CMakeLists.txt | 2 | ||||
-rw-r--r-- | test/common/SubProcessTest.cpp | 2 |
15 files changed, 114 insertions, 19 deletions
diff --git a/include/cru/common/Buffer.h b/include/cru/common/Buffer.h index 2c3b7b87..bc2e2a26 100644 --- a/include/cru/common/Buffer.h +++ b/include/cru/common/Buffer.h @@ -91,6 +91,8 @@ class Buffer final { Index PushBack(const std::byte* other, Index other_size, bool use_memmove = false); + void PushBackCount(Index count); + /** * @brief Move forward the used-begin ptr. * @return The actual size moved forward. @@ -146,6 +148,8 @@ class Buffer final { void Move_(Buffer&& other) noexcept; void Delete_() noexcept; + void AssertValid(); + private: std::byte* ptr_; Index size_; diff --git a/include/cru/common/PreConfig.h b/include/cru/common/PreConfig.h index ba0f5bd8..3f26c589 100644 --- a/include/cru/common/PreConfig.h +++ b/include/cru/common/PreConfig.h @@ -1,3 +1,5 @@ +// IWYU pragma: always_keep + #pragma once #ifdef _MSC_VER diff --git a/include/cru/common/io/AutoReadStream.h b/include/cru/common/io/AutoReadStream.h index 4ba4066f..2887b319 100644 --- a/include/cru/common/io/AutoReadStream.h +++ b/include/cru/common/io/AutoReadStream.h @@ -1,11 +1,9 @@ #pragma once -#include "../Buffer.h" +#include "../SelfResolvable.h" #include "BufferStream.h" #include "Stream.h" -#include <condition_variable> -#include <list> #include <mutex> #include <thread> @@ -33,7 +31,8 @@ struct AutoReadStreamOptions { * @brief A stream that wraps another stream and auto read it into a buffer in a * background thread. */ -class CRU_BASE_API AutoReadStream : public Stream { +class CRU_BASE_API AutoReadStream : public Stream, + public SelfResolvable<AutoReadStream> { public: /** * @brief Wrap a stream and auto read it in background. @@ -71,7 +70,5 @@ class CRU_BASE_API AutoReadStream : public Stream { Index size_per_read_; std::unique_ptr<BufferStream> buffer_stream_; std::mutex buffer_stream_mutex_; - - std::thread background_thread_; }; } // namespace cru::io diff --git a/include/cru/common/platform/unix/PosixSpawnSubProcess.h b/include/cru/common/platform/unix/PosixSpawnSubProcess.h index 249b8043..9c303700 100644 --- a/include/cru/common/platform/unix/PosixSpawnSubProcess.h +++ b/include/cru/common/platform/unix/PosixSpawnSubProcess.h @@ -2,7 +2,9 @@ #include "../../PreConfig.h" -#ifdef CRU_PLATFORM_UNIX +#ifndef CRU_PLATFORM_UNIX +#error "This file can only be included on unix." +#endif #include "../../Base.h" #include "../../SubProcess.h" @@ -46,5 +48,3 @@ class PosixSpawnSubProcess : public PlatformSubProcessBase { std::unique_ptr<io::AutoReadStream> stderr_buffer_stream_; }; } // namespace cru::platform::unix - -#endif diff --git a/include/cru/ui/document/TextDocumentElement.h b/include/cru/ui/document/TextDocumentElement.h index f7205b59..93b4933b 100644 --- a/include/cru/ui/document/TextDocumentElement.h +++ b/include/cru/ui/document/TextDocumentElement.h @@ -13,7 +13,7 @@ struct TextStyleTag {}; using TextStyle = Bitmask<details::TextStyleTag>; struct TextStyles { - static constexpr TextStyle Normal; + static constexpr TextStyle Normal{0x0}; static constexpr TextStyle Bold{0x1}; static constexpr TextStyle Italic{0x2}; }; diff --git a/include/cru/ui/render/MeasureRequirement.h b/include/cru/ui/render/MeasureRequirement.h index 832b936c..ace52ef6 100644 --- a/include/cru/ui/render/MeasureRequirement.h +++ b/include/cru/ui/render/MeasureRequirement.h @@ -24,14 +24,11 @@ class MeasureLength final { constexpr MeasureLength() : MeasureLength(tag_not_specify) {} constexpr MeasureLength(tag_not_specify_t) : length_(-1) {} - constexpr MeasureLength(float length) : length_(length) { - Expects(length >= 0); - } + constexpr MeasureLength(float length) : length_(length) {} MeasureLength(const MeasureLength& other) = default; constexpr MeasureLength& operator=(const MeasureLength& other) = default; constexpr MeasureLength& operator=(float length) { - Expects(length >= 0); length_ = length; return *this; } diff --git a/src/common/Buffer.cpp b/src/common/Buffer.cpp index e37fddc7..7b4248c7 100644 --- a/src/common/Buffer.cpp +++ b/src/common/Buffer.cpp @@ -27,6 +27,7 @@ Buffer::Buffer(Index size) { size_ = size; used_begin_ = used_end_ = 0; } + AssertValid(); } Buffer::Buffer(const Buffer& other) { Copy_(other); } @@ -53,13 +54,20 @@ Buffer::~Buffer() { Delete_(); } void Buffer::AssignBytes(Index dst_offset, std::byte* src, Index src_offset, Index src_size, bool use_memmove) { + CheckSize(src_size); + + AssertValid(); + (use_memmove ? std::memmove : std::memcpy)(ptr_ + dst_offset, src + src_offset, src_size); + AssertValid(); } void Buffer::ResizeBuffer(Index new_size, bool preserve_used) { CheckSize(new_size); + AssertValid(); + if (new_size == 0) { Delete_(); ptr_ = nullptr; @@ -81,12 +89,16 @@ void Buffer::ResizeBuffer(Index new_size, bool preserve_used) { } delete[] old_ptr; } + + AssertValid(); } Index Buffer::PushFront(const std::byte* other, Index other_size, bool use_memmove) { CheckSize(other_size); + AssertValid(); + auto copy_size = std::min(used_begin_, other_size); if (copy_size) { @@ -95,15 +107,19 @@ Index Buffer::PushFront(const std::byte* other, Index other_size, copy_size); } + AssertValid(); + return copy_size; } bool Buffer::PushBack(std::byte b) { + AssertValid(); if (IsUsedReachEnd()) { return false; } ptr_[used_end_] = b; used_end_++; + AssertValid(); return true; } @@ -111,6 +127,8 @@ Index Buffer::PushBack(const std::byte* other, Index other_size, bool use_memmove) { CheckSize(other_size); + AssertValid(); + auto copy_size = std::min(size_ - used_end_, other_size); if (copy_size) { @@ -119,20 +137,36 @@ Index Buffer::PushBack(const std::byte* other, Index other_size, used_end_ += copy_size; } + AssertValid(); + return copy_size; } +void Buffer::PushBackCount(Index count) { + if (count < 0 || count > GetBackFree()) { + throw Exception(u"Count out of range in PushBackCount."); + } + used_end_ += count; +} + Index Buffer::PopFront(Index size) { CheckSize(size); + AssertValid(); + auto move = std::min(used_begin_, size); used_begin_ -= move; + + AssertValid(); + return move; } Index Buffer::PopFront(std::byte* buffer, Index size, bool use_memmove) { CheckSize(size); + AssertValid(); + auto pop_size = std::min(GetUsedSize(), size); if (pop_size) { @@ -141,16 +175,29 @@ Index Buffer::PopFront(std::byte* buffer, Index size, bool use_memmove) { buffer, GetUsedBeginPtr() - pop_size, pop_size); } + AssertValid(); + return pop_size; } Index Buffer::PopEnd(Index size) { + CheckSize(size); + + AssertValid(); + auto move = std::min(size_ - used_end_, size); used_end_ += move; + + AssertValid(); + return move; } Index Buffer::PopEnd(std::byte* buffer, Index size, bool use_memmove) { + CheckSize(size); + + AssertValid(); + auto pop_size = std::min(GetUsedSize(), size); if (pop_size) { @@ -159,16 +206,23 @@ Index Buffer::PopEnd(std::byte* buffer, Index size, bool use_memmove) { pop_size); } + AssertValid(); + return pop_size; } std::byte* Buffer::Detach(Index* size) { + AssertValid(); + auto ptr = this->ptr_; if (size) { *size = this->size_; } this->ptr_ = nullptr; this->size_ = this->used_begin_ = this->used_end_ = 0; + + AssertValid(); + return ptr; } @@ -184,6 +238,7 @@ void Buffer::Copy_(const Buffer& other) { std::memcpy(ptr_ + used_begin_, other.ptr_ + used_begin_, used_end_ - used_begin_); } + AssertValid(); } void Buffer::Move_(Buffer&& other) noexcept { @@ -193,6 +248,7 @@ void Buffer::Move_(Buffer&& other) noexcept { used_end_ = other.used_end_; other.ptr_ = nullptr; other.size_ = other.used_begin_ = other.used_end_ = 0; + AssertValid(); } void Buffer::Delete_() noexcept { @@ -201,6 +257,16 @@ void Buffer::Delete_() noexcept { } } +void Buffer::AssertValid() { + assert(size_ >= 0); + assert(used_begin_ >= 0); + assert(used_begin_ <= size_); + assert(used_end_ >= 0); + assert(used_end_ <= size_); + assert(used_end_ >= used_begin_); + assert((ptr_ == nullptr && size_ == 0) || (ptr_ != nullptr && size_ > 0)); +} + void swap(Buffer& left, Buffer& right) noexcept { using std::swap; swap(left.ptr_, right.ptr_); diff --git a/src/common/String.cpp b/src/common/String.cpp index 8736c775..ddfa03a9 100644 --- a/src/common/String.cpp +++ b/src/common/String.cpp @@ -560,7 +560,7 @@ Buffer StringView::ToUtf8Buffer(bool end_zero) const { if (end_zero) { push_back(0); } - return std::move(buffer); + return buffer; } int StringView::ParseToInt(Index* processed_characters_count, unsigned flags, diff --git a/src/common/io/AutoReadStream.cpp b/src/common/io/AutoReadStream.cpp index bc43fa81..bee944a5 100644 --- a/src/common/io/AutoReadStream.cpp +++ b/src/common/io/AutoReadStream.cpp @@ -9,7 +9,9 @@ AutoReadStream::AutoReadStream(Stream* stream, bool auto_delete, stream_ = stream; size_per_read_ = buffer_stream_options.GetBlockSizeOrDefault(); buffer_stream_ = std::make_unique<BufferStream>(buffer_stream_options); - background_thread_ = std::thread(&AutoReadStream::BackgroundThreadRun, this); + auto background_thread = + std::thread(&AutoReadStream::BackgroundThreadRun, this); + background_thread.detach(); } AutoReadStream::~AutoReadStream() { @@ -43,10 +45,15 @@ void AutoReadStream::Flush() { stream_->Flush(); } void AutoReadStream::Close() { stream_->Close(); } void AutoReadStream::BackgroundThreadRun() { + auto resolver = CreateResolver(); std::vector<std::byte> buffer(size_per_read_); while (true) { try { auto read = stream_->Read(buffer.data(), buffer.size()); + auto self = resolver.Resolve(); + if (!self) { + break; + } if (read == 0) { buffer_stream_->SetEof(); break; diff --git a/src/common/io/BufferStream.cpp b/src/common/io/BufferStream.cpp index 3060a608..242396cd 100644 --- a/src/common/io/BufferStream.cpp +++ b/src/common/io/BufferStream.cpp @@ -75,6 +75,10 @@ Index BufferStream::Write(const std::byte* buffer, Index offset, Index size) { Index written = 0; + if (empty) { + buffer_list_.push_back(Buffer(block_size_)); + } + while (true) { if (buffer_list_.back().GetBackFree() == 0) { if (max_block_count_ > 0 && buffer_list_.size() == max_block_count_) { diff --git a/src/common/io/Stream.cpp b/src/common/io/Stream.cpp index b2a67a18..97cfcf99 100644 --- a/src/common/io/Stream.cpp +++ b/src/common/io/Stream.cpp @@ -62,6 +62,7 @@ Buffer Stream::ReadToEnd(Index grow_size) { Buffer buffer(grow_size); while (true) { auto read = Read(buffer.GetUsedEndPtr(), buffer.GetBackFree()); + buffer.PushBackCount(read); if (read == 0) { break; } diff --git a/src/common/log/Logger.cpp b/src/common/log/Logger.cpp index 3964a5a0..4b07ed87 100644 --- a/src/common/log/Logger.cpp +++ b/src/common/log/Logger.cpp @@ -1,9 +1,8 @@ #include "cru/common/log/Logger.h" #include "cru/common/log/StdioLogTarget.h" -#include <array> -#include <cstdlib> #include <ctime> +#include <algorithm> #ifdef CRU_PLATFORM_WINDOWS #include "cru/common/platform/win/DebugLogTarget.h" diff --git a/src/common/platform/unix/PosixSpawnSubProcess.cpp b/src/common/platform/unix/PosixSpawnSubProcess.cpp index fba536e5..1d69f54a 100644 --- a/src/common/platform/unix/PosixSpawnSubProcess.cpp +++ b/src/common/platform/unix/PosixSpawnSubProcess.cpp @@ -107,6 +107,15 @@ void PosixSpawnSubProcess::PlatformCreateProcess() { error = posix_spawn_file_actions_adddup2( &file_actions, stderr_pipe_.GetOtherFileDescriptor(), STDERR_FILENO); check_error(u"Failed to call posix_spawn_file_actions_adddup2 on stderr."); + error = posix_spawn_file_actions_addclose( + &file_actions, stdin_pipe_.GetSelfFileDescriptor()); + check_error(u"Failed to call posix_spawn_file_actions_addclose on stdin."); + error = posix_spawn_file_actions_addclose( + &file_actions, stdout_pipe_.GetSelfFileDescriptor()); + check_error(u"Failed to call posix_spawn_file_actions_addclose on stdout."); + error = posix_spawn_file_actions_addclose( + &file_actions, stderr_pipe_.GetSelfFileDescriptor()); + check_error(u"Failed to call posix_spawn_file_actions_addclose on stderr."); posix_spawnattr_t attr; error = posix_spawnattr_init(&attr); @@ -131,6 +140,13 @@ void PosixSpawnSubProcess::PlatformCreateProcess() { error = posix_spawnp(&pid_, exe.c_str(), &file_actions, &attr, argv, envp); check_error(u"Failed to call posix_spawnp."); + + error = ::close(stdin_pipe_.GetOtherFileDescriptor()); + check_error(u"Failed to close stdin."); + error = ::close(stdout_pipe_.GetOtherFileDescriptor()); + check_error(u"Failed to close stdout."); + error = ::close(stderr_pipe_.GetOtherFileDescriptor()); + check_error(u"Failed to close stderr."); } SubProcessExitResult PosixSpawnSubProcess::PlatformWaitForProcess() { diff --git a/src/platform/CMakeLists.txt b/src/platform/CMakeLists.txt index 4779bb57..1ce55e77 100644 --- a/src/platform/CMakeLists.txt +++ b/src/platform/CMakeLists.txt @@ -23,6 +23,8 @@ elseif (EMSCRIPTEN) add_subdirectory(web) # add_subdirectory(graphics/cairo) add_subdirectory(graphics/web_canvas) +elseif (UNIX) + add_subdirectory(graphics/cairo) endif() add_subdirectory(bootstrap) diff --git a/test/common/SubProcessTest.cpp b/test/common/SubProcessTest.cpp index 35bf88b9..f2df2142 100644 --- a/test/common/SubProcessTest.cpp +++ b/test/common/SubProcessTest.cpp @@ -8,6 +8,6 @@ TEST_CASE("SubProcess", "[subprocess]") { SECTION("should work.") { SubProcess process = SubProcess::Create(u"echo", {u"abc"}); auto output = process.GetStdoutStream()->ReadToEndAsUtf8String(); - REQUIRE(output == u"abc"); + REQUIRE(output == u"abc\n"); } } |