Update PCH handling (#172)

This commit is contained in:
ykiko
2025-08-10 22:31:00 +08:00
committed by GitHub
parent 3615c5a194
commit a738ad536c
37 changed files with 1076 additions and 679 deletions

View File

@@ -31,9 +31,7 @@ public:
class Guard {
public:
Guard(Lock* lock) : lock(lock) {
assert(lock->locked && "Guard: should be locked");
}
Guard(Lock* lock) : lock(lock) {}
Guard(Guard&& other) : lock(other.lock) {
other.lock = nullptr;
@@ -58,12 +56,19 @@ public:
/// Try to get the lock. If the lock is locked, the current coroutine will be
/// suspended and wait for the lock to be released.
Task<Guard> try_lock() {
/// Note that this task also may be canceled, we make sure
/// even cancel, it can resume one task(through destructor).
Guard guard(this);
if(locked) {
co_await awaiter::lock{awaiters};
}
locked = true;
co_return Guard{this};
/// Use `std::move` to make sure it will not resume
/// the awaiter here.
co_return std::move(guard);
}
private:

View File

@@ -18,7 +18,7 @@ void listen(Callback callback);
/// Listen on the given ip and port, callback is called when there is a LSP message available.
void listen(const char* ip, unsigned int port, Callback callback);
/// Spawn a new process and listen on its stdin/stdout.
/// FIXME: Spawn a new process and listen on its stdin/stdout.
void spawn(llvm::StringRef path, llvm::ArrayRef<std::string> args, Callback callback);
/// Write a JSON value to the client.

View File

@@ -8,7 +8,6 @@
#include <source_location>
#include "Support/Format.h"
#include "llvm/ADT/PointerIntPair.h"
namespace clice::async {
@@ -24,10 +23,15 @@ struct promise_base {
/// The coroutine handle will be destroyed when the task is done or cancelled.
Disposable = 1 << 1,
/// The coroutine is done or is cancelled and resumed, means it will never
/// scheduled again.
Finished = 1 << 2,
};
/// The address of the actual coroutine handle and flags.
llvm::PointerIntPair<void*, 2, Flags> data;
uint8_t flags;
void* data;
/// The coroutine handle that is waiting for the task to complete.
/// If this is a top-level coroutine, it is empty.
@@ -39,12 +43,12 @@ struct promise_base {
template <typename Promise>
void set(std::coroutine_handle<Promise> handle) {
data.setInt(Empty);
data.setPointer(handle.address());
flags = Empty;
data = handle.address();
}
auto handle() const noexcept {
return std::coroutine_handle<>::from_address(data.getPointer());
return std::coroutine_handle<>::from_address(data);
}
void schedule();
@@ -60,21 +64,29 @@ struct promise_base {
void cancel() {
auto p = this;
while(p) {
p->data.setInt(Flags(data.getInt() | Flags::Cancelled));
p->flags |= Flags::Cancelled;
p = p->next;
}
}
bool cancelled() const noexcept {
return data.getInt() & Flags::Cancelled;
return flags & Flags::Cancelled;
}
void dispose() {
data.setInt(Flags(data.getInt() | Flags::Disposable));
flags |= Flags::Disposable;
}
bool disposable() const noexcept {
return data.getInt() & Flags::Disposable;
return flags & Flags::Disposable;
}
void finish() {
flags |= Flags::Finished;
}
bool finished() {
return flags & Flags::Finished;
}
std::coroutine_handle<> resume_handle() {
@@ -83,11 +95,16 @@ struct promise_base {
auto p = this;
while(p && p->cancelled()) {
auto con = p->continuation;
if(p->disposable()) {
p->destroy();
} else {
p->finish();
}
p = con;
}
return std::noop_coroutine();
} else {
/// Otherwise, resume the coroutine handle.
@@ -121,6 +138,9 @@ struct final {
handle = continuation->resume_handle();
}
/// Mark current coroutine as finished.
current.promise().finish();
if(current.promise().disposable()) {
/// If this task is disposable, destroy the coroutine handle.
current.destroy();
@@ -270,12 +290,20 @@ public:
core.promise().cancel();
}
bool cancelled() {
return core.promise().cancelled();
}
/// Dispose the task, it will be destroyed when finished or cancelled.
void dispose() {
core.promise().dispose();
core = nullptr;
}
bool finished() {
return core.promise().finished();
}
T result() {
if constexpr(!std::is_void_v<T>) {
return std::move(core.promise().value.value());

View File

@@ -74,4 +74,6 @@ void init();
void run();
void stop();
} // namespace clice::async