aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcrupest <crupest@outlook.com>2024-06-24 00:06:25 +0800
committercrupest <crupest@outlook.com>2024-06-25 00:12:29 +0800
commit807c1dfe8a897f9c61bf3549ff2566917b53023b (patch)
tree8f0bfed314747ff570fa99577e8954060194ed7f
parent2f5651cd1a1efb136179cdbcb3b29ed0cc11ca2a (diff)
downloadcru-807c1dfe8a897f9c61bf3549ff2566917b53023b.tar.gz
cru-807c1dfe8a897f9c61bf3549ff2566917b53023b.tar.bz2
cru-807c1dfe8a897f9c61bf3549ff2566917b53023b.zip
feat: fix linux build, complete PosixSpawnSubProcess.
NEED TEST: BufferStream, AutoReadStream, SubProcess.
-rw-r--r--include/cru/common/Buffer.h4
-rw-r--r--include/cru/common/PreConfig.h2
-rw-r--r--include/cru/common/io/AutoReadStream.h9
-rw-r--r--include/cru/common/platform/unix/PosixSpawnSubProcess.h6
-rw-r--r--include/cru/ui/document/TextDocumentElement.h2
-rw-r--r--include/cru/ui/render/MeasureRequirement.h5
-rw-r--r--src/common/Buffer.cpp66
-rw-r--r--src/common/String.cpp2
-rw-r--r--src/common/io/AutoReadStream.cpp9
-rw-r--r--src/common/io/BufferStream.cpp4
-rw-r--r--src/common/io/Stream.cpp1
-rw-r--r--src/common/log/Logger.cpp3
-rw-r--r--src/common/platform/unix/PosixSpawnSubProcess.cpp16
-rw-r--r--src/platform/CMakeLists.txt2
-rw-r--r--test/common/SubProcessTest.cpp2
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");
}
}