implement Logger API for Lua
This commit is contained in:
parent
cc883c5f36
commit
b1117ccea9
@ -2,6 +2,7 @@
|
||||
|
||||
#include <cassert>
|
||||
#include <memory>
|
||||
#include <source_location>
|
||||
#include <string_view>
|
||||
|
||||
#include "nf7.hh"
|
||||
@ -35,17 +36,17 @@ class LoggerRef final {
|
||||
}
|
||||
|
||||
// thread-safe
|
||||
void Trace(std::string_view msg) noexcept {
|
||||
Write({nf7::Logger::kTrace, msg});
|
||||
void Trace(std::string_view msg, std::source_location s = std::source_location::current()) noexcept {
|
||||
Write({nf7::Logger::kTrace, msg, 0, s});
|
||||
}
|
||||
void Info(std::string_view msg) noexcept {
|
||||
Write({nf7::Logger::kInfo, msg});
|
||||
void Info(std::string_view msg, std::source_location s = std::source_location::current()) noexcept {
|
||||
Write({nf7::Logger::kInfo, msg, 0, s});
|
||||
}
|
||||
void Warn(std::string_view msg) noexcept {
|
||||
Write({nf7::Logger::kWarn, msg});
|
||||
void Warn(std::string_view msg, std::source_location s = std::source_location::current()) noexcept {
|
||||
Write({nf7::Logger::kWarn, msg, 0, s});
|
||||
}
|
||||
void Error(std::string_view msg) noexcept {
|
||||
Write({nf7::Logger::kError, msg});
|
||||
void Error(std::string_view msg, std::source_location s = std::source_location::current()) noexcept {
|
||||
Write({nf7::Logger::kError, msg, 0, s});
|
||||
}
|
||||
void Write(nf7::Logger::Item&& item) noexcept {
|
||||
if (!id_ || !logger_) return;
|
||||
|
@ -4,6 +4,10 @@
|
||||
|
||||
#include <lua.hpp>
|
||||
|
||||
#include "common/logger.hh"
|
||||
#include "common/logger_ref.hh"
|
||||
#include "common/luajit_thread.hh"
|
||||
|
||||
|
||||
namespace nf7::luajit {
|
||||
|
||||
|
@ -28,22 +28,9 @@ inline void PushWeakPtr(lua_State* L, const std::weak_ptr<T>& wptr) noexcept {
|
||||
new (lua_newuserdata(L, sizeof(wptr))) std::weak_ptr<T>(wptr);
|
||||
}
|
||||
template <typename T>
|
||||
inline std::weak_ptr<T>& ToWeakPtr(lua_State* L, int idx) {
|
||||
std::weak_ptr<T>* wptr = reinterpret_cast<decltype(wptr)>(lua_touserdata(L, idx));
|
||||
return *wptr;
|
||||
}
|
||||
template <typename T>
|
||||
inline std::shared_ptr<T> ToSharedPtr(lua_State* L, int idx) {
|
||||
if (auto ret = ToWeakPtr<T>(L, idx).lock()) {
|
||||
return ret;
|
||||
}
|
||||
luaL_error(L, "object expired: %s", typeid(T).name());
|
||||
return nullptr;
|
||||
}
|
||||
template <typename T>
|
||||
inline void PushWeakPtrDeleter(lua_State* L, const std::weak_ptr<T>& = {}) {
|
||||
inline void PushWeakPtrDeleter(lua_State* L, const std::weak_ptr<T>& = {}) noexcept {
|
||||
lua_pushcfunction(L, [](auto L) {
|
||||
ToWeakPtr<T>(L, 1).~weak_ptr();
|
||||
reinterpret_cast<std::weak_ptr<T>*>(lua_touserdata(L, 1))->~weak_ptr();
|
||||
return 0;
|
||||
});
|
||||
}
|
||||
@ -55,12 +42,21 @@ inline bool MatchMetaName(lua_State* L, int idx, const char* type) noexcept {
|
||||
lua_pop(L, 2);
|
||||
return ret;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline T* ToRef(lua_State* L, int idx, const char* type) noexcept {
|
||||
return MatchMetaName(L, idx, type)? reinterpret_cast<T*>(lua_touserdata(L, idx)): nullptr;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline std::shared_ptr<T> CheckWeakPtr(lua_State* L, int idx, const char* type) {
|
||||
auto ptr = reinterpret_cast<std::weak_ptr<T>*>(luaL_checkudata(L, idx, type));
|
||||
if (auto ret = ptr->lock()) {
|
||||
return ret;
|
||||
} else {
|
||||
luaL_error(L, "object expired: %s", typeid(T).name());
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
template <typename T>
|
||||
inline T& CheckRef(lua_State* L, int idx, const char* type) {
|
||||
return *reinterpret_cast<T*>(luaL_checkudata(L, idx, type));
|
||||
|
@ -1,9 +1,12 @@
|
||||
#include "common/luajit_thread.hh"
|
||||
|
||||
#include <sstream>
|
||||
|
||||
|
||||
namespace nf7::luajit {
|
||||
|
||||
constexpr size_t kInstructionLimit = 10000000;
|
||||
constexpr const char* kTypeName = "nf7::luajit::Thread";
|
||||
constexpr size_t kInstructionLimit = 10000000;
|
||||
|
||||
|
||||
Thread::~Thread() noexcept {
|
||||
@ -11,19 +14,41 @@ Thread::~Thread() noexcept {
|
||||
}
|
||||
|
||||
void Thread::PushMeta(lua_State* L) noexcept {
|
||||
if (luaL_newmetatable(L, "nf7::luajit::Thread")) {
|
||||
if (luaL_newmetatable(L, kTypeName)) {
|
||||
PushWeakPtrDeleter<Thread>(L);
|
||||
lua_setfield(L, -2, "__gc");
|
||||
|
||||
lua_createtable(L, 0, 0);
|
||||
{
|
||||
lua_pushcfunction(L, [](auto L) {
|
||||
auto th = ToSharedPtr<Thread>(L, 1);
|
||||
auto th = CheckWeakPtr<Thread>(L, 1, kTypeName);
|
||||
th->ExpectYield();
|
||||
th->ExecResume(L);
|
||||
return lua_yield(L, lua_gettop(L)-1);
|
||||
});
|
||||
lua_setfield(L, -2, "yield");
|
||||
|
||||
static const auto log_write = [](lua_State* L, nf7::Logger::Level lv) {
|
||||
auto th = CheckWeakPtr<Thread>(L, 1, kTypeName);
|
||||
auto logger = th->logger_;
|
||||
if (!logger) return luaL_error(L, "logger is not installed on current thread");
|
||||
|
||||
const int n = lua_gettop(L);
|
||||
std::stringstream st;
|
||||
for (int i = 2; i <= n; ++i) {
|
||||
st << lua_tostring(L, i);
|
||||
}
|
||||
logger->Write({lv, st.str()});
|
||||
return 0;
|
||||
};
|
||||
lua_pushcfunction(L, [](auto L) { return log_write(L, nf7::Logger::kTrace); });
|
||||
lua_setfield(L, -2, "trace");
|
||||
lua_pushcfunction(L, [](auto L) { return log_write(L, nf7::Logger::kInfo); });
|
||||
lua_setfield(L, -2, "info");
|
||||
lua_pushcfunction(L, [](auto L) { return log_write(L, nf7::Logger::kWarn); });
|
||||
lua_setfield(L, -2, "warn");
|
||||
lua_pushcfunction(L, [](auto L) { return log_write(L, nf7::Logger::kError); });
|
||||
lua_setfield(L, -2, "error");
|
||||
}
|
||||
lua_setfield(L, -2, "__index");
|
||||
}
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include "nf7.hh"
|
||||
|
||||
#include "common/future.hh"
|
||||
#include "common/logger_ref.hh"
|
||||
#include "common/luajit.hh"
|
||||
#include "common/luajit_ref.hh"
|
||||
#include "common/proxy_env.hh"
|
||||
@ -51,6 +52,11 @@ class Thread final : public std::enable_shared_from_this<Thread> {
|
||||
Thread& operator=(const Thread&) = delete;
|
||||
Thread& operator=(Thread&&) = delete;
|
||||
|
||||
void Install(const std::shared_ptr<nf7::LoggerRef>& logger) noexcept {
|
||||
assert(state_ == kInitial);
|
||||
logger_ = logger;
|
||||
}
|
||||
|
||||
// must be called on luajit thread
|
||||
lua_State* Init(lua_State* L) noexcept {
|
||||
assert(state_ == kInitial);
|
||||
@ -72,6 +78,12 @@ class Thread final : public std::enable_shared_from_this<Thread> {
|
||||
ljq_->Push(ctx_, [this, L, self = shared_from_this()](auto) { Resume(L, 0); });
|
||||
}
|
||||
|
||||
// must be called on luajit thread
|
||||
// handler_ won't be called on next yielding
|
||||
void ExpectYield() noexcept {
|
||||
skip_handle_ = true;
|
||||
}
|
||||
|
||||
// thread-safe
|
||||
void Abort() noexcept;
|
||||
|
||||
@ -82,12 +94,6 @@ class Thread final : public std::enable_shared_from_this<Thread> {
|
||||
}
|
||||
}
|
||||
|
||||
// must be called on luajit thread
|
||||
// handler_ won't be called on next yielding
|
||||
void ExpectYield() noexcept {
|
||||
skip_handle_ = true;
|
||||
}
|
||||
|
||||
nf7::Env& env() noexcept { return env_; }
|
||||
const std::shared_ptr<nf7::Context>& ctx() const noexcept { return ctx_; }
|
||||
const std::shared_ptr<nf7::luajit::Queue>& ljq() const noexcept { return ljq_; }
|
||||
@ -109,6 +115,10 @@ class Thread final : public std::enable_shared_from_this<Thread> {
|
||||
std::optional<nf7::luajit::Ref> th_ref_;
|
||||
|
||||
|
||||
// installed features
|
||||
std::shared_ptr<nf7::LoggerRef> logger_;
|
||||
|
||||
|
||||
// mutable params
|
||||
Holder* holder_ = nullptr;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user