diff --git a/compiler/code-gen/files/init-scripts.cpp b/compiler/code-gen/files/init-scripts.cpp index 67c3b7d103..7159037c37 100644 --- a/compiler/code-gen/files/init-scripts.cpp +++ b/compiler/code-gen/files/init-scripts.cpp @@ -109,18 +109,19 @@ void StaticInit::compile(CodeGenerator &W) const { struct RunInterruptedFunction { FunctionPtr function; - RunInterruptedFunction(FunctionPtr function) : function(function) {} + RunInterruptedFunction(FunctionPtr function) + : function(function) {} void compile(CodeGenerator &W) const { std::string await_prefix = function->is_interruptible ? "co_await " : ""; - std::string component_kind = G->is_output_mode_k2_cli() ? "ComponentKind::CLI" - : G->is_output_mode_k2_server() ? "ComponentKind::Server" - : G->is_output_mode_k2_oneshot() ? "ComponentKind::Oneshot" - : G->is_output_mode_k2_multishot() ? "ComponentKind::Multishot" - : "ComponentKind::Invalid"; - - std::string script_start = "co_await get_component_context()->run_component_prologue<" + component_kind + ">();"; - std::string script_finish = "co_await get_component_context()->run_component_epilogue();"; + std::string image_kind = G->is_output_mode_k2_cli() ? "ImageKind::CLI" + : G->is_output_mode_k2_server() ? "ImageKind::Server" + : G->is_output_mode_k2_oneshot() ? "ImageKind::Oneshot" + : G->is_output_mode_k2_multishot() ? "ImageKind::Multishot" + : "ImageKind::Invalid"; + + std::string script_start = "co_await InstanceState::get().run_instance_prologue<" + image_kind + ">();"; + std::string script_finish = "co_await InstanceState::get().run_instance_epilogue();"; FunctionSignatureGenerator(W) << "task_t " << FunctionName(function) << "$run() " << BEGIN << script_start << NL << await_prefix << FunctionName(function) << "();" << NL << script_finish << NL << "co_return;" << END; W << NL; @@ -285,7 +286,7 @@ void ComponentInfoFile::compile(CodeGenerator &W) const { auto now = std::chrono::system_clock::now(); W << OpenFile("image_info.cpp"); W << ExternInclude(G->settings().runtime_headers.get()); - W << "const ImageInfo *vk_k2_describe() " << BEGIN << "static ImageInfo imageInfo {\"" << G->settings().k2_component_name.get() << "\"" << "," + W << "const ImageInfo *k2_describe() " << BEGIN << "static ImageInfo imageInfo {\"" << G->settings().k2_component_name.get() << "\"" << "," << std::chrono::duration_cast(now.time_since_epoch()).count() << "," << "K2_PLATFORM_HEADER_H_VERSION, " << "{}," // todo:k2 add commit hash diff --git a/runtime-light/allocator/runtime-light-allocator.cpp b/runtime-light/allocator/runtime-light-allocator.cpp index 9823a9bca4..ab6bbbe3f5 100644 --- a/runtime-light/allocator/runtime-light-allocator.cpp +++ b/runtime-light/allocator/runtime-light-allocator.cpp @@ -2,141 +2,126 @@ // Copyright (c) 2024 LLC «V Kontakte» // Distributed under the GPL v3 License, see LICENSE.notice.txt +#include #include #include #include "runtime-common/core/utils/kphp-assert-core.h" -#include "runtime-light/component/component.h" +#include "runtime-light/k2-platform/k2-api.h" +#include "runtime-light/state/component-state.h" +#include "runtime-light/state/image-state.h" +#include "runtime-light/state/instance-state.h" namespace { // TODO: make it depend on max chunk size, e.g. MIN_EXTRA_MEM_SIZE = f(MAX_CHUNK_SIZE); constexpr auto MIN_EXTRA_MEM_SIZE = static_cast(32U * 1024U); // extra mem size should be greater than max chunk block size - -bool is_script_allocator_available() { - return get_component_context() != nullptr; -} +constexpr auto EXTRA_MEMORY_MULTIPLIER = 2; void request_extra_memory(size_t requested_size) { - const size_t extra_mem_size = std::max(MIN_EXTRA_MEM_SIZE, requested_size); - auto &rt_alloc = RuntimeAllocator::get(); - auto *extra_mem = rt_alloc.alloc_global_memory(extra_mem_size); - rt_alloc.memory_resource.add_extra_memory(new (extra_mem) memory_resource::extra_memory_pool{extra_mem_size}); + const size_t extra_mem_size{std::max(MIN_EXTRA_MEM_SIZE, EXTRA_MEMORY_MULTIPLIER * requested_size)}; + auto &allocator{RuntimeAllocator::get()}; + auto *extra_mem{allocator.alloc_global_memory(extra_mem_size)}; + allocator.memory_resource.add_extra_memory(new (extra_mem) memory_resource::extra_memory_pool{extra_mem_size}); } } // namespace +RuntimeAllocator &RuntimeAllocator::get() noexcept { + if (k2::instance_state() != nullptr) [[likely]] { + return InstanceState::get().allocator; + } else if (k2::component_state() != nullptr) [[likely]] { + return ComponentState::get_mutable().allocator; + } else if (k2::image_state() != nullptr) [[unlikely]] { + return ImageState::get_mutable().allocator; + } else { + php_critical_error("can't find available allocator"); + } +} + RuntimeAllocator::RuntimeAllocator(size_t script_mem_size, size_t oom_handling_mem_size) { - void *buffer = alloc_global_memory(script_mem_size); + void *buffer{alloc_global_memory(script_mem_size)}; php_assert(buffer != nullptr); memory_resource.init(buffer, script_mem_size, oom_handling_mem_size); } -RuntimeAllocator &RuntimeAllocator::get() noexcept { - return get_component_context()->runtime_allocator; -} - void RuntimeAllocator::init(void *buffer, size_t script_mem_size, size_t oom_handling_mem_size) { php_assert(buffer != nullptr); memory_resource.init(buffer, script_mem_size, oom_handling_mem_size); } void RuntimeAllocator::free() { - const Allocator &pt_ctx = get_platform_context()->allocator; - - auto *extra_memory = memory_resource.get_extra_memory_head(); + auto *extra_memory{memory_resource.get_extra_memory_head()}; while (extra_memory->get_pool_payload_size() != 0) { - auto *releasing_extra_memory = extra_memory; + auto *extra_memory_to_release{extra_memory}; extra_memory = extra_memory->next_in_chain; - pt_ctx.free(releasing_extra_memory); + k2::free(extra_memory_to_release); } - pt_ctx.free(memory_resource.memory_begin()); + k2::free(memory_resource.memory_begin()); } void *RuntimeAllocator::alloc_script_memory(size_t size) noexcept { - php_assert(size); - if (unlikely(!is_script_allocator_available())) { - return alloc_global_memory(size); - } - - ComponentState &rt_ctx = *get_component_context(); - - void *ptr = rt_ctx.runtime_allocator.memory_resource.allocate(size); - if (ptr == nullptr) { + php_assert(size > 0); + void *mem{memory_resource.allocate(size)}; + if (mem == nullptr) [[unlikely]] { request_extra_memory(size); - ptr = rt_ctx.runtime_allocator.memory_resource.allocate(size); - php_assert(ptr != nullptr); + mem = memory_resource.allocate(size); + php_assert(mem != nullptr); } - return ptr; + return mem; } void *RuntimeAllocator::alloc0_script_memory(size_t size) noexcept { - php_assert(size); - if (unlikely(!is_script_allocator_available())) { - return alloc0_global_memory(size); - } - - ComponentState &rt_ctx = *get_component_context(); - void *ptr = rt_ctx.runtime_allocator.memory_resource.allocate0(size); - if (ptr == nullptr) { + php_assert(size > 0); + void *mem{memory_resource.allocate0(size)}; + if (mem == nullptr) [[unlikely]] { request_extra_memory(size); - ptr = rt_ctx.runtime_allocator.memory_resource.allocate0(size); - php_assert(ptr != nullptr); + mem = memory_resource.allocate0(size); + php_assert(mem != nullptr); } - return ptr; + return mem; } -void *RuntimeAllocator::realloc_script_memory(void *mem, size_t new_size, size_t old_size) noexcept { +void *RuntimeAllocator::realloc_script_memory(void *old_mem, size_t new_size, size_t old_size) noexcept { php_assert(new_size > old_size); - if (unlikely(!is_script_allocator_available())) { - return realloc_global_memory(mem, new_size, old_size); - } - - ComponentState &rt_ctx = *get_component_context(); - void *ptr = rt_ctx.runtime_allocator.memory_resource.reallocate(mem, new_size, old_size); - if (ptr == nullptr) { + void *new_mem{memory_resource.reallocate(old_mem, new_size, old_size)}; + if (new_mem == nullptr) [[unlikely]] { request_extra_memory(new_size * 2); - ptr = rt_ctx.runtime_allocator.memory_resource.reallocate(mem, new_size, old_size); - php_assert(ptr != nullptr); + new_mem = memory_resource.reallocate(old_mem, new_size, old_size); + php_assert(new_mem != nullptr); } - return ptr; + return new_mem; } void RuntimeAllocator::free_script_memory(void *mem, size_t size) noexcept { - php_assert(size); - if (unlikely(!is_script_allocator_available())) { - free_global_memory(mem, size); - return; - } - - ComponentState &rt_ctx = *get_component_context(); - rt_ctx.runtime_allocator.memory_resource.deallocate(mem, size); + php_assert(size > 0); + memory_resource.deallocate(mem, size); } void *RuntimeAllocator::alloc_global_memory(size_t size) noexcept { - void *ptr = get_platform_context()->allocator.alloc(size); - if (unlikely(ptr == nullptr)) { + void *mem{k2::alloc(size)}; + if (unlikely(mem == nullptr)) [[unlikely]] { critical_error_handler(); } - return ptr; + return mem; } void *RuntimeAllocator::alloc0_global_memory(size_t size) noexcept { - void *ptr = get_platform_context()->allocator.alloc(size); - if (unlikely(ptr == nullptr)) { + void *mem{k2::alloc(size)}; + if (unlikely(mem == nullptr)) [[unlikely]] { critical_error_handler(); } - std::memset(ptr, 0, size); - return ptr; + std::memset(mem, 0, size); + return mem; } -void *RuntimeAllocator::realloc_global_memory(void *mem, size_t new_size, size_t) noexcept { - void *ptr = get_platform_context()->allocator.realloc(mem, new_size); - if (unlikely(ptr == nullptr)) { +void *RuntimeAllocator::realloc_global_memory(void *old_mem, size_t new_size, size_t /*unused*/) noexcept { + void *mem{k2::realloc(old_mem, new_size)}; + if (unlikely(mem == nullptr)) [[unlikely]] { critical_error_handler(); } - return ptr; + return mem; } -void RuntimeAllocator::free_global_memory(void *mem, size_t) noexcept { - get_platform_context()->allocator.free(mem); +void RuntimeAllocator::free_global_memory(void *mem, size_t /*unused*/) noexcept { + k2::free(mem); } diff --git a/runtime-light/component/component.cmake b/runtime-light/component/component.cmake deleted file mode 100644 index ebd0d8e5ab..0000000000 --- a/runtime-light/component/component.cmake +++ /dev/null @@ -1 +0,0 @@ -prepend(RUNTIME_LIGHT_COMPONENT_SRC component/ component.cpp init-functions.cpp) diff --git a/runtime-light/component/component.h b/runtime-light/component/component.h deleted file mode 100644 index d557682ceb..0000000000 --- a/runtime-light/component/component.h +++ /dev/null @@ -1,135 +0,0 @@ -// Compiler for PHP (aka KPHP) -// Copyright (c) 2024 LLC «V Kontakte» -// Distributed under the GPL v3 License, see LICENSE.notice.txt - -#pragma once - -#include -#include -#include -#include -#include - -#include "runtime-common/core/memory-resource/resource_allocator.h" -#include "runtime-common/core/memory-resource/unsynchronized_pool_resource.h" -#include "runtime-common/core/runtime-core.h" -#include "runtime-light/core/globals/php-script-globals.h" -#include "runtime-light/coroutine/task.h" -#include "runtime-light/header.h" -#include "runtime-light/scheduler/scheduler.h" -#include "runtime-light/server/http/http-server-context.h" -#include "runtime-light/server/job-worker/job-worker-server-context.h" -#include "runtime-light/stdlib/crypto/crypto-context.h" -#include "runtime-light/stdlib/curl/curl-context.h" -#include "runtime-light/stdlib/file/file-stream-context.h" -#include "runtime-light/stdlib/fork/fork-context.h" -#include "runtime-light/stdlib/job-worker/job-worker-client-context.h" -#include "runtime-light/stdlib/output/output-buffer.h" -#include "runtime-light/stdlib/regex/regex-context.h" -#include "runtime-light/stdlib/rpc/rpc-context.h" -#include "runtime-light/stdlib/string/string-context.h" -#include "runtime-light/stdlib/system/system-context.h" - -constexpr uint64_t INVALID_PLATFORM_DESCRIPTOR = 0; - -// Coroutine scheduler type. Change it here if you want to use another scheduler -using CoroutineScheduler = SimpleCoroutineScheduler; -static_assert(CoroutineSchedulerConcept); - -/** - * Supported kinds of KPHP components: - * 1. CLI — works the same way as regular PHP script does - * 2. Server — automatically accepts a stream and expects it to contain either http or job worker request - * 3. Oneshot — can only accept one incoming stream - * 4. Multishot — can accept any number of incoming streams - */ -enum class ComponentKind : uint8_t { Invalid, CLI, Server, Oneshot, Multishot }; - -struct ComponentState { - template - using unordered_set = memory_resource::stl::unordered_set; - - template - using deque = memory_resource::stl::deque; - - ComponentState() noexcept - : runtime_allocator(INIT_RUNTIME_ALLOCATOR_SIZE, 0) - , scheduler(runtime_allocator.memory_resource) - , fork_component_context(runtime_allocator.memory_resource) - , php_script_mutable_globals_singleton(runtime_allocator.memory_resource) - , rpc_component_context(runtime_allocator.memory_resource) - , incoming_streams_(deque::allocator_type{runtime_allocator.memory_resource}) - , opened_streams_(unordered_set::allocator_type{runtime_allocator.memory_resource}) - , pending_updates_(unordered_set::allocator_type{runtime_allocator.memory_resource}) {} - - ~ComponentState() = default; - - void init_script_execution() noexcept; - - template - task_t run_component_prologue() noexcept; - - task_t run_component_epilogue() noexcept; - - ComponentKind component_kind() const noexcept { - return component_kind_; - } - - void process_platform_updates() noexcept; - - bool stream_updated(uint64_t stream_d) const noexcept { - return pending_updates_.contains(stream_d); - } - const unordered_set &opened_streams() const noexcept { - return opened_streams_; - } - const deque &incoming_streams() const noexcept { - return incoming_streams_; - } - uint64_t standard_stream() const noexcept { - return standard_stream_; - } - uint64_t take_incoming_stream() noexcept; - - uint64_t open_stream(std::string_view) noexcept; - uint64_t open_stream(const string &component_name) noexcept { - return open_stream(std::string_view{component_name.c_str(), static_cast(component_name.size())}); - } - - uint64_t set_timer(std::chrono::nanoseconds) noexcept; - void release_stream(uint64_t) noexcept; - void release_all_streams() noexcept; - - RuntimeAllocator runtime_allocator; - - CoroutineScheduler scheduler; - ForkComponentContext fork_component_context; - PollStatus poll_status{PollStatus::PollReschedule}; - - Response response; - PhpScriptMutableGlobals php_script_mutable_globals_singleton; - - RuntimeContext runtime_component_context; - RpcComponentContext rpc_component_context; - HttpServerComponentContext http_server_component_context{}; - JobWorkerClientComponentContext job_worker_client_component_context{}; - JobWorkerServerComponentContext job_worker_server_component_context{}; - - RegexComponentContext regex_component_context; - CurlComponentContext curl_component_context; - CryptoComponentContext crypto_component_context; - StringComponentContext string_component_context; - SystemComponentContext system_component_context; - FileStreamComponentContext file_stream_component_context; - -private: - task_t main_task_; - - ComponentKind component_kind_{ComponentKind::Invalid}; - uint64_t standard_stream_{INVALID_PLATFORM_DESCRIPTOR}; - deque incoming_streams_; - unordered_set opened_streams_; - unordered_set pending_updates_; - - static constexpr auto INIT_RUNTIME_ALLOCATOR_SIZE = static_cast(512U * 1024U); // 512KB -}; diff --git a/runtime-light/component/image.h b/runtime-light/component/image.h deleted file mode 100644 index 0cd5c11005..0000000000 --- a/runtime-light/component/image.h +++ /dev/null @@ -1,15 +0,0 @@ -// Compiler for PHP (aka KPHP) -// Copyright (c) 2024 LLC «V Kontakte» -// Distributed under the GPL v3 License, see LICENSE.notice.txt - -#pragma once - -#include "common/mixin/not_copyable.h" -#include "runtime-light/stdlib/rpc/rpc-context.h" -#include "runtime-light/stdlib/string/string-context.h" - -struct ImageState final : private vk::not_copyable { - char *c_linear_mem; - RpcImageState rpc_image_state{}; - StringImageState string_image_state{}; -}; diff --git a/runtime-light/core/globals/php-script-globals.cpp b/runtime-light/core/globals/php-script-globals.cpp index ce793acb2d..b4ab428d81 100644 --- a/runtime-light/core/globals/php-script-globals.cpp +++ b/runtime-light/core/globals/php-script-globals.cpp @@ -4,11 +4,10 @@ #include "php-script-globals.h" -#include "runtime-light/component/component.h" -#include "runtime-light/utils/context.h" +#include "runtime-light/state/instance-state.h" PhpScriptMutableGlobals &PhpScriptMutableGlobals::current() noexcept { - return get_component_context()->php_script_mutable_globals_singleton; + return InstanceState::get().php_script_mutable_globals_singleton; } void PhpScriptMutableGlobals::once_alloc_linear_mem(unsigned int n_bytes) { diff --git a/runtime-light/core/kphp-core-impl/kphp-core-context.cpp b/runtime-light/core/kphp-core-impl/kphp-core-context.cpp index e1e18fa55a..f99a2b959e 100644 --- a/runtime-light/core/kphp-core-impl/kphp-core-context.cpp +++ b/runtime-light/core/kphp-core-impl/kphp-core-context.cpp @@ -3,14 +3,13 @@ // Distributed under the GPL v3 License, see LICENSE.notice.txt #include "runtime-common/core/runtime-core.h" -#include "runtime-light/component/component.h" -#include "runtime-light/utils/context.h" +#include "runtime-light/state/instance-state.h" constexpr string_size_type initial_minimum_string_buffer_length = 1024; constexpr string_size_type initial_maximum_string_buffer_length = (1 << 24); RuntimeContext &RuntimeContext::get() noexcept { - return get_component_context()->runtime_component_context; + return InstanceState::get().runtime_context; } void RuntimeContext::init() noexcept { diff --git a/runtime-light/coroutine/awaitable.h b/runtime-light/coroutine/awaitable.h index 45b8ba95cc..a788dd7093 100644 --- a/runtime-light/coroutine/awaitable.h +++ b/runtime-light/coroutine/awaitable.h @@ -14,12 +14,10 @@ #include #include "runtime-common/core/utils/kphp-assert-core.h" -#include "runtime-light/component/component.h" #include "runtime-light/coroutine/task.h" -#include "runtime-light/header.h" #include "runtime-light/scheduler/scheduler.h" -#include "runtime-light/stdlib/fork/fork-context.h" -#include "runtime-light/utils/context.h" +#include "runtime-light/state/instance-state.h" +#include "runtime-light/stdlib/fork/fork-state.h" template concept Awaitable = requires(T awaitable, std::coroutine_handle<> coro) { @@ -47,11 +45,11 @@ namespace awaitable_impl_ { enum class State : uint8_t { Init, Suspend, Ready, End }; class fork_id_watcher_t { - int64_t fork_id{ForkComponentContext::get().running_fork_id}; + int64_t fork_id{ForkInstanceState::get().running_fork_id}; protected: void await_resume() const noexcept { - ForkComponentContext::get().running_fork_id = fork_id; + ForkInstanceState::get().running_fork_id = fork_id; } }; @@ -84,7 +82,7 @@ class wait_for_update_t : public awaitable_impl_::fork_id_watcher_t { bool await_ready() noexcept { php_assert(state == awaitable_impl_::State::Init); - state = get_component_context()->stream_updated(stream_d) ? awaitable_impl_::State::Ready : awaitable_impl_::State::Init; + state = InstanceState::get().stream_updated(stream_d) ? awaitable_impl_::State::Ready : awaitable_impl_::State::Init; return state == awaitable_impl_::State::Ready; } @@ -134,7 +132,7 @@ class wait_for_incoming_stream_t : awaitable_impl_::fork_id_watcher_t { bool await_ready() noexcept { php_assert(state == awaitable_impl_::State::Init); - state = !get_component_context()->incoming_streams().empty() ? awaitable_impl_::State::Ready : awaitable_impl_::State::Init; + state = !InstanceState::get().incoming_streams().empty() ? awaitable_impl_::State::Ready : awaitable_impl_::State::Init; return state == awaitable_impl_::State::Ready; } @@ -147,7 +145,7 @@ class wait_for_incoming_stream_t : awaitable_impl_::fork_id_watcher_t { uint64_t await_resume() noexcept { state = awaitable_impl_::State::End; fork_id_watcher_t::await_resume(); - const auto incoming_stream_d{get_component_context()->take_incoming_stream()}; + const auto incoming_stream_d{InstanceState::get().take_incoming_stream()}; php_assert(incoming_stream_d != INVALID_PLATFORM_DESCRIPTOR); return incoming_stream_d; } @@ -238,7 +236,7 @@ class wait_for_timer_t : awaitable_impl_::fork_id_watcher_t { cancel(); } if (timer_d != INVALID_PLATFORM_DESCRIPTOR) { - get_component_context()->release_stream(timer_d); + InstanceState::get().release_stream(timer_d); } } @@ -249,7 +247,7 @@ class wait_for_timer_t : awaitable_impl_::fork_id_watcher_t { void await_suspend(std::coroutine_handle<> coro) noexcept { state = awaitable_impl_::State::Suspend; - timer_d = get_component_context()->set_timer(duration); + timer_d = InstanceState::get().set_timer(duration); if (timer_d != INVALID_PLATFORM_DESCRIPTOR) { suspend_token = std::make_pair(coro, WaitEvent::UpdateOnTimer{.timer_d = timer_d}); } @@ -293,7 +291,7 @@ class start_fork_t : awaitable_impl_::fork_id_watcher_t { explicit start_fork_t(task_t task_, execution exec_policy_) noexcept : exec_policy(exec_policy_) , fork_coro(task_.get_handle()) - , fork_id(ForkComponentContext::get().push_fork(std::move(task_))) {} + , fork_id(ForkInstanceState::get().push_fork(std::move(task_))) {} start_fork_t(start_fork_t &&other) noexcept : exec_policy(other.exec_policy) @@ -319,7 +317,7 @@ class start_fork_t : awaitable_impl_::fork_id_watcher_t { case execution::fork: { suspend_token.first = current_coro; continuation = fork_coro; - ForkComponentContext::get().running_fork_id = fork_id; + ForkInstanceState::get().running_fork_id = fork_id; break; } case execution::self: { @@ -357,7 +355,7 @@ class wait_fork_t : awaitable_impl_::fork_id_watcher_t { public: explicit wait_fork_t(int64_t fork_id_) noexcept : fork_id(fork_id_) - , fork_task(static_cast>(ForkComponentContext::get().pop_fork(fork_id))) + , fork_task(static_cast>(ForkInstanceState::get().pop_fork(fork_id))) , fork_awaiter(std::addressof(fork_task)) {} wait_fork_t(wait_fork_t &&other) noexcept diff --git a/runtime-light/coroutine/task.h b/runtime-light/coroutine/task.h index 85920b3133..64838f3445 100644 --- a/runtime-light/coroutine/task.h +++ b/runtime-light/coroutine/task.h @@ -13,7 +13,7 @@ #include "common/containers/final_action.h" #include "runtime-common/core/utils/kphp-assert-core.h" -#include "runtime-light/utils/context.h" +#include "runtime-light/k2-platform/k2-api.h" #if __clang_major__ > 7 #define CPPCORO_COMPILER_SUPPORTS_SYMMETRIC_TRANSFER @@ -122,13 +122,13 @@ struct task_t : public task_base_t { void *operator new(std::size_t n, [[maybe_unused]] Args &&...args) noexcept { // todo:k2 think about args in new // todo:k2 make coroutine allocator - void *buffer = get_platform_context()->allocator.alloc(n); + void *buffer = k2::alloc(n); return buffer; } void operator delete(void *ptr, size_t n) noexcept { (void)n; - get_platform_context()->allocator.free(ptr); + k2::free(ptr); } }; diff --git a/runtime-light/header.h b/runtime-light/header.h deleted file mode 100644 index cfa2bcc033..0000000000 --- a/runtime-light/header.h +++ /dev/null @@ -1,382 +0,0 @@ -// Compiler for PHP (aka KPHP) -// Copyright (c) 2024 LLC «V Kontakte» -// Distributed under the GPL v3 License, see LICENSE.notice.txt - -#ifndef K2_PLATFORM_HEADER_H -#define K2_PLATFORM_HEADER_H - -#pragma once - -#ifdef __cplusplus -#include -#include -#include -#else -#include -#include -#include -#endif - -#define K2_PLATFORM_HEADER_H_VERSION 8 - -// Always check that enum value is a valid value! - -#ifdef __cplusplus -extern "C" { -#endif - -struct Allocator { - // TODO zeroing or not? - void *(*alloc)(size_t); - void (*free)(void *); - void *(*realloc)(void *ptr, size_t); -}; - -enum IOStatus { - IOAvailable = 0, - IOBlocked = 1, - IOClosed = 2, -}; - -struct StreamStatus { - enum IOStatus read_status; - enum IOStatus write_status; - int32_t please_shutdown_write; - int32_t libc_errno; -}; - -enum GetStatusResult { - GetStatusOk = 0, - GetStatusErrorNotStream = 1, - GetStatusErrorUseAfterFree = 2, - GetStatusErrorNoSuchStream = 3, -}; - -enum SetTimerResult { - SetTimerOk = 0, - SetTimerErrorLimitExceeded = 1, -}; - -enum TimerStatus { - TimerStatusScheduled = 0, - TimerStatusElapsed = 1, - TimerStatusInvalid = 2, -}; - -enum OpenStreamResult { - OpenStreamOk = 0, - /* - * TODO: really need error? MB it's better to open and immediately close - * channel with corresponding error - */ - OpenStreamErrorInvalidName = 1, - OpenStreamErrorUnknownComponent = 3, - OpenStreamErrorComponentUnavailable = 4, - OpenStreamErrorLimitExceeded = 5, -}; - -/* - * This time point is valid only within the component. - * Similar to c++ `std::chrono::steady_clock::time_point` - */ -struct TimePoint { - uint64_t time_point_ns; -}; - -struct SystemTime { - uint64_t since_epoch_ns; -}; - -#ifdef __cplusplus -typedef std::atomic_uint32_t atomic_uint32_t; -#else -typedef _Atomic(uint32_t) atomic_uint32_t; -#endif - -// DEPRECATED: -struct PlatformCtx { - atomic_uint32_t please_yield; - atomic_uint32_t please_graceful_shutdown; - - /* - * Immediately abort component execution. - * Function is `[[noreturn]]` - * Note: `exit_code` used just as indicator for now. - * `exit_code` == 0 => FinishedOk, - * `exit_code` != 0 => FinishedError, - */ - void (*exit)(int32_t exit_code); - - // Deprecated; Synonym for `exit(255)`; - void (*abort)(); - - struct Allocator allocator; - - /* - * In case of `result == Ok` stream_d will be NonZero - * - * In case of `result != Ok`: - * `stream_d` will be assigned `0`. - * however `stream_d=0` itself is not an error marker - */ - enum OpenStreamResult (*open)(size_t name_len, const char *name, uint64_t *stream_d); - /* - * If the write or read status is `Blocked` - then the platform ensures that - * the component receives this `stream_d` via `take_update` when the status is - * no longer `Blocked` - * - * In case of `result != Ok`: - * `new_status` will be assigned as - * `{.read_status = 0, .write_status = 0, .please_shutdown = 0}`. - */ - enum GetStatusResult (*get_stream_status)(uint64_t stream_d, struct StreamStatus *new_status); - /* - * Return processed bytes (written or read). - * Guaranteed to return `0` if the stream is `Closed`, `Blocked` or - * `stream_d` is invalid. - * May return `0` even if the stream is `Available` - * - * The bytes processed may be less than `data_len`, - * even if the stream is in `Available` state after the operation. - * Therefore, it does not indicate `Blocked` or `Closed` status. - * Use `get_stream_status` to check how to perform co-scheduling. - */ - size_t (*write)(uint64_t stream_d, size_t data_len, const void *data); - size_t (*read)(uint64_t stream_d, size_t data_len, void *data); - - /* - * Sets `StreamStatus.please_whutdown_write=true` for the component on the - * opposite side (does not affect `StreamStatus` on your side). - * Does not disable the ability to read from the stream. - * To perform a graceful shutdown, you still need to read data from the stream - * as long as `read_status != IOClosed`. - */ - void (*please_shutdown_write)(uint64_t stream_d); - - /* - * Disables the ability to write to a stream. - * Data written to the stream buffer is still available for reading on the - * opposite side. - * Does not affect the ability to read from the stream. - * - * TODO: design information errors. - */ - void (*shutdown_write)(uint64_t stream_d); - - /* - * "Free" associated descriptor. - * All future uses of this `descriptor` will be invalid. - * - * In case were `descriptor` is stream: - * 1) If you are the owner of the stream (performed an `open`) - - * the read and write buffers will be immediately deleted. The opposite side - * will receive an `IOClosed` notification in both directions. - * 2) If you are not the owner, the opposite side will receive a notification - * `write_status = IOClosed`; Data sent from the opposite side and remaining - * in buffer will be deleted. The opposite side will be able to read the data - * sent from you and remaining in the buffer stream. - * - * In case where `descriptor` is timer: - * Ensures that no notification from this timer will be received. - * - * Noop in case if `descriptor` is invalid - */ - void (*free_descriptor)(uint64_t descriptor); - - // Time since epoch, non-monotonical - void (*get_system_time)(struct SystemTime *system_time); - - // Coordinated with timers. Monotonical, for timeouts, measurements, etc.. - void (*get_time)(struct TimePoint *time_point); - - /* - * In case of `result == Ok` timer_d will be NonZero - * In case of `result != Ok` timer_d will be `0` - * - * One-shot timer - * Use `free_descriptor` to cancel - */ - enum SetTimerResult (*set_timer)(uint64_t *timer_d, uint64_t duration_ns); - - /* - * It is guaranteed that if `TimerStatusElapsed` is returned - * then `deadline <= get_time()` - * There is no symmetric guarantee for `TimerStatusScheduled`. - * - * `deadline` will be assigned `0` if `timer_d` invalid - */ - enum TimerStatus (*get_timer_status)(uint64_t timer_d, struct TimePoint *deadline); - /* - * Return: `bool`. - * If `True`: the update was successfully received. - * If `False`: no updates, `update_d` will be set to `0`. - * - * `update_d` might be either a stream or a timer. - * `update_d` can be a new stream installed for this component. - * Therefore, component should keep track of all active descriptors to - * distinguish new stream from existing one. - * - * `update_d` may be an elapsed timer. - * `get_timer_status` for this timer will be a valid call and will allow you - * to get its deadline (which is guaranteed to be in the past). - * But you must call `free_descriptor` to release the associated descriptor. - * - * If a component has not read all updates during a `poll` iteration, the - * platform is guaranteed to reschedule it. - */ - uint8_t (*take_update)(uint64_t *update_d); - - /* - * Only utf-8 string supported. - * Possible `level` values: - * 1 => Error - * 2 => Warn - * 3 => Info - * 4 => Debug - * 5 => Trace - * Any other value will cause the log to be skipped - * if `level` > `log_level_enabled()` log will be skipped - */ - void (*log)(size_t level, size_t len, const char *str); - - // Use for optimization, see `log` - size_t (*log_level_enabled)(); - - // Note: prefer to use only as seed generator for pseudo-random - void (*os_rnd)(size_t len, void *bytes); -}; - -struct ComponentState; - -/* - * Image state created once on library load. - * Shared between all component [instances]. - * Designed to prevent heavy `_init` section of dlib - */ -struct ImageState; - -enum PollStatus { - // waitings IO or timer; no cpu work remains - PollBlocked = 0, - // there is some cpu work to do; platform will reschedule component - PollReschedule = 1, - // component decide to shutdown normally - PollFinishedOk = 2, - // component decide to shutdown unexpectedly - PollFinishedError = 3, -}; - -struct ImageInfo { - // TODO: null terminated string is OK? - // TODO: namespaces? - const char *image_name; - - uint64_t build_timestamp; - uint64_t header_h_version; - uint8_t commit_hash[40]; - // TODO: more informative? - uint8_t compiler_hash[64]; - // bool - uint8_t is_oneshot; -}; - -/// -// Symbols provided by component image -// Every image should provide these symbols -/// -enum PollStatus vk_k2_poll(const struct ImageState *image_state, const struct PlatformCtx *pt_ctx, struct ComponentState *component_ctx); - -/* - * platform_ctx without IO stuff (nullptr instead io-functions) - * for now, returning nullptr will indicate error - */ -struct ComponentState *vk_k2_create_component_state(const struct ImageState *image_state, const struct PlatformCtx *pt_ctx); -struct ImageState *vk_k2_create_image_state(const struct PlatformCtx *pt_ctx); - -const struct ImageInfo *vk_k2_describe(); - -struct ControlFlags { - atomic_uint32_t please_yield; - atomic_uint32_t please_graceful_shutdown; -}; - -/* - * - * Symbols provided by k2-node and resolved by linker during dlopen. - * Every image can use these symbols. - * - * Semantically analogs for `PlatformCtx` methods sometimes with small - * differences. Preferable way to communication with k2-node. - * - */ -const struct ControlFlags *k2_control_flags(); -const struct ImageState *k2_image_state(); -struct ComponentState *k2_component_state(); - -void *k2_alloc(size_t size, size_t align); -void *k2_realloc(void *ptr, size_t new_size); -void *k2_realloc_checked(void *ptr, size_t old_size, size_t align, size_t new_size); -void k2_free(void *ptr); -void k2_free_checked(void *ptr, size_t size, size_t align); - -void k2_exit(int32_t exit_code); - -// Difference with PlatformCtx: -// This function return `libc errno` (`0` on success) -// -// Some examples: -// `EINVAL` => `name` has invalid format (empty, non ascii, too long, etc..) -// `ECONNREFUSED` => no component with such name found -// `ENOMEM` => our compoonent has no enough memory for stream -// `EACCES` => permission denied -// -int32_t k2_open(uint64_t *d, size_t name_len, const char *name); - -// Difference with PlatformCtx: -// This function does not return status. -// But it will set `s->libc_errno` to corresponding errors: -// `EBADF` => d is not valid(never was valid or used after free) -// `EBADR` => d is valid descriptor, but not a stream (probably, timer) -// -void k2_stream_status(uint64_t d, struct StreamStatus *s); - -size_t k2_write(uint64_t d, size_t data_len, const void *data); -size_t k2_read(uint64_t d, size_t buf_len, void *buf); - -void k2_please_shutdown(uint64_t d); -void k2_shutdown_write(uint64_t d); - -void k2_instant(struct TimePoint *time_point); - -// Difference with PlatformCtx: -// This function return `libc errno` (`0` on success) -// -// Probably this function newer fails. -// Looks like `ENOMEM` is only reasonable error. -// I think component prefer abortion in this case. -// -int32_t k2_new_timer(uint64_t *d, uint64_t duration_ns); - -// Difference with PlatformCtx: -// This function return `libc errno` (`0` on success) -// -// `EBADF` => d is not valid(never was valid or used after free) -// `EBADR` => d is valid descriptor, but not a timer (probably stream) -// -int32_t k2_timer_deadline(uint64_t d, struct TimePoint *deadline); - -void k2_free_descriptor(uint64_t d); - -uint8_t k2_take_update(uint64_t *d); - -void k2_log(size_t level, size_t len, const char *str); -size_t k2_log_level_enabled(); - -void k2_os_rnd(size_t len, void *bytes); - -void k2_system_time(struct SystemTime *system_time); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/runtime-light/k2-platform/k2-api.h b/runtime-light/k2-platform/k2-api.h new file mode 100644 index 0000000000..41c73de6ec --- /dev/null +++ b/runtime-light/k2-platform/k2-api.h @@ -0,0 +1,148 @@ +// Compiler for PHP (aka KPHP) +// Copyright (c) 2024 LLC «V Kontakte» +// Distributed under the GPL v3 License, see LICENSE.notice.txt + +#pragma once + +#include +#include +#include +#include + +#define K2_API_HEADER_H +#include "runtime-light/k2-platform/k2-header.h" +#undef K2_API_HEADER_H + +namespace k2 { + +namespace k2_impl_ { + +inline constexpr size_t DEFAULT_MEMORY_ALIGN = 16; + +} // namespace k2_impl_ + +inline constexpr int32_t errno_ok = 0; + +using IOStatus = IOStatus; + +using StreamStatus = StreamStatus; + +using TimePoint = TimePoint; + +using SystemTime = SystemTime; + +using PollStatus = PollStatus; + +using ImageInfo = ImageInfo; + +using ControlFlags = ControlFlags; + +inline const ImageInfo *describe() noexcept { + return k2_describe(); +} + +inline const ControlFlags *control_flags() noexcept { + return k2_control_flags(); +} + +inline const ImageState *image_state() noexcept { + return k2_image_state(); +} + +inline const ComponentState *component_state() noexcept { + return k2_component_state(); +} + +inline InstanceState *instance_state() noexcept { + return k2_instance_state(); +} + +inline void *alloc_align(size_t size, size_t align) noexcept { + return k2_alloc(size, align); +} + +inline void *alloc(size_t size) noexcept { + return alloc_align(size, k2_impl_::DEFAULT_MEMORY_ALIGN); +} + +inline void *realloc(void *ptr, size_t new_size) noexcept { + return k2_realloc(ptr, new_size); +} + +inline void *realloc_checked(void *ptr, size_t old_size, size_t align, size_t new_size) noexcept { + return k2_realloc_checked(ptr, old_size, align, new_size); +} + +inline void free(void *ptr) noexcept { + k2_free(ptr); +} + +inline void free_checked(void *ptr, size_t size, size_t align) noexcept { + k2_free_checked(ptr, size, align); +} + +[[noreturn]] inline void exit(int32_t exit_code) noexcept { + k2_exit(exit_code); +} + +inline int32_t open(uint64_t *stream_d, size_t name_len, const char *name) noexcept { + return k2_open(stream_d, name_len, name); +} + +inline void stream_status(uint64_t stream_d, StreamStatus *status) noexcept { + k2_stream_status(stream_d, status); +} + +inline size_t write(uint64_t stream_d, size_t data_len, const void *data) noexcept { + return k2_write(stream_d, data_len, data); +} + +inline size_t read(uint64_t stream_d, size_t buf_len, void *buf) noexcept { + return k2_read(stream_d, buf_len, buf); +} + +inline void please_shutdown(uint64_t stream_d) noexcept { + k2_please_shutdown(stream_d); +} + +inline void shutdown_write(uint64_t stream_d) noexcept { + k2_shutdown_write(stream_d); +} + +inline void instant(TimePoint *time_point) noexcept { + k2_instant(time_point); +} + +inline int32_t new_timer(uint64_t *descriptor, uint64_t duration_ns) noexcept { + return k2_new_timer(descriptor, duration_ns); +} + +inline int32_t timer_deadline(uint64_t d, TimePoint *deadline) noexcept { + return k2_timer_deadline(d, deadline); +} + +inline void free_descriptor(uint64_t descriptor) noexcept { + k2_free_descriptor(descriptor); +} + +inline uint8_t take_update(uint64_t *update_d) noexcept { + return k2_take_update(update_d); +} + +inline void log(size_t level, size_t len, const char *str) noexcept { + k2_log(level, len, str); +} + +inline size_t log_level_enabled() noexcept { + return k2_log_level_enabled(); +} + +inline void os_rnd(size_t len, void *bytes) noexcept { + k2_os_rnd(len, bytes); +} + +inline void system_time(SystemTime *system_time) noexcept { + k2_system_time(system_time); +} + +} // namespace k2 diff --git a/runtime-light/k2-platform/k2-header.h b/runtime-light/k2-platform/k2-header.h new file mode 100644 index 0000000000..325dcd0ca0 --- /dev/null +++ b/runtime-light/k2-platform/k2-header.h @@ -0,0 +1,399 @@ +#ifndef K2_PLATFORM_HEADER_H +#define K2_PLATFORM_HEADER_H + +#pragma once + +#ifndef K2_API_HEADER_H +#error "should not be directly included" +#endif // K2_API_HEADER_H + +#include + +#ifdef __cplusplus +#include +#include +#include +#else +#include +#include +#include +#endif + +#define K2_PLATFORM_HEADER_H_VERSION 11 + +// Always check that enum value is a valid value! + +#ifdef __cplusplus +extern "C" { +#endif + +enum IOStatus { + IOAvailable = 0, + IOBlocked = 1, + IOClosed = 2, +}; + +struct StreamStatus { + enum IOStatus read_status; + enum IOStatus write_status; + int32_t please_shutdown_write; + int32_t libc_errno; +}; + +/* + * This time point is valid only within the component. + * Similar to c++ `std::chrono::steady_clock::time_point` + */ +struct TimePoint { + uint64_t time_point_ns; +}; + +struct SystemTime { + uint64_t since_epoch_ns; +}; + +#ifdef __cplusplus +typedef std::atomic_uint32_t atomic_uint32_t; +#else +typedef _Atomic(uint32_t) atomic_uint32_t; +#endif + +struct InstanceState; + +struct ComponentState; + +/* + * Image state created once on library load. + * Shared between all component [instances]. + * Designed to prevent heavy `_init` section of dlib + */ +struct ImageState; + +enum PollStatus { + // waitings IO or timer; no cpu work remains + PollBlocked = 0, + // there is some cpu work to do; platform will reschedule component + PollReschedule = 1, + // component decide to shutdown normally + PollFinishedOk = 2, + // component decide to shutdown unexpectedly + PollFinishedError = 3, +}; + +struct ImageInfo { + // TODO: null terminated string is OK? + // TODO: namespaces? + const char *image_name; + + uint64_t build_timestamp; + uint64_t header_h_version; + uint8_t commit_hash[40]; + // TODO: more informative? + uint8_t compiler_hash[64]; + // bool + uint8_t is_oneshot; +}; + +/** + * Symbols provided by component image + * Every image should provide these symbols + */ +enum PollStatus k2_poll(); + +// Symbols provided by .so. +struct ImageState *k2_create_image(); +void k2_init_image(); +struct ComponentState *k2_create_component(); +void k2_init_component(); +struct InstanceState *k2_create_instance(); +void k2_init_instance(); + +const struct ImageInfo *k2_describe(); + +struct ControlFlags { + atomic_uint32_t please_yield; + atomic_uint32_t please_graceful_shutdown; +}; + +/** + * + * Symbols provided by k2-node and resolved by linker during dlopen. + * Every image can use these symbols. + * + * Semantically analogs for `PlatformCtx` methods sometimes with small + * differences. Preferable way to communication with k2-node. + * + */ +struct ControlFlags *k2_control_flags(); +struct ImageState *k2_image_state(); +struct ComponentState *k2_component_state(); +struct InstanceState *k2_instance_state(); + +/** + * If component track alignment and allocated memory size - + * it is preferable to use the `*_checked` versions, which have additional checks enabled. + * The rest of the functions are allowed to be used in any case. + */ +void *k2_alloc(size_t size, size_t align); +void *k2_realloc(void *ptr, size_t new_size); +void *k2_realloc_checked(void *ptr, size_t old_size, size_t align, size_t new_size); +void k2_free(void *ptr); +void k2_free_checked(void *ptr, size_t size, size_t align); + +/** + * Immediately abort component execution. + * Function is `[[noreturn]]` + * Note: `exit_code` used just as indicator for now. + * `exit_code` == 0 => FinishedOk, + * `exit_code` != 0 => FinishedError, + */ +[[noreturn]] void k2_exit(int32_t exit_code); + +/** + * @return return `0` on success. libc-like `errno` otherwise + * `stream_d` will be assigned new descriptor on success. + * `stream_d` will be assigned `0` on error. however `stream_d=0` itself is not an error marker. + * + * Some `errno` examples: + * `EINVAL` => `name` has invalid format (empty, non ascii, too long, etc..) + * `ECONNREFUSED` => no component with such name found + * `ENOMEM` => our component has no enough memory for stream + * `EACCES` => permission denied + */ +int32_t k2_open(uint64_t *stream_d, size_t name_len, const char *name); + +/** + * If the write or read status is `Blocked` - then the platform ensures that + * the component receives this `stream_d` via `k2_take_update` when the status is + * no longer `Blocked` ("edge-triggered epoll"-like behaviour). + * + * `status` will be filled with actual descriptor status on of success. + * `s->libc_errno` used to represent errors. + * + * Some `errno` examples: + * `EBADF` => d is not valid(never was valid or used after free) + * `EBADR` => d is valid descriptor, but not a stream (probably, timer) + */ +void k2_stream_status(uint64_t stream_d, struct StreamStatus *status); + +/** + * Guaranteed to return `0` if the stream is `Closed`, `Blocked` or `stream_d` is invalid. + * May return `0` even if the stream is `Available`. + * + * The bytes processed may be less than `data_len`, + * even if the stream is in `Available` state after the operation. + * Therefore, it does not indicate `Blocked` or `Closed` status. + * Use `k2_stream_status` to check how to perform co-scheduling. + * + * @return number of written bytes. + */ +size_t k2_write(uint64_t stream_d, size_t data_len, const void *data); + +/** + * Guaranteed to return `0` if the stream is `Closed`, `Blocked` or `stream_d` is invalid. + * May return `0` even if the stream is `Available`. + * + * The bytes processed may be less than `buf_len`, + * even if the stream is in `Available` state after the operation. + * Therefore, it does not indicate `Blocked` or `Closed` status. + * Use `k2_stream_status` to check how to perform co-scheduling. + * + * @return number of read bytes. + */ +size_t k2_read(uint64_t stream_d, size_t buf_len, void *buf); + +/** + * Sets `StreamStatus.please_whutdown_write=true` for the component on the + * opposite side (does not affect `StreamStatus` on your side). + * Does not disable the ability to read from the stream. + * To perform a graceful shutdown, you still need to read data from the stream + * as long as `read_status != IOClosed`. + */ +void k2_please_shutdown(uint64_t stream_d); + +/** + * Disables the ability to write to a stream. + * Data written to the stream buffer is still available for reading on the + * opposite side. + * Does not affect the ability to read from the stream. + * + * TODO: design information errors. + */ +void k2_shutdown_write(uint64_t stream_d); + +// Coordinated with timers. Monotonical, for timeouts, measurements, etc.. +void k2_instant(struct TimePoint *time_point); + +/** + * One-shot timer. + * Use `free_descriptor` to cancel. + * + * @return `0` on success. libc-like `errno` on error. + * `descriptor` will be assigned to new descriptor on success. + * `descriptor` will be assigned `0` on error. + * + * Probably this function never fails. + * Looks like `ENOMEM` is only reasonable error. + * I think component should prefer abortion in this case. + */ +int32_t k2_new_timer(uint64_t *descriptor, uint64_t duration_ns); + +/** + * @return `0` on success. libc-like `errno` on error. + * `deadline` will be assigned to actual timer deadline on success. + * `deadline` will be assigned `0` on error. + * + * Some `error` examples: + * `EBADF` => `d` is not valid(never was valid or used after free) + * `EBADR` => `d` is valid descriptor, but not a timer (probably stream) + */ +int32_t k2_timer_deadline(uint64_t d, struct TimePoint *deadline); + +/** + * "Free" associated descriptor. + * All future uses of this `descriptor` will be invalid. + * + * In case were `descriptor` is stream: + * 1) If you are the owner of the stream (performed an `open`) - + * the read and write buffers will be immediately deleted. The opposite side + * will receive an `IOClosed` notification in both directions. + * 2) If you are not the owner, the opposite side will receive a notification + * `write_status = IOClosed`; Data sent from the opposite side and remaining + * in buffer will be deleted. The opposite side will be able to read the data + * sent from you and remaining in the buffer stream. + * + * In case where `descriptor` is timer: + * Ensures that no notification from this timer will be received. + * + * Perform `noop` if `descriptor` is invalid descriptor + */ +void k2_free_descriptor(uint64_t descriptor); + +/** + * `update_d` might be either a stream or a timer. + * `update_d` can be a new stream installed for this component. + * Therefore, component should keep track of all active descriptors to + * distinguish new stream from existing one. + * + * `update_d` may be an elapsed timer. + * `k2_timer_deadline` for this timer will be a valid call and will allow you + * to get its deadline (which is guaranteed to be in the past). + * But you must call `free_descriptor` to release the associated descriptor. + * + * If a component has not take all updates during a `poll` iteration, the + * platform is guaranteed to reschedule it. + * + * @return: `1` if update is successfully taken. `descriptor` will be assigned to updated descriptor. + * @return: `1` if there is no updates to take. `descriptor` will be assigned to `0`. + */ +uint8_t k2_take_update(uint64_t *update_d); + +/** + * Only utf-8 string supported. + * Possible `level` values: + * 1 => Error + * 2 => Warn + * 3 => Info + * 4 => Debug + * 5 => Trace + * Any other value will cause the log to be skipped + * if `level` > `log_level_enabled()` log will be skipped + */ +void k2_log(size_t level, size_t len, const char *str); + +// Use for optimization, see `k2_log` +size_t k2_log_level_enabled(); + +// Note: prefer to use only as seed generator for pseudo-random +void k2_os_rnd(size_t len, void *bytes); + +// Time since epoch, non-monotonical +void k2_system_time(struct SystemTime *system_time); + +/** + * libc-like socket api. + * @return: `0` on success, `errno != 0` otherwise + */ +int32_t k2_socket(uint64_t *socket_d, int32_t domain, int32_t type, int protocol); + +/** + * libc-like socket api. + * @return: `0` on success, `errno != 0` otherwise + */ +int32_t k2_connect(uint64_t socket_d, const struct sockaddr_storage *addr, size_t addrlen); + +/** + * Perform sequentially `k2_lookup_host` -> `k2_socket` -> `k2_connect` + * @return: `0` on success, `errno != 0` otherwise + */ +int32_t k2_udp_connect(uint64_t *socket_d, const char *host, size_t host_len); + +/** + * Perform sequentially `k2_lookup_host` -> `k2_socket` -> `k2_connect` + * @return: `0` on success, `errno != 0` otherwise + */ +int32_t k2_tcp_connect(uint64_t *socket_d, const char *host, size_t host_len); + +struct SockAddr { + uint16_t is_v6; + uint16_t port; + uint8_t addr[16]; // used first 4 bytes in case of ipv4 + uint32_t flowinfo; // ipv6 only + uint32_t scope_id; // ipv6 only +}; + +/** + * Optimistically tries to parse `host` as `ip` + `port`. + * Examples: + * IpV4 `host` format: `"123.123.123.123:8080"`. + * IpV6 `host` format: `"[2001:db8::1]:8080"`. + * + * Then performs a DNS resolution with `man 3 getaddrinfo` (implementation depends on the host machine settings). + * Examples: + * `host = "localhost:8080"` + * `host = "vk.com:443"` + * + * + * Although the function signature is synchronous DNS resolution may perform file reading and networking. + * k2-node will attempt to do this work in the background, but the component execution and associated work will be suspended. + * Thus, this is an expensive operation that should have an asynchronous signature, but it does not. + * + * @param `host` should be valid utf-8. + * @return: `0` on success, `errno != 0` otherwise + * on success: + * `result_buf_len` is set to the number of resolved addresses. `0 <= result_buf_len <= min(result_buf_len, 128)`. + * the first `result_buf_len` items of `result_buf` will be filled with resolved addresses + */ +int32_t k2_lookup_host(const char *host, size_t host_len, struct SockAddr *result_buf, size_t *result_buf_len); + +/** + * Only available during `k2_create_component` call. Returns `0` in other context. + * Arguments are constants and do not change during the component lifetime. + * @return number of arguments available for fetching. + */ +uint32_t k2_args_count(); + +/** + * @param `arg_num` must satisfy `0 <= arg_num <= k2_args_count()` + * @return length of argument key with number `arg_num` in bytes + */ +uint32_t k2_args_key_len(uint32_t arg_num); + +/** + * @param `arg_num` must satisfy `0 <= arg_num <= k2_args_count()` + * @return length of argumen value with number `arg_num` in bytes + */ +uint32_t k2_args_value_len(uint32_t arg_num); + +/** + * Note: key and value are **not** null-terminated. + * @param `arg_num` must satisfy `0 <= arg_num <= k2_args_count()` + * @param `key` buffer where key will be written, buffer len must staisfy `0 <= len <= k2_args_key_len(arg_num)` + * @param `value` buffer where value will be written, buffer len must staisfy `0 <= len <= k2_args_value_len(arg_num)` + */ +void k2_args_fetch(uint32_t arg_num, char *key, char *value); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/runtime-light/runtime-light.cmake b/runtime-light/runtime-light.cmake index 92f8d3188c..87b716820d 100644 --- a/runtime-light/runtime-light.cmake +++ b/runtime-light/runtime-light.cmake @@ -6,7 +6,7 @@ include(${RUNTIME_LIGHT_DIR}/stdlib/stdlib.cmake) include(${RUNTIME_LIGHT_DIR}/streams/streams.cmake) include(${RUNTIME_LIGHT_DIR}/tl/tl.cmake) include(${RUNTIME_LIGHT_DIR}/utils/utils.cmake) -include(${RUNTIME_LIGHT_DIR}/component/component.cmake) +include(${RUNTIME_LIGHT_DIR}/state/state.cmake) include(${RUNTIME_LIGHT_DIR}/memory-resource-impl/memory-resource-impl.cmake) set(RUNTIME_LIGHT_SRC @@ -16,7 +16,7 @@ set(RUNTIME_LIGHT_SRC ${RUNTIME_LIGHT_SERVER_SRC} ${RUNTIME_LIGHT_ALLOCATOR_SRC} ${RUNTIME_LIGHT_COROUTINE_SRC} - ${RUNTIME_LIGHT_COMPONENT_SRC} + ${RUNTIME_LIGHT_STATE_SRC} ${RUNTIME_LIGHT_STREAMS_SRC} ${RUNTIME_LIGHT_TL_SRC} ${RUNTIME_LIGHT_UTILS_SRC} @@ -37,6 +37,12 @@ target_compile_options(runtime-light PUBLIC -stdlib=libc++ -iquote ${GENERATED_DIR} -fPIC -O3) target_link_options(runtime-light PUBLIC -stdlib=libc++ -static-libstdc++) +if(APPLE) + target_link_options(runtime-light PUBLIC -undefined dynamic_lookup) +else() + target_link_options(runtime-light PUBLIC --allow-shlib-undefined) +endif() + vk_add_library(kphp-light-runtime STATIC) target_link_libraries( kphp-light-runtime PUBLIC vk::light-common vk::light-unicode diff --git a/runtime-light/runtime-light.cpp b/runtime-light/runtime-light.cpp index 2ff5ebf2ff..413b0bde4f 100644 --- a/runtime-light/runtime-light.cpp +++ b/runtime-light/runtime-light.cpp @@ -3,56 +3,60 @@ // Distributed under the GPL v3 License, see LICENSE.notice.txt #include "runtime-common/core/utils/kphp-assert-core.h" -#include "runtime-light/component/component.h" -#include "runtime-light/component/image.h" #include "runtime-light/core/globals/php-init-scripts.h" -#include "runtime-light/utils/context.h" - -ImageState *vk_k2_create_image_state(const struct PlatformCtx *pt_ctx) { - // Note that in vk_k2_create_image_state available only allocator and logs from pt_ctx - platformCtx = pt_ctx; - php_debug("create image state on \"%s\"", vk_k2_describe()->image_name); - char *buffer = static_cast(platformCtx->allocator.alloc(sizeof(ImageState))); - if (buffer == nullptr) { - php_warning("cannot allocate enough memory for ImageState"); +#include "runtime-light/k2-platform/k2-api.h" +#include "runtime-light/state/image-state.h" +#include "runtime-light/state/instance-state.h" + +ImageState *k2_create_image() { + // Note that in k2_create_image most of K2 functionality is not yet available + php_debug("create image state of \"%s\"", k2::describe()->image_name); + auto *image_state_ptr{static_cast(k2::alloc(sizeof(ImageState)))}; + if (image_state_ptr == nullptr) { + php_warning("can't allocate enough memory for ImageState"); return nullptr; } - mutableImageState = new (buffer) ImageState(); - imageState = mutableImageState; + php_debug("finish image state creation of \"%s\"", k2::describe()->image_name); + return image_state_ptr; +} + +void k2_init_image() { + php_debug("start image state init"); + new (const_cast(k2::image_state())) ImageState{}; init_php_scripts_once_in_master(); - ImageState *mutable_image_state = mutableImageState; - php_debug("finish image state creation on \"%s\"", vk_k2_describe()->image_name); - reset_thread_locals(); - return mutable_image_state; + php_debug("end image state init"); } -ComponentState *vk_k2_create_component_state(const struct ImageState *image_state, const struct PlatformCtx *pt_ctx) { - // Note that in vk_k2_create_component_state available only allocator and logs from pt_ctx - imageState = image_state; - platformCtx = pt_ctx; - php_debug("create component state on \"%s\"", vk_k2_describe()->image_name); - char *buffer = static_cast(platformCtx->allocator.alloc(sizeof(ComponentState))); - if (buffer == nullptr) { +ComponentState *k2_create_component() { + return nullptr; +} + +void k2_init_component() {} + +InstanceState *k2_create_instance() { + // Note that in k2_create_instance most of K2 functionality is not yet available + php_debug("create instance state of \"%s\"", k2::describe()->image_name); + auto *instance_state_ptr{static_cast(k2::alloc(sizeof(InstanceState)))}; + if (instance_state_ptr == nullptr) { php_warning("cannot allocate enough memory for ComponentState"); return nullptr; } - componentState = new (buffer) ComponentState(); - componentState->init_script_execution(); - ComponentState *component_state = componentState; - php_debug("finish component state creation on \"%s\"", vk_k2_describe()->image_name); - reset_thread_locals(); - return component_state; + php_debug("finish component state creation of \"%s\"", k2::describe()->image_name); + return instance_state_ptr; } -PollStatus vk_k2_poll(const ImageState *image_state, const PlatformCtx *pt_ctx, ComponentState *component_ctx) { - imageState = image_state; - platformCtx = pt_ctx; - componentState = component_ctx; +void k2_init_instance() { + php_debug("start instance state init"); + new (k2::instance_state()) InstanceState{}; + k2::instance_state()->init_script_execution(); + php_debug("end instance state init"); +} - php_debug("vk_k2_poll started..."); - componentState->process_platform_updates(); - const auto poll_status = componentState->poll_status; - php_debug("vk_k2_poll finished with status: %d", poll_status); - reset_thread_locals(); +k2::PollStatus k2_poll() { + php_debug("k2_poll started..."); + auto &instance_state{InstanceState::get()}; + instance_state.process_platform_updates(); + const auto poll_status{instance_state.poll_status}; + php_debug("k2_poll finished with status: %d", poll_status); return poll_status; } diff --git a/runtime-light/scheduler/scheduler.cpp b/runtime-light/scheduler/scheduler.cpp index 491d1d3d1b..4f0b13830d 100644 --- a/runtime-light/scheduler/scheduler.cpp +++ b/runtime-light/scheduler/scheduler.cpp @@ -11,13 +11,12 @@ #include #include -#include "runtime-light/component/component.h" -#include "runtime-light/utils/context.h" +#include "runtime-light/state/instance-state.h" // === SimpleCoroutineScheduler =================================================================== SimpleCoroutineScheduler &SimpleCoroutineScheduler::get() noexcept { - return get_component_context()->scheduler; + return InstanceState::get().scheduler; } ScheduleStatus SimpleCoroutineScheduler::scheduleOnNoEvent() noexcept { diff --git a/runtime-light/server/http/http-server-context.cpp b/runtime-light/server/http/http-server-context.cpp deleted file mode 100644 index 03126e1e87..0000000000 --- a/runtime-light/server/http/http-server-context.cpp +++ /dev/null @@ -1,12 +0,0 @@ -// Compiler for PHP (aka KPHP) -// Copyright (c) 2024 LLC «V Kontakte» -// Distributed under the GPL v3 License, see LICENSE.notice.txt - -#include "runtime-light/server/http/http-server-context.h" - -#include "runtime-light/component/component.h" -#include "runtime-light/utils/context.h" - -HttpServerComponentContext &HttpServerComponentContext::get() noexcept { - return get_component_context()->http_server_component_context; -} diff --git a/runtime-light/server/http/http-server-state.cpp b/runtime-light/server/http/http-server-state.cpp new file mode 100644 index 0000000000..81266e6d40 --- /dev/null +++ b/runtime-light/server/http/http-server-state.cpp @@ -0,0 +1,11 @@ +// Compiler for PHP (aka KPHP) +// Copyright (c) 2024 LLC «V Kontakte» +// Distributed under the GPL v3 License, see LICENSE.notice.txt + +#include "runtime-light/server/http/http-server-state.h" + +#include "runtime-light/state/instance-state.h" + +HttpServerInstanceState &HttpServerInstanceState::get() noexcept { + return InstanceState::get().http_server_instance_state; +} diff --git a/runtime-light/server/http/http-server-context.h b/runtime-light/server/http/http-server-state.h similarity index 76% rename from runtime-light/server/http/http-server-context.h rename to runtime-light/server/http/http-server-state.h index 72bd5b3694..d8e01436d6 100644 --- a/runtime-light/server/http/http-server-context.h +++ b/runtime-light/server/http/http-server-state.h @@ -8,11 +8,11 @@ #include "common/mixin/not_copyable.h" -struct HttpServerComponentContext final : private vk::not_copyable { +struct HttpServerInstanceState final : private vk::not_copyable { static constexpr auto ENCODING_GZIP = static_cast(1U << 0U); static constexpr auto ENCODING_DEFLATE = static_cast(1U << 1U); uint32_t encoding{}; - static HttpServerComponentContext &get() noexcept; + static HttpServerInstanceState &get() noexcept; }; diff --git a/runtime-light/server/http/init-functions.cpp b/runtime-light/server/http/init-functions.cpp index 99e42e8106..1fe6536c18 100644 --- a/runtime-light/server/http/init-functions.cpp +++ b/runtime-light/server/http/init-functions.cpp @@ -15,12 +15,11 @@ #include "runtime-common/core/runtime-core.h" #include "runtime-common/core/utils/kphp-assert-core.h" -#include "runtime-light/component/component.h" #include "runtime-light/core/globals/php-script-globals.h" -#include "runtime-light/server/http/http-server-context.h" +#include "runtime-light/server/http/http-server-state.h" +#include "runtime-light/state/instance-state.h" #include "runtime-light/tl/tl-functions.h" #include "runtime-light/tl/tl-types.h" -#include "runtime-light/utils/context.h" namespace { @@ -82,17 +81,17 @@ void process_cookie_header(const string &header, PhpScriptBuiltInSuperGlobals &s void process_headers(tl::dictionary &&headers, PhpScriptBuiltInSuperGlobals &superglobals) noexcept { auto &server{superglobals.v$_SERVER}; - auto &http_server_ctx{HttpServerComponentContext::get()}; + auto &http_server_ctx{HttpServerInstanceState::get()}; using namespace PhpServerSuperGlobalIndices; // platform provides headers that are already in lowercase for (auto &[header_name, header] : headers) { if (std::strcmp(header_name.c_str(), HEADER_ACCEPT_ENCODING) == 0) { if (std::strstr(header.value.c_str(), ENCODING_GZIP) != nullptr) { - http_server_ctx.encoding |= HttpServerComponentContext::ENCODING_GZIP; + http_server_ctx.encoding |= HttpServerInstanceState::ENCODING_GZIP; } if (std::strstr(header.value.c_str(), ENCODING_DEFLATE) != nullptr) { - http_server_ctx.encoding |= HttpServerComponentContext::ENCODING_DEFLATE; + http_server_ctx.encoding |= HttpServerInstanceState::ENCODING_DEFLATE; } } else if (std::strcmp(header_name.c_str(), HEADER_COOKIE) == 0) { process_cookie_header(header.value, superglobals); @@ -117,7 +116,7 @@ void process_headers(tl::dictionary &&headers, PhpScriptBui } // namespace void init_http_server(tl::K2InvokeHttp &&invoke_http) noexcept { - auto &superglobals{get_component_context()->php_script_mutable_globals_singleton.get_superglobals()}; + auto &superglobals{InstanceState::get().php_script_mutable_globals_singleton.get_superglobals()}; auto &server{superglobals.v$_SERVER}; HttpMethod http_method{HttpMethod::OTHER}; diff --git a/runtime-light/server/init-functions.h b/runtime-light/server/init-functions.h index afc88d61d5..aaa65d2b86 100644 --- a/runtime-light/server/init-functions.h +++ b/runtime-light/server/init-functions.h @@ -9,11 +9,10 @@ #include #include -#include "runtime-light/component/component.h" +#include "runtime-light/state/instance-state.h" #include "runtime-light/server/http/init-functions.h" #include "runtime-light/server/job-worker/init-functions.h" #include "runtime-light/tl/tl-functions.h" -#include "runtime-light/utils/context.h" using ServerQuery = std::variant; @@ -24,7 +23,7 @@ inline void init_server(ServerQuery &&query) noexcept { // common initialization { using namespace PhpServerSuperGlobalIndices; - auto &server{get_component_context()->php_script_mutable_globals_singleton.get_superglobals().v$_SERVER}; + auto &server{InstanceState::get().php_script_mutable_globals_singleton.get_superglobals().v$_SERVER}; server.set_value(string{SERVER_SOFTWARE, std::char_traits::length(SERVER_SOFTWARE)}, string{SERVER_SOFTWARE_VALUE, std::char_traits::length(SERVER_SOFTWARE_VALUE)}); server.set_value(string{SERVER_SIGNATURE, std::char_traits::length(SERVER_SIGNATURE)}, diff --git a/runtime-light/server/job-worker/init-functions.h b/runtime-light/server/job-worker/init-functions.h index 3f97141640..f93012fbd7 100644 --- a/runtime-light/server/job-worker/init-functions.h +++ b/runtime-light/server/job-worker/init-functions.h @@ -4,22 +4,21 @@ #pragma once -#include "runtime-light/component/component.h" #include "runtime-light/core/globals/php-script-globals.h" -#include "runtime-light/server/job-worker/job-worker-server-context.h" +#include "runtime-light/server/job-worker/job-worker-server-state.h" +#include "runtime-light/state/instance-state.h" #include "runtime-light/tl/tl-functions.h" -#include "runtime-light/utils/context.h" inline void init_job_server(tl::K2InvokeJobWorker &&invoke_jw) noexcept { - auto &jw_server_ctx{JobWorkerServerComponentContext::get()}; - jw_server_ctx.kind = invoke_jw.ignore_answer ? JobWorkerServerComponentContext::Kind::NoReply : JobWorkerServerComponentContext::Kind::Regular; - jw_server_ctx.state = JobWorkerServerComponentContext::State::Working; + auto &jw_server_ctx{JobWorkerServerInstanceState::get()}; + jw_server_ctx.kind = invoke_jw.ignore_answer ? JobWorkerServerInstanceState::Kind::NoReply : JobWorkerServerInstanceState::Kind::Regular; + jw_server_ctx.state = JobWorkerServerInstanceState::State::Working; jw_server_ctx.job_id = invoke_jw.job_id; jw_server_ctx.body = std::move(invoke_jw.body); { using namespace PhpServerSuperGlobalIndices; - auto &server{get_component_context()->php_script_mutable_globals_singleton.get_superglobals().v$_SERVER}; + auto &server{InstanceState::get().php_script_mutable_globals_singleton.get_superglobals().v$_SERVER}; server.set_value(string{JOB_ID, std::char_traits::length(JOB_ID)}, invoke_jw.job_id); } } diff --git a/runtime-light/server/job-worker/job-worker-server-context.cpp b/runtime-light/server/job-worker/job-worker-server-context.cpp deleted file mode 100644 index 8f18c8712f..0000000000 --- a/runtime-light/server/job-worker/job-worker-server-context.cpp +++ /dev/null @@ -1,12 +0,0 @@ -// Compiler for PHP (aka KPHP) -// Copyright (c) 2024 LLC «V Kontakte» -// Distributed under the GPL v3 License, see LICENSE.notice.txt - -#include "runtime-light/server/job-worker/job-worker-server-context.h" - -#include "runtime-light/component/component.h" -#include "runtime-light/utils/context.h" - -JobWorkerServerComponentContext &JobWorkerServerComponentContext::get() noexcept { - return get_component_context()->job_worker_server_component_context; -} diff --git a/runtime-light/server/job-worker/job-worker-server-state.cpp b/runtime-light/server/job-worker/job-worker-server-state.cpp new file mode 100644 index 0000000000..c37d300d2b --- /dev/null +++ b/runtime-light/server/job-worker/job-worker-server-state.cpp @@ -0,0 +1,11 @@ +// Compiler for PHP (aka KPHP) +// Copyright (c) 2024 LLC «V Kontakte» +// Distributed under the GPL v3 License, see LICENSE.notice.txt + +#include "runtime-light/server/job-worker/job-worker-server-state.h" + +#include "runtime-light/state/instance-state.h" + +JobWorkerServerInstanceState &JobWorkerServerInstanceState::get() noexcept { + return InstanceState::get().job_worker_server_instance_state; +} diff --git a/runtime-light/server/job-worker/job-worker-server-context.h b/runtime-light/server/job-worker/job-worker-server-state.h similarity index 80% rename from runtime-light/server/job-worker/job-worker-server-context.h rename to runtime-light/server/job-worker/job-worker-server-state.h index fe972c22b0..f5fb822ab2 100644 --- a/runtime-light/server/job-worker/job-worker-server-context.h +++ b/runtime-light/server/job-worker/job-worker-server-state.h @@ -10,7 +10,7 @@ #include "runtime-common/core/runtime-core.h" #include "runtime-light/stdlib/job-worker/job-worker.h" -struct JobWorkerServerComponentContext final : private vk::not_copyable { +struct JobWorkerServerInstanceState final : private vk::not_copyable { enum class Kind : uint8_t { Invalid, Regular, NoReply }; enum class State : uint8_t { Invalid, Working, Replied }; @@ -19,5 +19,5 @@ struct JobWorkerServerComponentContext final : private vk::not_copyable { int64_t job_id{JOB_WORKER_INVALID_JOB_ID}; string body; - static JobWorkerServerComponentContext &get() noexcept; + static JobWorkerServerInstanceState &get() noexcept; }; diff --git a/runtime-light/server/server.cmake b/runtime-light/server/server.cmake index 6325fdfa06..32b392561e 100644 --- a/runtime-light/server/server.cmake +++ b/runtime-light/server/server.cmake @@ -1,2 +1,2 @@ prepend(RUNTIME_LIGHT_SERVER_SRC server/ http/init-functions.cpp - http/http-server-context.cpp job-worker/job-worker-server-context.cpp) + http/http-server-state.cpp job-worker/job-worker-server-state.cpp) diff --git a/runtime-light/state/component-state.h b/runtime-light/state/component-state.h new file mode 100644 index 0000000000..ac2cab59a0 --- /dev/null +++ b/runtime-light/state/component-state.h @@ -0,0 +1,29 @@ +// Compiler for PHP (aka KPHP) +// Copyright (c) 2024 LLC «V Kontakte» +// Distributed under the GPL v3 License, see LICENSE.notice.txt + +#pragma once + +#include + +#include "common/mixin/not_copyable.h" +#include "runtime-common/core/allocator/runtime-allocator.h" +#include "runtime-light/k2-platform/k2-api.h" + +struct ComponentState final : private vk::not_copyable { + RuntimeAllocator allocator; + + ComponentState() noexcept + : allocator(INIT_COMPONENT_ALLOCATOR_SIZE, 0) {} + + static const ComponentState &get() noexcept { + return *k2::component_state(); + } + + static ComponentState &get_mutable() noexcept { + return *const_cast(k2::component_state()); + } + +private: + static constexpr auto INIT_COMPONENT_ALLOCATOR_SIZE = static_cast(512U * 1024U); // 512KB +}; diff --git a/runtime-light/state/image-state.h b/runtime-light/state/image-state.h new file mode 100644 index 0000000000..7a293d58b3 --- /dev/null +++ b/runtime-light/state/image-state.h @@ -0,0 +1,35 @@ +// Compiler for PHP (aka KPHP) +// Copyright (c) 2024 LLC «V Kontakte» +// Distributed under the GPL v3 License, see LICENSE.notice.txt + +#pragma once + +#include + +#include "common/mixin/not_copyable.h" +#include "runtime-common/core/allocator/runtime-allocator.h" +#include "runtime-light/k2-platform/k2-api.h" +#include "runtime-light/stdlib/rpc/rpc-state.h" +#include "runtime-light/stdlib/string/string-state.h" + +struct ImageState final : private vk::not_copyable { + RuntimeAllocator allocator; + + char *c_linear_mem{nullptr}; + RpcImageState rpc_image_state{}; + StringImageState string_image_state{}; + + ImageState() noexcept + : allocator(INIT_IMAGE_ALLOCATOR_SIZE, 0) {} + + static const ImageState &get() noexcept { + return *k2::image_state(); + } + + static ImageState &get_mutable() noexcept { + return *const_cast(k2::image_state()); + } + +private: + static constexpr auto INIT_IMAGE_ALLOCATOR_SIZE = static_cast(512U * 1024U); // 512KB +}; diff --git a/runtime-light/component/init-functions.cpp b/runtime-light/state/init-functions.cpp similarity index 76% rename from runtime-light/component/init-functions.cpp rename to runtime-light/state/init-functions.cpp index 33fc911a50..5d2f762ca1 100644 --- a/runtime-light/component/init-functions.cpp +++ b/runtime-light/state/init-functions.cpp @@ -2,21 +2,20 @@ // Copyright (c) 2024 LLC «V Kontakte» // Distributed under the GPL v3 License, see LICENSE.notice.txt -#include "runtime-light/component/init-functions.h" +#include "runtime-light/state/init-functions.h" #include #include "runtime-common/core/utils/kphp-assert-core.h" -#include "runtime-light/component/component.h" #include "runtime-light/coroutine/awaitable.h" #include "runtime-light/coroutine/task.h" -#include "runtime-light/header.h" +#include "runtime-light/k2-platform/k2-api.h" #include "runtime-light/server/init-functions.h" -#include "runtime-light/server/job-worker/job-worker-server-context.h" +#include "runtime-light/server/job-worker/job-worker-server-state.h" +#include "runtime-light/state/instance-state.h" #include "runtime-light/streams/streams.h" #include "runtime-light/tl/tl-core.h" #include "runtime-light/tl/tl-functions.h" -#include "runtime-light/utils/context.h" namespace { @@ -33,7 +32,7 @@ void process_k2_invoke_job_worker(tl::TLBuffer &tlb) noexcept { if (!invoke_jw.fetch(tlb)) { php_error("erroneous job worker request"); } - php_assert(invoke_jw.image_id == vk_k2_describe()->build_timestamp); // ensure that we got the request from ourselves + php_assert(invoke_jw.image_id == k2::describe()->build_timestamp); // ensure that we got the request from ourselves init_server(ServerQuery{std::move(invoke_jw)}); } @@ -45,7 +44,7 @@ task_t init_kphp_server_component() noexcept { php_assert(size >= sizeof(uint32_t)); // check that we can fetch at least magic tl::TLBuffer tlb{}; tlb.store_bytes({buffer, static_cast(size)}); - get_platform_context()->allocator.free(buffer); + k2::free(buffer); switch (const auto magic{*tlb.lookup_trivial()}) { // lookup magic case tl::K2_INVOKE_HTTP_MAGIC: { @@ -55,8 +54,8 @@ task_t init_kphp_server_component() noexcept { case tl::K2_INVOKE_JOB_WORKER_MAGIC: { process_k2_invoke_job_worker(tlb); // release standard stream in case of a no reply job worker since we don't need that stream anymore - if (JobWorkerServerComponentContext::get().kind == JobWorkerServerComponentContext::Kind::NoReply) { - get_component_context()->release_stream(stream_d); + if (JobWorkerServerInstanceState::get().kind == JobWorkerServerInstanceState::Kind::NoReply) { + InstanceState::get().release_stream(stream_d); stream_d = INVALID_PLATFORM_DESCRIPTOR; } break; diff --git a/runtime-light/component/init-functions.h b/runtime-light/state/init-functions.h similarity index 100% rename from runtime-light/component/init-functions.h rename to runtime-light/state/init-functions.h diff --git a/runtime-light/component/component.cpp b/runtime-light/state/instance-state.cpp similarity index 72% rename from runtime-light/component/component.cpp rename to runtime-light/state/instance-state.cpp index 3c695f0cb0..f4b794614d 100644 --- a/runtime-light/component/component.cpp +++ b/runtime-light/state/instance-state.cpp @@ -2,7 +2,7 @@ // Copyright (c) 2024 LLC «V Kontakte» // Distributed under the GPL v3 License, see LICENSE.notice.txt -#include "runtime-light/component/component.h" +#include "runtime-light/state/instance-state.h" #include #include @@ -13,21 +13,20 @@ #include "runtime-common/core/runtime-core.h" #include "runtime-common/core/utils/kphp-assert-core.h" -#include "runtime-light/component/init-functions.h" #include "runtime-light/core/globals/php-init-scripts.h" #include "runtime-light/core/globals/php-script-globals.h" #include "runtime-light/coroutine/task.h" -#include "runtime-light/header.h" +#include "runtime-light/k2-platform/k2-api.h" #include "runtime-light/scheduler/scheduler.h" -#include "runtime-light/server/job-worker/job-worker-server-context.h" +#include "runtime-light/server/job-worker/job-worker-server-state.h" +#include "runtime-light/state/init-functions.h" #include "runtime-light/streams/streams.h" -#include "runtime-light/utils/context.h" namespace { int32_t merge_output_buffers() noexcept { - auto &component_ctx{*get_component_context()}; - Response &response{component_ctx.response}; + auto &instance_st{InstanceState::get()}; + Response &response{instance_st.response}; php_assert(response.current_buffer >= 0); int32_t ob_first_not_empty{}; @@ -42,26 +41,25 @@ int32_t merge_output_buffers() noexcept { } // namespace -void ComponentState::init_script_execution() noexcept { - runtime_component_context.init(); +void InstanceState::init_script_execution() noexcept { + runtime_context.init(); init_php_scripts_in_each_worker(php_script_mutable_globals_singleton, main_task_); scheduler.suspend(std::make_pair(main_task_.get_handle(), WaitEvent::Rechedule{})); } -template -task_t ComponentState::run_component_prologue() noexcept { - static_assert(kind != ComponentKind::Invalid); - component_kind_ = kind; +template +task_t InstanceState::run_instance_prologue() noexcept { + static_assert(kind != ImageKind::Invalid); + image_kind_ = kind; // common initialization auto &superglobals{php_script_mutable_globals_singleton.get_superglobals()}; superglobals.v$argc = static_cast(0); // TODO superglobals.v$argv = array{}; // TODO { - const auto &platform_ctx{*get_platform_context()}; SystemTime sys_time{}; - platform_ctx.get_system_time(std::addressof(sys_time)); + k2::system_time(std::addressof(sys_time)); const auto time_mcs{std::chrono::duration_cast(std::chrono::nanoseconds{sys_time.since_epoch_ns}).count()}; using namespace PhpServerSuperGlobalIndices; @@ -75,24 +73,24 @@ task_t ComponentState::run_component_prologue() noexcept { // TODO sapi, env // specific initialization - if constexpr (kind == ComponentKind::CLI) { + if constexpr (kind == ImageKind::CLI) { standard_stream_ = co_await init_kphp_cli_component(); - } else if constexpr (kind == ComponentKind::Server) { + } else if constexpr (kind == ImageKind::Server) { standard_stream_ = co_await init_kphp_server_component(); } } -template task_t ComponentState::run_component_prologue(); -template task_t ComponentState::run_component_prologue(); -template task_t ComponentState::run_component_prologue(); -template task_t ComponentState::run_component_prologue(); +template task_t InstanceState::run_instance_prologue(); +template task_t InstanceState::run_instance_prologue(); +template task_t InstanceState::run_instance_prologue(); +template task_t InstanceState::run_instance_prologue(); -task_t ComponentState::run_component_epilogue() noexcept { - if (component_kind_ == ComponentKind::Oneshot || component_kind_ == ComponentKind::Multishot) { +task_t InstanceState::run_instance_epilogue() noexcept { + if (image_kind_ == ImageKind::Oneshot || image_kind_ == ImageKind::Multishot) { co_return; } // do not flush output buffers if we are in job worker - if (job_worker_server_component_context.kind != JobWorkerServerComponentContext::Kind::Invalid) { + if (job_worker_server_instance_state.kind != JobWorkerServerInstanceState::Kind::Invalid) { co_return; } if (standard_stream() == INVALID_PLATFORM_DESCRIPTOR) { @@ -106,12 +104,10 @@ task_t ComponentState::run_component_epilogue() noexcept { } } -void ComponentState::process_platform_updates() noexcept { - const auto &platform_ctx{*get_platform_context()}; - +void InstanceState::process_platform_updates() noexcept { for (;;) { // check if platform asked for yield - if (static_cast(platform_ctx.please_yield.load())) { // tell the scheduler that we are about to yield + if (static_cast(k2::control_flags()->please_yield.load())) { // tell the scheduler that we are about to yield php_debug("platform asked for yield"); const auto schedule_status{scheduler.schedule(ScheduleEvent::Yield{})}; poll_status = schedule_status == ScheduleStatus::Error ? PollStatus::PollFinishedError : PollStatus::PollReschedule; @@ -119,7 +115,7 @@ void ComponentState::process_platform_updates() noexcept { } // try taking update from the platform - if (uint64_t stream_d{}; static_cast(platform_ctx.take_update(std::addressof(stream_d)))) { + if (uint64_t stream_d{}; static_cast(k2::take_update(std::addressof(stream_d)))) { if (opened_streams_.contains(stream_d)) { // update on opened stream php_debug("took update on stream %" PRIu64, stream_d); switch (scheduler.schedule(ScheduleEvent::UpdateOnStream{.stream_d = stream_d})) { @@ -164,7 +160,7 @@ void ComponentState::process_platform_updates() noexcept { poll_status = PollStatus::PollFinishedError; } -uint64_t ComponentState::take_incoming_stream() noexcept { +uint64_t InstanceState::take_incoming_stream() noexcept { if (incoming_streams_.empty()) { php_warning("can't take incoming stream cause we don't have them"); return INVALID_PLATFORM_DESCRIPTOR; @@ -175,10 +171,9 @@ uint64_t ComponentState::take_incoming_stream() noexcept { return stream_d; } -uint64_t ComponentState::open_stream(std::string_view component_name_view) noexcept { +uint64_t InstanceState::open_stream(std::string_view component_name_view) noexcept { uint64_t stream_d{}; - if (const auto open_stream_res{get_platform_context()->open(component_name_view.size(), component_name_view.data(), std::addressof(stream_d))}; - open_stream_res != OpenStreamResult::OpenStreamOk) { + if (const auto open_stream_res{k2::open(std::addressof(stream_d), component_name_view.size(), component_name_view.data())}; open_stream_res != k2::errno_ok) { php_warning("can't open stream to %s", component_name_view.data()); return INVALID_PLATFORM_DESCRIPTOR; } @@ -187,10 +182,9 @@ uint64_t ComponentState::open_stream(std::string_view component_name_view) noexc return stream_d; } -uint64_t ComponentState::set_timer(std::chrono::nanoseconds duration) noexcept { +uint64_t InstanceState::set_timer(std::chrono::nanoseconds duration) noexcept { uint64_t timer_d{}; - if (const auto set_timer_res{get_platform_context()->set_timer(std::addressof(timer_d), static_cast(duration.count()))}; - set_timer_res != SetTimerResult::SetTimerOk) { + if (const auto set_timer_res{k2::new_timer(std::addressof(timer_d), static_cast(duration.count()))}; set_timer_res != k2::errno_ok) { php_warning("can't set timer for %.9f sec", std::chrono::duration(duration).count()); return INVALID_PLATFORM_DESCRIPTOR; } @@ -199,21 +193,20 @@ uint64_t ComponentState::set_timer(std::chrono::nanoseconds duration) noexcept { return timer_d; } -void ComponentState::release_stream(uint64_t stream_d) noexcept { +void InstanceState::release_stream(uint64_t stream_d) noexcept { if (stream_d == standard_stream_) { standard_stream_ = INVALID_PLATFORM_DESCRIPTOR; } opened_streams_.erase(stream_d); pending_updates_.erase(stream_d); // also erase pending updates if exists - get_platform_context()->free_descriptor(stream_d); + k2::free_descriptor(stream_d); php_debug("released a stream %" PRIu64, stream_d); } -void ComponentState::release_all_streams() noexcept { - const auto &platform_ctx{*get_platform_context()}; +void InstanceState::release_all_streams() noexcept { standard_stream_ = INVALID_PLATFORM_DESCRIPTOR; for (const auto stream_d : opened_streams_) { - platform_ctx.free_descriptor(stream_d); + k2::free_descriptor(stream_d); php_debug("released a stream %" PRIu64, stream_d); } opened_streams_.clear(); diff --git a/runtime-light/state/instance-state.h b/runtime-light/state/instance-state.h new file mode 100644 index 0000000000..eee2c51436 --- /dev/null +++ b/runtime-light/state/instance-state.h @@ -0,0 +1,139 @@ +// Compiler for PHP (aka KPHP) +// Copyright (c) 2024 LLC «V Kontakte» +// Distributed under the GPL v3 License, see LICENSE.notice.txt + +#pragma once + +#include +#include +#include +#include + +#include "common/mixin/not_copyable.h" +#include "runtime-common/core/memory-resource/resource_allocator.h" +#include "runtime-common/core/memory-resource/unsynchronized_pool_resource.h" +#include "runtime-common/core/runtime-core.h" +#include "runtime-light/core/globals/php-script-globals.h" +#include "runtime-light/coroutine/task.h" +#include "runtime-light/k2-platform/k2-api.h" +#include "runtime-light/scheduler/scheduler.h" +#include "runtime-light/server/http/http-server-state.h" +#include "runtime-light/server/job-worker/job-worker-server-state.h" +#include "runtime-light/stdlib/crypto/crypto-state.h" +#include "runtime-light/stdlib/curl/curl-state.h" +#include "runtime-light/stdlib/file/file-stream-state.h" +#include "runtime-light/stdlib/fork/fork-state.h" +#include "runtime-light/stdlib/job-worker/job-worker-client-state.h" +#include "runtime-light/stdlib/output/output-buffer.h" +#include "runtime-light/stdlib/regex/regex-state.h" +#include "runtime-light/stdlib/rpc/rpc-state.h" +#include "runtime-light/stdlib/string/string-state.h" +#include "runtime-light/stdlib/system/system-state.h" + +inline constexpr uint64_t INVALID_PLATFORM_DESCRIPTOR = 0; + +// Coroutine scheduler type. Change it here if you want to use another scheduler +using CoroutineScheduler = SimpleCoroutineScheduler; +static_assert(CoroutineSchedulerConcept); + +/** + * Supported kinds of KPHP images: + * 1. CLI — works the same way as regular PHP script does + * 2. Server — automatically accepts a stream and expects it to contain either http or job worker request + * 3. Oneshot — can only accept one incoming stream + * 4. Multishot — can accept any number of incoming streams + */ +enum class ImageKind : uint8_t { Invalid, CLI, Server, Oneshot, Multishot }; + +struct InstanceState final : vk::not_copyable { + template + using unordered_set = memory_resource::stl::unordered_set; + + template + using deque = memory_resource::stl::deque; + + InstanceState() noexcept + : allocator(INIT_INSTANCE_ALLOCATOR_SIZE, 0) + , scheduler(allocator.memory_resource) + , fork_instance_state(allocator.memory_resource) + , php_script_mutable_globals_singleton(allocator.memory_resource) + , rpc_instance_state(allocator.memory_resource) + , incoming_streams_(deque::allocator_type{allocator.memory_resource}) + , opened_streams_(unordered_set::allocator_type{allocator.memory_resource}) + , pending_updates_(unordered_set::allocator_type{allocator.memory_resource}) {} + + ~InstanceState() = default; + + static InstanceState &get() noexcept { + return *k2::instance_state(); + } + + void init_script_execution() noexcept; + + template + task_t run_instance_prologue() noexcept; + + task_t run_instance_epilogue() noexcept; + + ImageKind image_kind() const noexcept { + return image_kind_; + } + + void process_platform_updates() noexcept; + + bool stream_updated(uint64_t stream_d) const noexcept { + return pending_updates_.contains(stream_d); + } + const unordered_set &opened_streams() const noexcept { + return opened_streams_; + } + const deque &incoming_streams() const noexcept { + return incoming_streams_; + } + uint64_t standard_stream() const noexcept { + return standard_stream_; + } + uint64_t take_incoming_stream() noexcept; + + uint64_t open_stream(std::string_view) noexcept; + uint64_t open_stream(const string &component_name) noexcept { + return open_stream(std::string_view{component_name.c_str(), static_cast(component_name.size())}); + } + + uint64_t set_timer(std::chrono::nanoseconds) noexcept; + void release_stream(uint64_t) noexcept; + void release_all_streams() noexcept; + + RuntimeAllocator allocator; + + CoroutineScheduler scheduler; + ForkInstanceState fork_instance_state; + k2::PollStatus poll_status{k2::PollStatus::PollReschedule}; + + Response response; + PhpScriptMutableGlobals php_script_mutable_globals_singleton; + + RuntimeContext runtime_context; + RpcInstanceState rpc_instance_state; + HttpServerInstanceState http_server_instance_state{}; + JobWorkerClientInstanceState job_worker_client_instance_state{}; + JobWorkerServerInstanceState job_worker_server_instance_state{}; + + RegexInstanceState regex_instance_state{}; + CurlInstanceState curl_instance_state{}; + CryptoInstanceState crypto_instance_state{}; + StringInstanceState string_instance_state{}; + SystemInstanceState system_instance_state{}; + FileStreamInstanceState file_stream_instance_state{}; + +private: + task_t main_task_; + + ImageKind image_kind_{ImageKind::Invalid}; + uint64_t standard_stream_{INVALID_PLATFORM_DESCRIPTOR}; + deque incoming_streams_; + unordered_set opened_streams_; + unordered_set pending_updates_; + + static constexpr auto INIT_INSTANCE_ALLOCATOR_SIZE = static_cast(512U * 1024U); // 512KB +}; diff --git a/runtime-light/state/state.cmake b/runtime-light/state/state.cmake new file mode 100644 index 0000000000..2076964a3b --- /dev/null +++ b/runtime-light/state/state.cmake @@ -0,0 +1 @@ +prepend(RUNTIME_LIGHT_STATE_SRC state/ instance-state.cpp init-functions.cpp) diff --git a/runtime-light/stdlib/component/component-api.cpp b/runtime-light/stdlib/component/component-api.cpp index f4f95b05e8..1e7c470178 100644 --- a/runtime-light/stdlib/component/component-api.cpp +++ b/runtime-light/stdlib/component/component-api.cpp @@ -8,16 +8,16 @@ #include "runtime-common/core/runtime-core.h" #include "runtime-common/core/utils/kphp-assert-core.h" -#include "runtime-light/component/component.h" #include "runtime-light/coroutine/awaitable.h" #include "runtime-light/coroutine/task.h" +#include "runtime-light/k2-platform/k2-api.h" +#include "runtime-light/state/instance-state.h" #include "runtime-light/streams/streams.h" -#include "runtime-light/utils/context.h" // === component query client interface =========================================================== task_t> f$component_client_send_request(string name, string message) noexcept { - const auto stream_d{get_component_context()->open_stream(name)}; + const auto stream_d{InstanceState::get().open_stream(name)}; if (stream_d == INVALID_PLATFORM_DESCRIPTOR) { co_return class_instance{}; } @@ -28,7 +28,7 @@ task_t> f$component_client_send_request(string co_return class_instance{}; } - get_platform_context()->shutdown_write(stream_d); + k2::shutdown_write(stream_d); php_debug("sent %d bytes from %d to '%s' on stream %" PRIu64, written, message.size(), name.c_str(), stream_d); co_return make_instance(stream_d); } @@ -42,9 +42,9 @@ task_t f$component_client_fetch_response(class_instance(size)}; - get_platform_context()->allocator.free(buffer); + k2::free(buffer); php_debug("read %d bytes from stream %" PRIu64, size, stream_d); - get_component_context()->release_stream(stream_d); + InstanceState::get().release_stream(stream_d); query.get()->stream_d = INVALID_PLATFORM_DESCRIPTOR; co_return result; } @@ -59,7 +59,7 @@ task_t f$component_server_fetch_request(class_instance uint64_t stream_d{query.is_null() ? INVALID_PLATFORM_DESCRIPTOR : query.get()->stream_d}; const auto [buffer, size]{co_await read_all_from_stream(stream_d)}; string result{buffer, static_cast(size)}; - get_platform_context()->allocator.free(buffer); + k2::free(buffer); co_return result; } @@ -70,5 +70,5 @@ task_t f$component_server_send_response(class_instance q } else { php_debug("sent %d bytes as response to stream %" PRIu64, message.size(), stream_d); } - get_component_context()->release_stream(stream_d); + InstanceState::get().release_stream(stream_d); } diff --git a/runtime-light/stdlib/component/component-api.h b/runtime-light/stdlib/component/component-api.h index 8b5135ab07..ab4265c185 100644 --- a/runtime-light/stdlib/component/component-api.h +++ b/runtime-light/stdlib/component/component-api.h @@ -10,9 +10,8 @@ #include "runtime-common/core/class-instance/refcountable-php-classes.h" #include "runtime-common/core/runtime-core.h" -#include "runtime-light/component/component.h" #include "runtime-light/coroutine/task.h" -#include "runtime-light/utils/context.h" +#include "runtime-light/state/instance-state.h" // === ComponentQuery ============================================================================= @@ -37,9 +36,9 @@ struct C$ComponentQuery final : public refcountable_php_classescrypto_component_context; -} diff --git a/runtime-light/stdlib/crypto/crypto-functions.h b/runtime-light/stdlib/crypto/crypto-functions.h index 02e7963ad1..94339ddfdf 100644 --- a/runtime-light/stdlib/crypto/crypto-functions.h +++ b/runtime-light/stdlib/crypto/crypto-functions.h @@ -6,16 +6,21 @@ #include "runtime-common/core/runtime-core.h" #include "runtime-light/coroutine/task.h" -#include "runtime-light/stdlib/crypto/crypto-context.h" +#include "runtime-light/stdlib/crypto/crypto-state.h" #include "runtime-light/tl/tl-types.h" task_t> f$openssl_random_pseudo_bytes(int64_t length) noexcept; + task_t>> f$openssl_x509_parse(const string &data, bool shortnames = true) noexcept; -task_t f$openssl_sign(const string &data, string &signature, const string &private_key, int64_t algo=tl::DigestAlgorithm::SHA1) noexcept; -task_t f$openssl_verify(const string &data, const string &signature, const string &pub_key_id, int64_t algo=tl::DigestAlgorithm::SHA1) noexcept; + +task_t f$openssl_sign(const string &data, string &signature, const string &private_key, int64_t algo = tl::DigestAlgorithm::SHA1) noexcept; + +task_t f$openssl_verify(const string &data, const string &signature, const string &pub_key_id, int64_t algo = tl::DigestAlgorithm::SHA1) noexcept; inline Optional f$openssl_encrypt(const string &data __attribute__((unused)), const string &method __attribute__((unused)), - const string &key __attribute__((unused)), int64_t options __attribute__((unused)) = 0, const string &iv __attribute__((unused)) = string{}, - string &tag __attribute__((unused)) = CryptoComponentContext::get().default_tag_dummy, const string &aad __attribute__((unused)) = string{}, int64_t tag_length __attribute__((unused)) = 16) { + const string &key __attribute__((unused)), int64_t options __attribute__((unused)) = 0, + const string &iv __attribute__((unused)) = string{}, + string &tag __attribute__((unused)) = CryptoInstanceState::get().default_tag_dummy, + const string &aad __attribute__((unused)) = string{}, int64_t tag_length __attribute__((unused)) = 16) noexcept { php_critical_error("call to unsupported function"); } diff --git a/runtime-light/stdlib/crypto/crypto-state.cpp b/runtime-light/stdlib/crypto/crypto-state.cpp new file mode 100644 index 0000000000..d4ba710427 --- /dev/null +++ b/runtime-light/stdlib/crypto/crypto-state.cpp @@ -0,0 +1,11 @@ +// Compiler for PHP (aka KPHP) +// Copyright (c) 2024 LLC «V Kontakte» +// Distributed under the GPL v3 License, see LICENSE.notice.txt + +#include "runtime-light/stdlib/crypto/crypto-state.h" + +#include "runtime-light/state/instance-state.h" + +CryptoInstanceState &CryptoInstanceState::get() noexcept { + return InstanceState::get().crypto_instance_state; +} diff --git a/runtime-light/stdlib/crypto/crypto-context.h b/runtime-light/stdlib/crypto/crypto-state.h similarity index 68% rename from runtime-light/stdlib/crypto/crypto-context.h rename to runtime-light/stdlib/crypto/crypto-state.h index 2327482209..de33388b3e 100644 --- a/runtime-light/stdlib/crypto/crypto-context.h +++ b/runtime-light/stdlib/crypto/crypto-state.h @@ -6,8 +6,8 @@ #include "runtime-common/core/runtime-core.h" -struct CryptoComponentContext final : vk::not_copyable { +struct CryptoInstanceState final : private vk::not_copyable { string default_tag_dummy; - static CryptoComponentContext &get() noexcept; + static CryptoInstanceState &get() noexcept; }; diff --git a/runtime-light/stdlib/curl/curl-context.cpp b/runtime-light/stdlib/curl/curl-context.cpp deleted file mode 100644 index 3e68fcb3e6..0000000000 --- a/runtime-light/stdlib/curl/curl-context.cpp +++ /dev/null @@ -1,12 +0,0 @@ -// Compiler for PHP (aka KPHP) -// Copyright (c) 2024 LLC «V Kontakte» -// Distributed under the GPL v3 License, see LICENSE.notice.txt - -#include "runtime-light/stdlib/curl/curl-context.h" - -#include "runtime-light/component/component.h" -#include "runtime-light/utils/context.h" - -CurlComponentContext &CurlComponentContext::get() noexcept { - return get_component_context()->curl_component_context; -} diff --git a/runtime-light/stdlib/curl/curl-functions.h b/runtime-light/stdlib/curl/curl-functions.h index 012b327228..40afac0721 100644 --- a/runtime-light/stdlib/curl/curl-functions.h +++ b/runtime-light/stdlib/curl/curl-functions.h @@ -7,9 +7,9 @@ #include #include "runtime-common/core/runtime-core.h" -#include "runtime-light/stdlib/curl/curl-context.h" +#include "runtime-light/stdlib/curl/curl-state.h" -inline Optional> f$curl_multi_info_read(int64_t, int64_t & = CurlComponentContext::get().curl_multi_info_read_msgs_in_queue_stub) { +inline Optional> f$curl_multi_info_read(int64_t, int64_t & = CurlInstanceState::get().curl_multi_info_read_msgs_in_queue_stub) { php_critical_error("call to unsupported function : curl_multi_info_read"); } diff --git a/runtime-light/stdlib/curl/curl-state.cpp b/runtime-light/stdlib/curl/curl-state.cpp new file mode 100644 index 0000000000..0c0ab08239 --- /dev/null +++ b/runtime-light/stdlib/curl/curl-state.cpp @@ -0,0 +1,11 @@ +// Compiler for PHP (aka KPHP) +// Copyright (c) 2024 LLC «V Kontakte» +// Distributed under the GPL v3 License, see LICENSE.notice.txt + +#include "runtime-light/stdlib/curl/curl-state.h" + +#include "runtime-light/state/instance-state.h" + +CurlInstanceState &CurlInstanceState::get() noexcept { + return InstanceState::get().curl_instance_state; +} diff --git a/runtime-light/stdlib/curl/curl-context.h b/runtime-light/stdlib/curl/curl-state.h similarity index 61% rename from runtime-light/stdlib/curl/curl-context.h rename to runtime-light/stdlib/curl/curl-state.h index e6a13a208f..ffef55704c 100644 --- a/runtime-light/stdlib/curl/curl-context.h +++ b/runtime-light/stdlib/curl/curl-state.h @@ -6,8 +6,10 @@ #include -struct CurlComponentContext { +#include "common/mixin/not_copyable.h" + +struct CurlInstanceState final : private vk::not_copyable { int64_t curl_multi_info_read_msgs_in_queue_stub{}; - static CurlComponentContext &get() noexcept; + static CurlInstanceState &get() noexcept; }; diff --git a/runtime-light/stdlib/exception/exception-functions.h b/runtime-light/stdlib/exception/exception-functions.h index 63d39a7d6d..e50c9acec8 100644 --- a/runtime-light/stdlib/exception/exception-functions.h +++ b/runtime-light/stdlib/exception/exception-functions.h @@ -2,7 +2,6 @@ // Copyright (c) 2024 LLC «V Kontakte» // Distributed under the GPL v3 License, see LICENSE.notice.txt - #pragma once #include "runtime-common/core/runtime-core.h" diff --git a/runtime-light/stdlib/exit/exit-functions.cpp b/runtime-light/stdlib/exit/exit-functions.cpp index 8db7a4ad3b..57eff70e45 100644 --- a/runtime-light/stdlib/exit/exit-functions.cpp +++ b/runtime-light/stdlib/exit/exit-functions.cpp @@ -6,14 +6,15 @@ #include -#include "runtime-light/component/component.h" -#include "runtime-light/header.h" -#include "runtime-light/utils/context.h" +#include "runtime-light/k2-platform/k2-api.h" +#include "runtime-light/state/instance-state.h" task_t f$exit(const mixed &v) noexcept { // TODO: make it synchronous + auto &instance_st{InstanceState::get()}; + int64_t exit_code{}; if (v.is_string()) { - Response &response{get_component_context()->response}; + Response &response{instance_st.response}; response.output_buffers[response.current_buffer] << v; } else if (v.is_int()) { int64_t v_code{v.to_int()}; @@ -22,10 +23,9 @@ task_t f$exit(const mixed &v) noexcept { // TODO: make it synchronous } else { exit_code = 1; } - auto &component_ctx{*get_component_context()}; - co_await component_ctx.run_component_epilogue(); - component_ctx.poll_status = - component_ctx.poll_status != PollStatus::PollFinishedError && exit_code == 0 ? PollStatus::PollFinishedOk : PollStatus::PollFinishedError; - component_ctx.release_all_streams(); - get_platform_context()->exit(static_cast(exit_code)); + co_await instance_st.run_instance_epilogue(); + instance_st.poll_status = + instance_st.poll_status != k2::PollStatus::PollFinishedError && exit_code == 0 ? k2::PollStatus::PollFinishedOk : k2::PollStatus::PollFinishedError; + instance_st.release_all_streams(); + k2::exit(static_cast(exit_code)); } diff --git a/runtime-light/stdlib/file/file-stream-context.cpp b/runtime-light/stdlib/file/file-stream-context.cpp deleted file mode 100644 index 9edf534b8e..0000000000 --- a/runtime-light/stdlib/file/file-stream-context.cpp +++ /dev/null @@ -1,11 +0,0 @@ -// Compiler for PHP (aka KPHP) -// Copyright (c) 2024 LLC «V Kontakte» -// Distributed under the GPL v3 License, see LICENSE.notice.txt - -#include "runtime-light/stdlib/file/file-stream-context.h" - -#include "runtime-light/component/component.h" - -FileStreamComponentContext &FileStreamComponentContext::get() noexcept { - return get_component_context()->file_stream_component_context; -} diff --git a/runtime-light/stdlib/file/file-stream-functions.h b/runtime-light/stdlib/file/file-stream-functions.h index 43ef4f4cd9..39f29afbbc 100644 --- a/runtime-light/stdlib/file/file-stream-functions.h +++ b/runtime-light/stdlib/file/file-stream-functions.h @@ -6,10 +6,9 @@ #include -#include "runtime-light/stdlib/file/file-stream-context.h" +#include "runtime-light/stdlib/file/file-stream-state.h" -inline mixed f$stream_socket_client(const string &, mixed & = FileStreamComponentContext::get().error_number_dummy, - mixed & = FileStreamComponentContext::get().error_description_dummy, double = -1, int64_t = 1, - const mixed & = mixed()) { +inline mixed f$stream_socket_client(const string &, mixed & = FileStreamInstanceState::get().error_number_dummy, + mixed & = FileStreamInstanceState::get().error_description_dummy, double = -1, int64_t = 1, const mixed & = mixed()) { php_critical_error("call to unsupported function"); } diff --git a/runtime-light/stdlib/file/file-stream-state.cpp b/runtime-light/stdlib/file/file-stream-state.cpp new file mode 100644 index 0000000000..9179f47a77 --- /dev/null +++ b/runtime-light/stdlib/file/file-stream-state.cpp @@ -0,0 +1,11 @@ +// Compiler for PHP (aka KPHP) +// Copyright (c) 2024 LLC «V Kontakte» +// Distributed under the GPL v3 License, see LICENSE.notice.txt + +#include "runtime-light/stdlib/file/file-stream-state.h" + +#include "runtime-light/state/instance-state.h" + +FileStreamInstanceState &FileStreamInstanceState::get() noexcept { + return InstanceState::get().file_stream_instance_state; +} diff --git a/runtime-light/stdlib/file/file-stream-context.h b/runtime-light/stdlib/file/file-stream-state.h similarity index 62% rename from runtime-light/stdlib/file/file-stream-context.h rename to runtime-light/stdlib/file/file-stream-state.h index 0a6327444d..ca03e02335 100644 --- a/runtime-light/stdlib/file/file-stream-context.h +++ b/runtime-light/stdlib/file/file-stream-state.h @@ -4,11 +4,12 @@ #pragma once +#include "common/mixin/not_copyable.h" #include "runtime-common/core/runtime-core.h" -struct FileStreamComponentContext { +struct FileStreamInstanceState final : private vk::not_copyable { mixed error_number_dummy; mixed error_description_dummy; - static FileStreamComponentContext &get() noexcept; + static FileStreamInstanceState &get() noexcept; }; diff --git a/runtime-light/stdlib/fork/fork-context.cpp b/runtime-light/stdlib/fork/fork-context.cpp deleted file mode 100644 index 9006243eac..0000000000 --- a/runtime-light/stdlib/fork/fork-context.cpp +++ /dev/null @@ -1,12 +0,0 @@ -// Compiler for PHP (aka KPHP) -// Copyright (c) 2024 LLC «V Kontakte» -// Distributed under the GPL v3 License, see LICENSE.notice.txt - -#include "runtime-light/stdlib/fork/fork-context.h" - -#include "runtime-light/component/component.h" -#include "runtime-light/utils/context.h" - -ForkComponentContext &ForkComponentContext::get() noexcept { - return get_component_context()->fork_component_context; -} diff --git a/runtime-light/stdlib/fork/fork-functions.h b/runtime-light/stdlib/fork/fork-functions.h index a2d32f0606..5f9bf84cf1 100644 --- a/runtime-light/stdlib/fork/fork-functions.h +++ b/runtime-light/stdlib/fork/fork-functions.h @@ -13,7 +13,7 @@ #include "runtime-common/core/utils/kphp-assert-core.h" #include "runtime-light/coroutine/awaitable.h" #include "runtime-light/coroutine/task.h" -#include "runtime-light/stdlib/fork/fork-context.h" +#include "runtime-light/stdlib/fork/fork-state.h" namespace fork_api_impl_ { @@ -28,7 +28,7 @@ inline constexpr auto DEFAULT_TIMEOUT_NS = std::chrono::duration_cast requires(is_optional::value || std::same_as || is_class_instance::value) task_t f$wait(int64_t fork_id, double timeout = -1.0) noexcept { - auto &fork_ctx{ForkComponentContext::get()}; + auto &fork_ctx{ForkInstanceState::get()}; if (!fork_ctx.contains(fork_id)) { php_warning("can't find fork %" PRId64, fork_id); co_return T{}; @@ -42,7 +42,8 @@ requires(is_optional::value || std::same_as || is_class_instance } template -requires(is_optional::value || std::same_as || is_class_instance::value) task_t f$wait(Optional fork_id_opt, double timeout = -1.0) noexcept { +requires(is_optional::value || std::same_as || is_class_instance::value) task_t f$wait(Optional fork_id_opt, + double timeout = -1.0) noexcept { co_return co_await f$wait(fork_id_opt.has_value() ? fork_id_opt.val() : INVALID_FORK_ID, timeout); } @@ -61,7 +62,7 @@ inline task_t f$sched_yield_sleep(double duration) noexcept { // === Non-blocking API ============================================================================ inline int64_t f$get_running_fork_id() noexcept { - return ForkComponentContext::get().running_fork_id; + return ForkInstanceState::get().running_fork_id; } inline int64_t f$wait_queue_create() { @@ -84,7 +85,7 @@ inline Optional f$wait_queue_next(int64_t queue_id, double timeout = -1 php_critical_error("call to unsupported function"); } -inline bool f$wait_concurrently (int64_t fork_id) { +inline bool f$wait_concurrently(int64_t fork_id) { php_critical_error("call to unsupported function"); } diff --git a/runtime-light/stdlib/fork/fork-state.cpp b/runtime-light/stdlib/fork/fork-state.cpp new file mode 100644 index 0000000000..c890edcff1 --- /dev/null +++ b/runtime-light/stdlib/fork/fork-state.cpp @@ -0,0 +1,11 @@ +// Compiler for PHP (aka KPHP) +// Copyright (c) 2024 LLC «V Kontakte» +// Distributed under the GPL v3 License, see LICENSE.notice.txt + +#include "runtime-light/stdlib/fork/fork-state.h" + +#include "runtime-light/state/instance-state.h" + +ForkInstanceState &ForkInstanceState::get() noexcept { + return InstanceState::get().fork_instance_state; +} diff --git a/runtime-light/stdlib/fork/fork-context.h b/runtime-light/stdlib/fork/fork-state.h similarity index 86% rename from runtime-light/stdlib/fork/fork-context.h rename to runtime-light/stdlib/fork/fork-state.h index b9fde8c1c2..10ebe5f28f 100644 --- a/runtime-light/stdlib/fork/fork-context.h +++ b/runtime-light/stdlib/fork/fork-state.h @@ -7,6 +7,7 @@ #include #include +#include "common/mixin/not_copyable.h" #include "runtime-common/core/memory-resource/unsynchronized_pool_resource.h" #include "runtime-common/core/utils/kphp-assert-core.h" #include "runtime-light/coroutine/task.h" @@ -14,7 +15,7 @@ inline constexpr int64_t INVALID_FORK_ID = -1; -class ForkComponentContext { +class ForkInstanceState final : private vk::not_copyable { template using unordered_map = memory_resource::stl::unordered_map; @@ -44,10 +45,10 @@ class ForkComponentContext { public: int64_t running_fork_id{FORK_ID_INIT}; - explicit ForkComponentContext(memory_resource::unsynchronized_pool_resource &memory_resource) noexcept + explicit ForkInstanceState(memory_resource::unsynchronized_pool_resource &memory_resource) noexcept : forks(unordered_map>::allocator_type{memory_resource}) {} - static ForkComponentContext &get() noexcept; + static ForkInstanceState &get() noexcept; bool contains(int64_t fork_id) const noexcept { return forks.contains(fork_id); diff --git a/runtime-light/stdlib/hash/hash-functions.cpp b/runtime-light/stdlib/hash/hash-functions.cpp index d1ba955d93..8bfa4e00d3 100644 --- a/runtime-light/stdlib/hash/hash-functions.cpp +++ b/runtime-light/stdlib/hash/hash-functions.cpp @@ -47,7 +47,7 @@ static int base64_encode(const unsigned char *const input, int ilen, char *outpu return 0; } -string f$base64_encode(const string &s) { +string f$base64_encode(const string &s) noexcept { int result_len = (s.size() + 2) / 3 * 4; string res(result_len, false); result_len = base64_encode(reinterpret_cast(s.c_str()), static_cast(s.size()), res.buffer(), result_len + 1); @@ -73,7 +73,7 @@ static constexpr short base64_reverse_table[256] = {-2, -2, -2, -2, -2, -2, -2, /* Function f$base64_decode ported from https://github.com/php/php-src/blob/master/ext/standard/base64.c#L130 * "This product includes PHP software, freely available from ". */ -Optional f$base64_decode(const string &s, bool strict) { +Optional f$base64_decode(const string &s, bool strict) noexcept { /* run through the whole string, converting as we go */ string::size_type result_len = (s.size() + 3) / 4 * 3; string result(result_len, false); diff --git a/runtime-light/stdlib/hash/hash-functions.h b/runtime-light/stdlib/hash/hash-functions.h index 3b95a5742e..e8ca21369a 100644 --- a/runtime-light/stdlib/hash/hash-functions.h +++ b/runtime-light/stdlib/hash/hash-functions.h @@ -6,5 +6,6 @@ #include "runtime-common/core/runtime-core.h" -string f$base64_encode(const string &s); -Optional f$base64_decode(const string &s, bool strict = false); +string f$base64_encode(const string &s) noexcept; + +Optional f$base64_decode(const string &s, bool strict = false) noexcept; diff --git a/runtime-light/stdlib/instance-cache/instance-cache.h b/runtime-light/stdlib/instance-cache/instance-cache.h index dcff53d1fe..2b7a09139c 100644 --- a/runtime-light/stdlib/instance-cache/instance-cache.h +++ b/runtime-light/stdlib/instance-cache/instance-cache.h @@ -7,11 +7,11 @@ #include "runtime-common/core/runtime-core.h" template -bool f$instance_cache_store(const string &key, const ClassInstanceType &instance, int64_t ttl = 0) { +bool f$instance_cache_store(const string & /*key*/, const ClassInstanceType & /*instance*/, int64_t /*ttl*/ = 0) { php_critical_error("call to unsupported function"); } template -ClassInstanceType f$instance_cache_fetch(const string &class_name, const string &key, bool even_if_expired = false) { +ClassInstanceType f$instance_cache_fetch(const string & /*class_name*/, const string & /*key*/, bool /*even_if_expired*/ = false) { php_critical_error("call to unsupported function"); } diff --git a/runtime-light/stdlib/job-worker/job-worker-api.cpp b/runtime-light/stdlib/job-worker/job-worker-api.cpp index 78213eac37..59265087f1 100644 --- a/runtime-light/stdlib/job-worker/job-worker-api.cpp +++ b/runtime-light/stdlib/job-worker/job-worker-api.cpp @@ -12,20 +12,19 @@ #include "runtime-common/core/runtime-core.h" #include "runtime-common/core/utils/kphp-assert-core.h" -#include "runtime-light/component/component.h" #include "runtime-light/coroutine/awaitable.h" #include "runtime-light/coroutine/task.h" -#include "runtime-light/header.h" -#include "runtime-light/server/job-worker/job-worker-server-context.h" +#include "runtime-light/k2-platform/k2-api.h" +#include "runtime-light/server/job-worker/job-worker-server-state.h" +#include "runtime-light/state/instance-state.h" #include "runtime-light/stdlib/component/component-api.h" -#include "runtime-light/stdlib/fork/fork-context.h" -#include "runtime-light/stdlib/job-worker/job-worker-client-context.h" +#include "runtime-light/stdlib/fork/fork-state.h" +#include "runtime-light/stdlib/job-worker/job-worker-client-state.h" #include "runtime-light/stdlib/job-worker/job-worker.h" #include "runtime-light/streams/streams.h" #include "runtime-light/tl/tl-core.h" #include "runtime-light/tl/tl-functions.h" #include "runtime-light/tl/tl-types.h" -#include "runtime-light/utils/context.h" namespace { @@ -44,13 +43,13 @@ task_t kphp_job_worker_start_impl(string request, double timeout, bool co_return INVALID_FORK_ID; } - auto &jw_client_ctx{JobWorkerClientComponentContext::get()}; + auto &jw_client_st{JobWorkerClientInstanceState::get()}; // normalize timeout const auto timeout_ns{std::chrono::duration_cast(std::chrono::duration(std::clamp(timeout, MIN_TIMEOUT_S, MAX_TIMEOUT_S)))}; // prepare JW component request tl::TLBuffer tlb{}; - const tl::K2InvokeJobWorker invoke_jw{.image_id = vk_k2_describe()->build_timestamp, - .job_id = jw_client_ctx.current_job_id++, + const tl::K2InvokeJobWorker invoke_jw{.image_id = k2::describe()->build_timestamp, + .job_id = jw_client_st.current_job_id++, .ignore_answer = ignore_answer, .timeout_ns = static_cast(timeout_ns.count()), .body = std::move(request)}; @@ -111,27 +110,27 @@ task_t f$job_worker_fetch_request() noexcept { co_return string{}; } - auto &jw_server_ctx{JobWorkerServerComponentContext::get()}; - if (jw_server_ctx.job_id == JOB_WORKER_INVALID_JOB_ID || jw_server_ctx.body.empty()) { + auto &jw_server_st{JobWorkerServerInstanceState::get()}; + if (jw_server_st.job_id == JOB_WORKER_INVALID_JOB_ID || jw_server_st.body.empty()) { php_warning("couldn't fetch job worker request"); co_return string{}; } - co_return std::exchange(jw_server_ctx.body, string{}); + co_return std::exchange(jw_server_st.body, string{}); } task_t f$job_worker_store_response(string response) noexcept { - auto &component_ctx{*get_component_context()}; - auto &jw_server_ctx{JobWorkerServerComponentContext::get()}; + auto &instance_st{InstanceState::get()}; + auto &jw_server_st{JobWorkerServerInstanceState::get()}; if (!f$is_kphp_job_workers_enabled()) { // workers are enabled php_warning("couldn't store job worker response: job workers are disabled"); co_return static_cast(JobWorkerError::store_response_incorrect_call_error); - } else if (jw_server_ctx.kind != JobWorkerServerComponentContext::Kind::Regular) { // we're in regular worker + } else if (jw_server_st.kind != JobWorkerServerInstanceState::Kind::Regular) { // we're in regular worker php_warning("couldn't store job worker response: we are either in no reply job worker or not in a job worker at all"); co_return static_cast(JobWorkerError::store_response_incorrect_call_error); - } else if (jw_server_ctx.state == JobWorkerServerComponentContext::State::Replied) { // it's the first attempt to reply + } else if (jw_server_st.state == JobWorkerServerInstanceState::State::Replied) { // it's the first attempt to reply php_warning("couldn't store job worker response: multiple stores are forbidden"); co_return static_cast(JobWorkerError::store_response_incorrect_call_error); - } else if (component_ctx.standard_stream() == INVALID_PLATFORM_DESCRIPTOR) { // we have a stream to write into + } else if (instance_st.standard_stream() == INVALID_PLATFORM_DESCRIPTOR) { // we have a stream to write into php_warning("couldn't store job worker response: no standard stream"); co_return static_cast(JobWorkerError::store_response_incorrect_call_error); } else if (response.empty()) { // we have a response to reply @@ -140,12 +139,12 @@ task_t f$job_worker_store_response(string response) noexcept { } tl::TLBuffer tlb{}; - tl::K2JobWorkerResponse jw_response{.job_id = jw_server_ctx.job_id, .body = std::move(response)}; + tl::K2JobWorkerResponse jw_response{.job_id = jw_server_st.job_id, .body = std::move(response)}; jw_response.store(tlb); - if ((co_await write_all_to_stream(component_ctx.standard_stream(), tlb.data(), tlb.size())) != tlb.size()) { + if ((co_await write_all_to_stream(instance_st.standard_stream(), tlb.data(), tlb.size())) != tlb.size()) { php_warning("couldn't store job worker response"); co_return static_cast(JobWorkerError::store_response_cant_send_error); } - jw_server_ctx.state = JobWorkerServerComponentContext::State::Replied; + jw_server_st.state = JobWorkerServerInstanceState::State::Replied; co_return 0; } diff --git a/runtime-light/stdlib/job-worker/job-worker-api.h b/runtime-light/stdlib/job-worker/job-worker-api.h index f9c36a3339..5d51c23b44 100644 --- a/runtime-light/stdlib/job-worker/job-worker-api.h +++ b/runtime-light/stdlib/job-worker/job-worker-api.h @@ -7,9 +7,8 @@ #include #include "runtime-common/core/runtime-core.h" -#include "runtime-light/component/component.h" #include "runtime-light/coroutine/task.h" -#include "runtime-light/utils/context.h" +#include "runtime-light/state/instance-state.h" // === Client ===================================================================================== @@ -28,7 +27,7 @@ task_t f$job_worker_store_response(string response) noexcept; // === Misc ======================================================================================= inline bool f$is_kphp_job_workers_enabled() noexcept { - return get_component_context()->component_kind() == ComponentKind::Server; + return InstanceState::get().image_kind() == ImageKind::Server; } inline int64_t f$get_job_workers_number() noexcept { diff --git a/runtime-light/stdlib/job-worker/job-worker-client-context.cpp b/runtime-light/stdlib/job-worker/job-worker-client-context.cpp deleted file mode 100644 index b06ee7735d..0000000000 --- a/runtime-light/stdlib/job-worker/job-worker-client-context.cpp +++ /dev/null @@ -1,12 +0,0 @@ -// Compiler for PHP (aka KPHP) -// Copyright (c) 2024 LLC «V Kontakte» -// Distributed under the GPL v3 License, see LICENSE.notice.txt - -#include "runtime-light/stdlib/job-worker/job-worker-client-context.h" - -#include "runtime-light/component/component.h" -#include "runtime-light/utils/context.h" - -JobWorkerClientComponentContext &JobWorkerClientComponentContext::get() noexcept { - return get_component_context()->job_worker_client_component_context; -} diff --git a/runtime-light/stdlib/job-worker/job-worker-client-state.cpp b/runtime-light/stdlib/job-worker/job-worker-client-state.cpp new file mode 100644 index 0000000000..68dc9dfe0c --- /dev/null +++ b/runtime-light/stdlib/job-worker/job-worker-client-state.cpp @@ -0,0 +1,11 @@ +// Compiler for PHP (aka KPHP) +// Copyright (c) 2024 LLC «V Kontakte» +// Distributed under the GPL v3 License, see LICENSE.notice.txt + +#include "runtime-light/stdlib/job-worker/job-worker-client-state.h" + +#include "runtime-light/state/instance-state.h" + +JobWorkerClientInstanceState &JobWorkerClientInstanceState::get() noexcept { + return InstanceState::get().job_worker_client_instance_state; +} diff --git a/runtime-light/stdlib/job-worker/job-worker-client-context.h b/runtime-light/stdlib/job-worker/job-worker-client-state.h similarity index 71% rename from runtime-light/stdlib/job-worker/job-worker-client-context.h rename to runtime-light/stdlib/job-worker/job-worker-client-state.h index 394f797685..a4ba2cda16 100644 --- a/runtime-light/stdlib/job-worker/job-worker-client-context.h +++ b/runtime-light/stdlib/job-worker/job-worker-client-state.h @@ -9,8 +9,8 @@ #include "common/mixin/not_copyable.h" #include "runtime-light/stdlib/job-worker/job-worker.h" -struct JobWorkerClientComponentContext final : private vk::not_copyable { +struct JobWorkerClientInstanceState final : private vk::not_copyable { int64_t current_job_id{JOB_WORKER_VALID_JOB_ID_RANGE_START}; - static JobWorkerClientComponentContext &get() noexcept; + static JobWorkerClientInstanceState &get() noexcept; }; diff --git a/runtime-light/stdlib/output/http-functions.h b/runtime-light/stdlib/output/http-functions.h index 0c43c9f2b1..8a746c0518 100644 --- a/runtime-light/stdlib/output/http-functions.h +++ b/runtime-light/stdlib/output/http-functions.h @@ -9,6 +9,7 @@ #include "runtime-common/core/runtime-core.h" template -string f$http_build_query(const array &a, const string &numeric_prefix = {}, const string &arg_separator = string(), int64_t enc_type = 1) { +string f$http_build_query(const array & /*a*/, const string & /*numeric_prefix*/ = {}, const string & /*arg_separator*/ = string(), + int64_t /*enc_type*/ = 1) { php_critical_error("call to unsupported function"); } diff --git a/runtime-light/stdlib/output/output-buffer.cpp b/runtime-light/stdlib/output/output-buffer.cpp index 91675a1645..4493c10907 100644 --- a/runtime-light/stdlib/output/output-buffer.cpp +++ b/runtime-light/stdlib/output/output-buffer.cpp @@ -6,14 +6,13 @@ #include -#include "runtime-light/component/component.h" +#include "runtime-light/state/instance-state.h" #include "runtime-light/stdlib/output/print-functions.h" -#include "runtime-light/utils/context.h" static constexpr int32_t system_level_buffer = 0; void f$ob_start(const string &callback) noexcept { - Response &httpResponse{get_component_context()->response}; + Response &httpResponse{InstanceState::get().response}; if (httpResponse.current_buffer + 1 == Response::ob_max_buffers) { php_warning("Maximum nested level of output buffering reached. Can't do ob_start(%s)", callback.c_str()); return; @@ -26,7 +25,7 @@ void f$ob_start(const string &callback) noexcept { } Optional f$ob_get_length() noexcept { - Response &httpResponse{get_component_context()->response}; + Response &httpResponse{InstanceState::get().response}; if (httpResponse.current_buffer == 0) { return false; } @@ -34,16 +33,16 @@ Optional f$ob_get_length() noexcept { } int64_t f$ob_get_level() noexcept { - return get_component_context()->response.current_buffer; + return InstanceState::get().response.current_buffer; } void f$ob_clean() noexcept { - Response &httpResponse{get_component_context()->response}; + Response &httpResponse{InstanceState::get().response}; httpResponse.output_buffers[httpResponse.current_buffer].clean(); } bool f$ob_end_clean() noexcept { - Response &httpResponse{get_component_context()->response}; + Response &httpResponse{InstanceState::get().response}; if (httpResponse.current_buffer == system_level_buffer) { return false; } @@ -53,7 +52,7 @@ bool f$ob_end_clean() noexcept { } Optional f$ob_get_clean() noexcept { - Response &httpResponse{get_component_context()->response}; + Response &httpResponse{InstanceState::get().response}; if (httpResponse.current_buffer == system_level_buffer) { return false; } @@ -61,12 +60,12 @@ Optional f$ob_get_clean() noexcept { } string f$ob_get_contents() noexcept { - Response &httpResponse{get_component_context()->response}; + Response &httpResponse{InstanceState::get().response}; return httpResponse.output_buffers[httpResponse.current_buffer].str(); } void f$ob_flush() noexcept { - Response &httpResponse{get_component_context()->response}; + Response &httpResponse{InstanceState::get().response}; if (httpResponse.current_buffer == 0) { php_warning("ob_flush with no buffer opented"); return; @@ -78,7 +77,7 @@ void f$ob_flush() noexcept { } bool f$ob_end_flush() noexcept { - Response &httpResponse{get_component_context()->response}; + Response &httpResponse{InstanceState::get().response}; if (httpResponse.current_buffer == 0) { return false; } @@ -87,7 +86,7 @@ bool f$ob_end_flush() noexcept { } Optional f$ob_get_flush() noexcept { - Response &httpResponse{get_component_context()->response}; + Response &httpResponse{InstanceState::get().response}; if (httpResponse.current_buffer == 0) { return false; } diff --git a/runtime-light/stdlib/output/print-functions.cpp b/runtime-light/stdlib/output/print-functions.cpp index d08b8bfce1..e6401ddf5d 100644 --- a/runtime-light/stdlib/output/print-functions.cpp +++ b/runtime-light/stdlib/output/print-functions.cpp @@ -8,9 +8,8 @@ #include "runtime-common/core/runtime-core.h" #include "runtime-common/core/utils/kphp-assert-core.h" -#include "runtime-light/component/component.h" +#include "runtime-light/state/instance-state.h" #include "runtime-light/stdlib/output/output-buffer.h" -#include "runtime-light/utils/context.h" namespace { @@ -20,7 +19,7 @@ void do_print_r(const mixed &v, int32_t depth) noexcept { return; } - Response &httpResponse{get_component_context()->response}; + Response &httpResponse{InstanceState::get().response}; string_buffer &coub{httpResponse.output_buffers[httpResponse.current_buffer]}; switch (v.get_type()) { case mixed::type::NUL: @@ -71,7 +70,7 @@ void do_var_dump(const mixed &v, int32_t depth) noexcept { } string shift(depth * 2, ' '); - Response &httpResponse{get_component_context()->response}; + Response &httpResponse{InstanceState::get().response}; string_buffer &coub{httpResponse.output_buffers[httpResponse.current_buffer]}; switch (v.get_type()) { case mixed::type::NUL: @@ -119,7 +118,7 @@ void do_var_dump(const mixed &v, int32_t depth) noexcept { } void var_export_escaped_string(const string &s) noexcept { - Response &httpResponse{get_component_context()->response}; + Response &httpResponse{InstanceState::get().response}; string_buffer &coub{httpResponse.output_buffers[httpResponse.current_buffer]}; for (string::size_type i = 0; i < s.size(); i++) { switch (s[i]) { @@ -143,7 +142,7 @@ void do_var_export(const mixed &v, int32_t depth, char endc = 0) noexcept { } string shift(depth * 2, ' '); - Response &httpResponse{get_component_context()->response}; + Response &httpResponse{InstanceState::get().response}; string_buffer &coub{httpResponse.output_buffers[httpResponse.current_buffer]}; switch (v.get_type()) { case mixed::type::NUL: diff --git a/runtime-light/stdlib/output/print-functions.h b/runtime-light/stdlib/output/print-functions.h index 0a002a1006..6f5a525348 100644 --- a/runtime-light/stdlib/output/print-functions.h +++ b/runtime-light/stdlib/output/print-functions.h @@ -7,13 +7,12 @@ #include #include "runtime-common/core/runtime-core.h" -#include "runtime-light/component/component.h" -#include "runtime-light/utils/context.h" +#include "runtime-light/state/instance-state.h" // === print ====================================================================================== inline void print(const char *s, size_t len) noexcept { - Response &response{get_component_context()->response}; + Response &response{InstanceState::get().response}; response.output_buffers[response.current_buffer].append(s, len); } diff --git a/runtime-light/stdlib/regex/regex-functions.h b/runtime-light/stdlib/regex/regex-functions.h index f4c3c1876a..bad62830a6 100644 --- a/runtime-light/stdlib/regex/regex-functions.h +++ b/runtime-light/stdlib/regex/regex-functions.h @@ -5,7 +5,7 @@ #pragma once #include "runtime-common/core/runtime-core.h" -#include "runtime-light/stdlib/regex/regex-context.h" +#include "runtime-light/stdlib/regex/regex-state.h" class regexp final : private vk::not_copyable { public: @@ -20,83 +20,83 @@ class regexp final : private vk::not_copyable { template> auto f$preg_replace(const T1 ®ex, const T2 &replace_val, const T3 &subject, int64_t limit = -1, - int64_t &replace_count = RegexComponentContext::get().preg_replace_count_dummy) { + int64_t &replace_count = RegexInstanceState::get().preg_replace_count_dummy) { return f$preg_replace(regex, replace_val, subject.val(), limit, replace_count); } inline Optional f$preg_replace(const regexp &, const string &, const string &, int64_t = -1, - int64_t & = RegexComponentContext::get().preg_replace_count_dummy) { + int64_t & = RegexInstanceState::get().preg_replace_count_dummy) { php_critical_error("call to unsupported function"); } inline Optional f$preg_replace(const regexp &, const mixed &, const string &, int64_t = -1, - int64_t & = RegexComponentContext::get().preg_replace_count_dummy) { + int64_t & = RegexInstanceState::get().preg_replace_count_dummy) { php_critical_error("call to unsupported function"); } -inline mixed f$preg_replace(const regexp &, const string &, const mixed &, int64_t = -1, int64_t & = RegexComponentContext::get().preg_replace_count_dummy) { +inline mixed f$preg_replace(const regexp &, const string &, const mixed &, int64_t = -1, int64_t & = RegexInstanceState::get().preg_replace_count_dummy) { php_critical_error("call to unsupported function"); } -inline mixed f$preg_replace(const regexp &, const mixed &, const mixed &, int64_t = -1, int64_t & = RegexComponentContext::get().preg_replace_count_dummy) { +inline mixed f$preg_replace(const regexp &, const mixed &, const mixed &, int64_t = -1, int64_t & = RegexInstanceState::get().preg_replace_count_dummy) { php_critical_error("call to unsupported function"); } template auto f$preg_replace(const string ®ex, const T1 &replace_val, const T2 &subject, int64_t limit, - int64_t &replace_count = RegexComponentContext::get().preg_replace_count_dummy) { + int64_t &replace_count = RegexInstanceState::get().preg_replace_count_dummy) { return f$preg_replace(regexp(regex), replace_val, subject, limit, replace_count); } inline Optional f$preg_replace(const mixed &, const string &, const string &, int64_t = -1, - int64_t & = RegexComponentContext::get().preg_replace_count_dummy) { + int64_t & = RegexInstanceState::get().preg_replace_count_dummy) { php_critical_error("call to unsupported function"); } -inline mixed f$preg_replace(const mixed &, const string &, const mixed &, int64_t = -1, int64_t & = RegexComponentContext::get().preg_replace_count_dummy) { +inline mixed f$preg_replace(const mixed &, const string &, const mixed &, int64_t = -1, int64_t & = RegexInstanceState::get().preg_replace_count_dummy) { php_critical_error("call to unsupported function"); } inline Optional f$preg_replace(const mixed &, const mixed &, const string &, int64_t = -1, - int64_t & = RegexComponentContext::get().preg_replace_count_dummy) { + int64_t & = RegexInstanceState::get().preg_replace_count_dummy) { php_critical_error("call to unsupported function"); } -inline mixed f$preg_replace(const mixed &, const mixed &, const mixed &, int64_t = -1, int64_t & = RegexComponentContext::get().preg_replace_count_dummy) { +inline mixed f$preg_replace(const mixed &, const mixed &, const mixed &, int64_t = -1, int64_t & = RegexInstanceState::get().preg_replace_count_dummy) { php_critical_error("call to unsupported function"); } template> auto f$preg_replace_callback(const T1 ®ex, const T2 &replace_val, const T3 &subject, int64_t limit = -1, - int64_t &replace_count = RegexComponentContext::get().preg_replace_count_dummy) { + int64_t &replace_count = RegexInstanceState::get().preg_replace_count_dummy) { return f$preg_replace_callback(regex, replace_val, subject.val(), limit, replace_count); } template Optional f$preg_replace_callback(const regexp &, const T &, const string &, int64_t = -1, - int64_t & = RegexComponentContext::get().preg_replace_count_dummy) { + int64_t & = RegexInstanceState::get().preg_replace_count_dummy) { php_critical_error("call to unsupported function"); } template -mixed f$preg_replace_callback(const regexp &, const T &, const mixed &, int64_t = -1, int64_t & = RegexComponentContext::get().preg_replace_count_dummy) { +mixed f$preg_replace_callback(const regexp &, const T &, const mixed &, int64_t = -1, int64_t & = RegexInstanceState::get().preg_replace_count_dummy) { php_critical_error("call to unsupported function"); } template auto f$preg_replace_callback(const string ®ex, const T &replace_val, const T2 &subject, int64_t limit = -1, - int64_t &replace_count = RegexComponentContext::get().preg_replace_count_dummy) { + int64_t &replace_count = RegexInstanceState::get().preg_replace_count_dummy) { return f$preg_replace_callback(regexp(regex), replace_val, subject, limit, replace_count); } template Optional f$preg_replace_callback(const mixed &, const T &, const string &, int64_t = -1, - int64_t & = RegexComponentContext::get().preg_replace_count_dummy) { + int64_t & = RegexInstanceState::get().preg_replace_count_dummy) { php_critical_error("call to unsupported function"); } template -mixed f$preg_replace_callback(const mixed &, const T &, const mixed &, int64_t = -1, int64_t & = RegexComponentContext::get().preg_replace_count_dummy) { +mixed f$preg_replace_callback(const mixed &, const T &, const mixed &, int64_t = -1, int64_t & = RegexInstanceState::get().preg_replace_count_dummy) { php_critical_error("call to unsupported function"); } diff --git a/runtime-light/stdlib/regex/regex-context.cpp b/runtime-light/stdlib/regex/regex-state.cpp similarity index 53% rename from runtime-light/stdlib/regex/regex-context.cpp rename to runtime-light/stdlib/regex/regex-state.cpp index ef73837c1e..71b313558d 100644 --- a/runtime-light/stdlib/regex/regex-context.cpp +++ b/runtime-light/stdlib/regex/regex-state.cpp @@ -4,8 +4,8 @@ #include "runtime-light/stdlib/regex/regex-functions.h" -#include "runtime-light/component/component.h" +#include "runtime-light/state/instance-state.h" -RegexComponentContext &RegexComponentContext::get() noexcept { - return get_component_context()->regex_component_context; +RegexInstanceState &RegexInstanceState::get() noexcept { + return InstanceState::get().regex_instance_state; } diff --git a/runtime-light/stdlib/regex/regex-context.h b/runtime-light/stdlib/regex/regex-state.h similarity index 59% rename from runtime-light/stdlib/regex/regex-context.h rename to runtime-light/stdlib/regex/regex-state.h index 3fb8d15303..2abe12fb9d 100644 --- a/runtime-light/stdlib/regex/regex-context.h +++ b/runtime-light/stdlib/regex/regex-state.h @@ -6,8 +6,10 @@ #include -struct RegexComponentContext { +#include "common/mixin/not_copyable.h" + +struct RegexInstanceState final : private vk::not_copyable { int64_t preg_replace_count_dummy{}; - static RegexComponentContext &get() noexcept; + static RegexInstanceState &get() noexcept; }; diff --git a/runtime-light/stdlib/rpc/rpc-api.cpp b/runtime-light/stdlib/rpc/rpc-api.cpp index de2e113d5e..1ec956f66d 100644 --- a/runtime-light/stdlib/rpc/rpc-api.cpp +++ b/runtime-light/stdlib/rpc/rpc-api.cpp @@ -19,9 +19,9 @@ #include "runtime-light/coroutine/awaitable.h" #include "runtime-light/coroutine/task.h" #include "runtime-light/stdlib/component/component-api.h" -#include "runtime-light/stdlib/rpc/rpc-context.h" #include "runtime-light/stdlib/rpc/rpc-extra-headers.h" #include "runtime-light/stdlib/rpc/rpc-extra-info.h" +#include "runtime-light/stdlib/rpc/rpc-state.h" #include "runtime-light/tl/tl-core.h" namespace rpc_impl_ { @@ -98,7 +98,7 @@ class_instance store_function(const mixed &tl_object) noexcept { } task_t rpc_send_impl(string actor, double timeout, bool ignore_answer, bool collect_responses_extra_info) noexcept { - auto &rpc_ctx{RpcComponentContext::get()}; + auto &rpc_ctx{RpcInstanceState::get()}; // prepare RPC request string request_buf{}; size_t request_size{rpc_ctx.rpc_buffer.size()}; @@ -138,7 +138,7 @@ task_t rpc_send_impl(string actor, double timeout, bool ignore_ans const auto response{(co_await wait_with_timeout_t{task_t::awaiter_t{std::addressof(fetch_task)}, timeout}).value_or(string{})}; // update response extra info if needed if (collect_responses_extra_info) { - auto &extra_info_map{RpcComponentContext::get().rpc_responses_extra_info}; + auto &extra_info_map{RpcInstanceState::get().rpc_responses_extra_info}; if (const auto it_extra_info{extra_info_map.find(query_id)}; it_extra_info != extra_info_map.end()) { const auto timestamp{std::chrono::duration{std::chrono::system_clock::now().time_since_epoch()}.count()}; it_extra_info->second.second = std::make_tuple(response.size(), timestamp - std::get<1>(it_extra_info->second.second)); @@ -160,7 +160,7 @@ task_t rpc_send_impl(string actor, double timeout, bool ignore_ans } task_t rpc_tl_query_one_impl(string actor, mixed tl_object, double timeout, bool collect_resp_extra_info, bool ignore_answer) noexcept { - auto &rpc_ctx{RpcComponentContext::get()}; + auto &rpc_ctx{RpcInstanceState::get()}; if (!tl_object.is_array()) { rpc_ctx.current_query.raise_storing_error("not an array passed to function rpc_tl_query"); @@ -182,7 +182,7 @@ task_t rpc_tl_query_one_impl(string actor, mixed tl_object, double task_t typed_rpc_tl_query_one_impl(string actor, const RpcRequest &rpc_request, double timeout, bool collect_responses_extra_info, bool ignore_answer) noexcept { - auto &rpc_ctx{RpcComponentContext::get()}; + auto &rpc_ctx{RpcInstanceState::get()}; if (rpc_request.empty()) { rpc_ctx.current_query.raise_storing_error("query function is null"); @@ -212,7 +212,7 @@ task_t> rpc_tl_query_result_one_impl(int64_t query_id) noexcept { co_return make_fetch_error(string{"wrong query_id"}, TL_ERROR_WRONG_QUERY_ID); } - auto &rpc_ctx{RpcComponentContext::get()}; + auto &rpc_ctx{RpcInstanceState::get()}; class_instance rpc_query{}; int64_t response_waiter_fork_id{INVALID_FORK_ID}; @@ -259,7 +259,7 @@ task_t> typed_rpc_tl_query_result_one_impl(i co_return error_factory.make_error(string{"wrong query_id"}, TL_ERROR_WRONG_QUERY_ID); } - auto &rpc_ctx{RpcComponentContext::get()}; + auto &rpc_ctx{RpcInstanceState::get()}; class_instance rpc_query{}; int64_t response_waiter_fork_id{INVALID_FORK_ID}; @@ -309,57 +309,57 @@ bool f$store_int(int64_t v) noexcept { if (unlikely(is_int32_overflow(v))) { php_warning("Got int32 overflow on storing '%" PRIi64 "', the value will be casted to '%d'", v, static_cast(v)); } - RpcComponentContext::get().rpc_buffer.store_trivial(v); + RpcInstanceState::get().rpc_buffer.store_trivial(v); return true; } bool f$store_long(int64_t v) noexcept { - RpcComponentContext::get().rpc_buffer.store_trivial(v); + RpcInstanceState::get().rpc_buffer.store_trivial(v); return true; } bool f$store_float(double v) noexcept { - RpcComponentContext::get().rpc_buffer.store_trivial(v); + RpcInstanceState::get().rpc_buffer.store_trivial(v); return true; } bool f$store_double(double v) noexcept { - RpcComponentContext::get().rpc_buffer.store_trivial(v); + RpcInstanceState::get().rpc_buffer.store_trivial(v); return true; } bool f$store_string(const string &v) noexcept { - RpcComponentContext::get().rpc_buffer.store_string(std::string_view{v.c_str(), v.size()}); + RpcInstanceState::get().rpc_buffer.store_string(std::string_view{v.c_str(), v.size()}); return true; } // === Rpc Fetch ================================================================================== int64_t f$fetch_int() noexcept { - return static_cast(RpcComponentContext::get().rpc_buffer.fetch_trivial().value_or(0)); + return static_cast(RpcInstanceState::get().rpc_buffer.fetch_trivial().value_or(0)); } int64_t f$fetch_long() noexcept { - return RpcComponentContext::get().rpc_buffer.fetch_trivial().value_or(0); + return RpcInstanceState::get().rpc_buffer.fetch_trivial().value_or(0); } double f$fetch_double() noexcept { - return RpcComponentContext::get().rpc_buffer.fetch_trivial().value_or(0.0); + return RpcInstanceState::get().rpc_buffer.fetch_trivial().value_or(0.0); } double f$fetch_float() noexcept { - return static_cast(RpcComponentContext::get().rpc_buffer.fetch_trivial().value_or(0)); + return static_cast(RpcInstanceState::get().rpc_buffer.fetch_trivial().value_or(0)); } string f$fetch_string() noexcept { - const std::string_view str{RpcComponentContext::get().rpc_buffer.fetch_string()}; + const std::string_view str{RpcInstanceState::get().rpc_buffer.fetch_string()}; return {str.data(), static_cast(str.length())}; } // === Rpc Query ================================================================================== task_t> f$rpc_send_requests(string actor, array tl_objects, double timeout, bool ignore_answer, - class_instance requests_extra_info, bool need_responses_extra_info) noexcept { + class_instance requests_extra_info, bool need_responses_extra_info) noexcept { if (ignore_answer && need_responses_extra_info) { php_warning("Both $ignore_answer and $need_responses_extra_info are 'true'. Can't collect metrics for ignored answers"); } @@ -391,7 +391,7 @@ task_t>> f$rpc_fetch_responses(array query_ids) noex // === Rpc Misc ================================================================================== void f$rpc_clean() noexcept { - RpcComponentContext::get().rpc_buffer.clean(); + RpcInstanceState::get().rpc_buffer.clean(); } // === Misc ======================================================================================= @@ -406,11 +406,11 @@ bool is_int32_overflow(int64_t v) noexcept { void store_raw_vector_double(const array &vector) noexcept { // TODO: didn't we forget vector's length? const std::string_view vector_view{reinterpret_cast(vector.get_const_vector_pointer()), sizeof(double) * vector.count()}; - RpcComponentContext::get().rpc_buffer.store_bytes(vector_view); + RpcInstanceState::get().rpc_buffer.store_bytes(vector_view); } void fetch_raw_vector_double(array &vector, int64_t num_elems) noexcept { - auto &rpc_buf{RpcComponentContext::get().rpc_buffer}; + auto &rpc_buf{RpcInstanceState::get().rpc_buffer}; const auto len_bytes{sizeof(double) * num_elems}; if (rpc_buf.remaining() < len_bytes) { return; // TODO: error handling diff --git a/runtime-light/stdlib/rpc/rpc-api.h b/runtime-light/stdlib/rpc/rpc-api.h index 44e6de255a..6f56b0f31d 100644 --- a/runtime-light/stdlib/rpc/rpc-api.h +++ b/runtime-light/stdlib/rpc/rpc-api.h @@ -59,13 +59,14 @@ string f$fetch_string() noexcept; // === Rpc Query ================================================================================== - task_t> f$rpc_send_requests(string actor, array tl_objects, double timeout = -1.0, bool ignore_answer = false, - class_instance requests_extra_info = {}, bool need_responses_extra_info = false) noexcept; +task_t> f$rpc_send_requests(string actor, array tl_objects, double timeout = -1.0, bool ignore_answer = false, + class_instance requests_extra_info = {}, + bool need_responses_extra_info = false) noexcept; template rpc_function_t, std::same_as rpc_request_t = KphpRpcRequest> task_t> f$rpc_send_typed_query_requests(string actor, array> query_functions, double timeout = -1.0, - bool ignore_answer = false, class_instance requests_extra_info = {}, - bool need_responses_extra_info = false) noexcept { + bool ignore_answer = false, class_instance requests_extra_info = {}, + bool need_responses_extra_info = false) noexcept { if (ignore_answer && need_responses_extra_info) { php_warning("Both $ignore_answer and $need_responses_extra_info are 'true'. Can't collect metrics for ignored answers"); } @@ -110,7 +111,7 @@ array> f$rpc_tl_query_result_synchronously(const array &) { } inline task_t> f$rpc_tl_query(const class_instance &, const array &, double = -1.0, bool = false, - class_instance = {}, bool = false) { + class_instance = {}, bool = false) { php_critical_error("call to unsupported function"); } diff --git a/runtime-light/stdlib/rpc/rpc-context.cpp b/runtime-light/stdlib/rpc/rpc-context.cpp deleted file mode 100644 index 0c73fcd547..0000000000 --- a/runtime-light/stdlib/rpc/rpc-context.cpp +++ /dev/null @@ -1,21 +0,0 @@ -// Compiler for PHP (aka KPHP) -// Copyright (c) 2024 LLC «V Kontakte» -// Distributed under the GPL v3 License, see LICENSE.notice.txt - -#include "runtime-light/stdlib/rpc/rpc-context.h" - -#include "runtime-light/component/component.h" -#include "runtime-light/component/image.h" -#include "runtime-light/utils/context.h" - -RpcComponentContext &RpcComponentContext::get() noexcept { - return get_component_context()->rpc_component_context; -} - -const RpcImageState &RpcImageState::get() noexcept { - return get_image_state()->rpc_image_state; -} - -RpcImageState &RpcImageState::get_mutable() noexcept { - return get_mutable_image_state()->rpc_image_state; -} diff --git a/runtime-light/stdlib/rpc/rpc-extra-info.cpp b/runtime-light/stdlib/rpc/rpc-extra-info.cpp index 70779af0ec..6ea409f2b3 100644 --- a/runtime-light/stdlib/rpc/rpc-extra-info.cpp +++ b/runtime-light/stdlib/rpc/rpc-extra-info.cpp @@ -6,7 +6,7 @@ #include "common/algorithms/hashes.h" #include "common/wrappers/string_view.h" -#include "runtime-light/stdlib/rpc/rpc-context.h" +#include "runtime-light/stdlib/rpc/rpc-state.h" const char *C$KphpRpcRequestsExtraInfo::get_class() const noexcept { return R"(KphpRpcRequestsExtraInfo)"; @@ -21,7 +21,7 @@ array f$KphpRpcRequestsExtraInfo$$get(class_instance f$extract_kphp_rpc_response_extra_info(int64_t query_id) noexcept { - auto &extra_info_map{RpcComponentContext::get().rpc_responses_extra_info}; + auto &extra_info_map{RpcInstanceState::get().rpc_responses_extra_info}; if (const auto it{extra_info_map.find(query_id)}; it != extra_info_map.end() && it->second.first == rpc_response_extra_info_status_t::READY) { const auto extra_info{it->second.second}; extra_info_map.erase(it); diff --git a/runtime-light/stdlib/rpc/rpc-state.cpp b/runtime-light/stdlib/rpc/rpc-state.cpp new file mode 100644 index 0000000000..13ddfec80a --- /dev/null +++ b/runtime-light/stdlib/rpc/rpc-state.cpp @@ -0,0 +1,20 @@ +// Compiler for PHP (aka KPHP) +// Copyright (c) 2024 LLC «V Kontakte» +// Distributed under the GPL v3 License, see LICENSE.notice.txt + +#include "runtime-light/stdlib/rpc/rpc-state.h" + +#include "runtime-light/state/image-state.h" +#include "runtime-light/state/instance-state.h" + +RpcInstanceState &RpcInstanceState::get() noexcept { + return InstanceState::get().rpc_instance_state; +} + +const RpcImageState &RpcImageState::get() noexcept { + return ImageState::get().rpc_image_state; +} + +RpcImageState &RpcImageState::get_mutable() noexcept { + return ImageState::get_mutable().rpc_image_state; +} diff --git a/runtime-light/stdlib/rpc/rpc-context.h b/runtime-light/stdlib/rpc/rpc-state.h similarity index 89% rename from runtime-light/stdlib/rpc/rpc-context.h rename to runtime-light/stdlib/rpc/rpc-state.h index f2dc80b0e7..25c3cbd298 100644 --- a/runtime-light/stdlib/rpc/rpc-context.h +++ b/runtime-light/stdlib/rpc/rpc-state.h @@ -15,7 +15,7 @@ #include "runtime-light/stdlib/rpc/rpc-tl-query.h" #include "runtime-light/tl/tl-core.h" -struct RpcComponentContext final : private vk::not_copyable { +struct RpcInstanceState final : private vk::not_copyable { template using unordered_map = memory_resource::stl::unordered_map; @@ -26,14 +26,14 @@ struct RpcComponentContext final : private vk::not_copyable { unordered_map> response_fetcher_instances; unordered_map> rpc_responses_extra_info; - explicit RpcComponentContext(memory_resource::unsynchronized_pool_resource &memory_resource) noexcept + explicit RpcInstanceState(memory_resource::unsynchronized_pool_resource &memory_resource) noexcept : current_query() , response_waiter_forks(unordered_map::allocator_type{memory_resource}) , response_fetcher_instances(unordered_map>::allocator_type{memory_resource}) , rpc_responses_extra_info( unordered_map>::allocator_type{memory_resource}) {} - static RpcComponentContext &get() noexcept; + static RpcInstanceState &get() noexcept; }; // ================================================================================================ diff --git a/runtime-light/stdlib/rpc/rpc-tl-kphp-request.h b/runtime-light/stdlib/rpc/rpc-tl-kphp-request.h index a87ec61030..deaddb4027 100644 --- a/runtime-light/stdlib/rpc/rpc-tl-kphp-request.h +++ b/runtime-light/stdlib/rpc/rpc-tl-kphp-request.h @@ -7,7 +7,7 @@ #include #include "runtime-light/allocator/allocator.h" -#include "runtime-light/stdlib/rpc/rpc-context.h" +#include "runtime-light/stdlib/rpc/rpc-state.h" #include "runtime-light/stdlib/rpc/rpc-tl-defs.h" #include "runtime-light/stdlib/rpc/rpc-tl-request.h" @@ -40,7 +40,7 @@ class KphpRpcRequest final : public RpcRequest { std::unique_ptr store_request() const final { // php_assert(CurException.is_null()); - auto &rpc_ctx{RpcComponentContext::get()}; + auto &rpc_ctx{RpcInstanceState::get()}; rpc_ctx.current_query.set_current_tl_function(tl_function_name()); std::unique_ptr stored_fetcher = storing_function.get()->store(); rpc_ctx.current_query.reset(); diff --git a/runtime-light/stdlib/rpc/rpc-tl-query.cpp b/runtime-light/stdlib/rpc/rpc-tl-query.cpp index d39204c6ef..577e8acfdd 100644 --- a/runtime-light/stdlib/rpc/rpc-tl-query.cpp +++ b/runtime-light/stdlib/rpc/rpc-tl-query.cpp @@ -7,7 +7,7 @@ #include #include "runtime-common/core/utils/kphp-assert-core.h" -#include "runtime-light/stdlib/rpc/rpc-context.h" +#include "runtime-light/stdlib/rpc/rpc-state.h" void CurrentTlQuery::reset() noexcept { current_tl_function_name = string{}; @@ -81,5 +81,5 @@ const string &CurrentTlQuery::get_current_tl_function_name() const noexcept { } CurrentTlQuery &CurrentTlQuery::get() noexcept { - return RpcComponentContext::get().current_query; + return RpcInstanceState::get().current_query; } diff --git a/runtime-light/stdlib/stdlib.cmake b/runtime-light/stdlib/stdlib.cmake index 31d2714f42..b62d5f49c4 100644 --- a/runtime-light/stdlib/stdlib.cmake +++ b/runtime-light/stdlib/stdlib.cmake @@ -4,23 +4,23 @@ prepend( component/component-api.cpp confdata/confdata-functions.cpp crypto/crypto-functions.cpp - crypto/crypto-context.cpp - curl/curl-context.cpp + crypto/crypto-state.cpp + curl/curl-state.cpp exit/exit-functions.cpp - fork/fork-context.cpp + fork/fork-state.cpp hash/hash-functions.cpp job-worker/job-worker-api.cpp - job-worker/job-worker-client-context.cpp + job-worker/job-worker-client-state.cpp output/output-buffer.cpp output/print-functions.cpp - regex/regex-context.cpp + regex/regex-state.cpp rpc/rpc-api.cpp - rpc/rpc-context.cpp + rpc/rpc-state.cpp rpc/rpc-extra-headers.cpp rpc/rpc-extra-info.cpp rpc/rpc-tl-error.cpp rpc/rpc-tl-query.cpp rpc/rpc-tl-request.cpp - string/string-context.cpp - system/system-context.cpp - file/file-stream-context.cpp) + string/string-state.cpp + system/system-state.cpp + file/file-stream-state.cpp) diff --git a/runtime-light/stdlib/string/string-context.cpp b/runtime-light/stdlib/string/string-context.cpp deleted file mode 100644 index 3c0c48c4b4..0000000000 --- a/runtime-light/stdlib/string/string-context.cpp +++ /dev/null @@ -1,17 +0,0 @@ -// Compiler for PHP (aka KPHP) -// Copyright (c) 2024 LLC «V Kontakte» -// Distributed under the GPL v3 License, see LICENSE.notice.txt - -#include "runtime-light/stdlib/string/string-context.h" - -#include "runtime-light/component/component.h" -#include "runtime-light/component/image.h" -#include "runtime-light/utils/context.h" - -StringComponentContext &StringComponentContext::get() noexcept { - return get_component_context()->string_component_context; -} - -const StringImageState &StringImageState::get() noexcept { - return get_image_state()->string_image_state; -} diff --git a/runtime-light/stdlib/string/string-state.cpp b/runtime-light/stdlib/string/string-state.cpp new file mode 100644 index 0000000000..0e3136a720 --- /dev/null +++ b/runtime-light/stdlib/string/string-state.cpp @@ -0,0 +1,16 @@ +// Compiler for PHP (aka KPHP) +// Copyright (c) 2024 LLC «V Kontakte» +// Distributed under the GPL v3 License, see LICENSE.notice.txt + +#include "runtime-light/stdlib/string/string-state.h" + +#include "runtime-light/state/image-state.h" +#include "runtime-light/state/instance-state.h" + +StringInstanceState &StringInstanceState::get() noexcept { + return InstanceState::get().string_instance_state; +} + +const StringImageState &StringImageState::get() noexcept { + return ImageState::get().string_image_state; +} diff --git a/runtime-light/stdlib/string/string-context.h b/runtime-light/stdlib/string/string-state.h similarity index 83% rename from runtime-light/stdlib/string/string-context.h rename to runtime-light/stdlib/string/string-state.h index 09d462e8fe..3617a9ea23 100644 --- a/runtime-light/stdlib/string/string-context.h +++ b/runtime-light/stdlib/string/string-state.h @@ -6,5 +6,5 @@ #include "runtime-common/stdlib/string/string-context.h" -using StringComponentContext = StringLibContext; +using StringInstanceState = StringLibContext; using StringImageState = StringLibConstants; diff --git a/runtime-light/stdlib/system/system-context.cpp b/runtime-light/stdlib/system/system-context.cpp deleted file mode 100644 index 48e24028b5..0000000000 --- a/runtime-light/stdlib/system/system-context.cpp +++ /dev/null @@ -1,11 +0,0 @@ -// Compiler for PHP (aka KPHP) -// Copyright (c) 2024 LLC «V Kontakte» -// Distributed under the GPL v3 License, see LICENSE.notice.txt - -#include "runtime-light/stdlib/system/system-context.h" - -#include "runtime-light/component/component.h" - -SystemComponentContext &SystemComponentContext::get() noexcept { - return get_component_context()->system_component_context; -} diff --git a/runtime-light/stdlib/system/system-functions.h b/runtime-light/stdlib/system/system-functions.h index b8432ea126..6755fcc073 100644 --- a/runtime-light/stdlib/system/system-functions.h +++ b/runtime-light/stdlib/system/system-functions.h @@ -5,7 +5,7 @@ #pragma once #include "runtime-common/core/utils/kphp-assert-core.h" -#include "runtime-light/stdlib/system/system-context.h" +#include "runtime-light/stdlib/system/system-state.h" template int64_t f$estimate_memory_usage(const T &) { @@ -32,10 +32,11 @@ void f$kphp_extended_instance_cache_metrics_init(F &&callback) { php_critical_error("call to unsupported function"); } -inline int64_t f$system(const string &command, int64_t &result_code = SystemComponentContext::get().result_code_dummy) { +inline int64_t f$system(const string &command, int64_t &result_code = SystemInstanceState::get().result_code_dummy) { php_critical_error("call to unsupported function"); } -inline Optional> f$getopt(const string &options, array longopts = {}, Optional &rest_index = SystemComponentContext::get().rest_index_dummy) { +inline Optional> f$getopt(const string &options, array longopts = {}, + Optional &rest_index = SystemInstanceState::get().rest_index_dummy) { php_critical_error("call to unsupported function"); } diff --git a/runtime-light/stdlib/system/system-state.cpp b/runtime-light/stdlib/system/system-state.cpp new file mode 100644 index 0000000000..155445965f --- /dev/null +++ b/runtime-light/stdlib/system/system-state.cpp @@ -0,0 +1,11 @@ +// Compiler for PHP (aka KPHP) +// Copyright (c) 2024 LLC «V Kontakte» +// Distributed under the GPL v3 License, see LICENSE.notice.txt + +#include "runtime-light/stdlib/system/system-state.h" + +#include "runtime-light/state/instance-state.h" + +SystemInstanceState &SystemInstanceState::get() noexcept { + return InstanceState::get().system_instance_state; +} diff --git a/runtime-light/stdlib/system/system-context.h b/runtime-light/stdlib/system/system-state.h similarity index 72% rename from runtime-light/stdlib/system/system-context.h rename to runtime-light/stdlib/system/system-state.h index 3ea66187a7..7c9e298d19 100644 --- a/runtime-light/stdlib/system/system-context.h +++ b/runtime-light/stdlib/system/system-state.h @@ -8,11 +8,9 @@ #include "runtime-common/core/runtime-core.h" -struct SystemComponentContext final : vk::not_copyable { +struct SystemInstanceState final : private vk::not_copyable { int64_t result_code_dummy{}; Optional rest_index_dummy; - static SystemComponentContext &get() noexcept; + static SystemInstanceState &get() noexcept; }; - - diff --git a/runtime-light/streams/streams.cpp b/runtime-light/streams/streams.cpp index fa8a9c5350..acf1edbf37 100644 --- a/runtime-light/streams/streams.cpp +++ b/runtime-light/streams/streams.cpp @@ -12,91 +12,89 @@ #include "runtime-common/core/utils/kphp-assert-core.h" #include "runtime-light/coroutine/awaitable.h" #include "runtime-light/coroutine/task.h" -#include "runtime-light/header.h" -#include "runtime-light/utils/context.h" +#include "runtime-light/k2-platform/k2-api.h" task_t> read_all_from_stream(uint64_t stream_d) noexcept { - const auto &platform_ctx = *get_platform_context(); constexpr int32_t batch_size = 32; int32_t buffer_capacity = batch_size; - auto *buffer = static_cast(platform_ctx.allocator.alloc(buffer_capacity)); + auto *buffer = static_cast(k2::alloc(buffer_capacity)); int32_t buffer_size = 0; - StreamStatus status{}; + k2::StreamStatus status{}; do { - GetStatusResult res = platform_ctx.get_stream_status(stream_d, std::addressof(status)); - if (res != GetStatusResult::GetStatusOk) { - php_warning("get stream status returned status %d", res); + k2::stream_status(stream_d, std::addressof(status)); + if (status.libc_errno != k2::errno_ok) { + php_warning("get stream status returned status %d", status.libc_errno); co_return std::make_pair(nullptr, 0); } - if (status.read_status == IOStatus::IOAvailable) { + if (status.read_status == k2::IOStatus::IOAvailable) { if (buffer_capacity - buffer_size < batch_size) { - auto *new_buffer = static_cast(platform_ctx.allocator.alloc(static_cast(buffer_capacity) * 2)); + auto *new_buffer = static_cast(k2::alloc(static_cast(buffer_capacity) * 2)); std::memcpy(new_buffer, buffer, buffer_size); - platform_ctx.allocator.free(buffer); + k2::free(buffer); buffer_capacity = buffer_capacity * 2; buffer = new_buffer; } - buffer_size += platform_ctx.read(stream_d, batch_size, buffer + buffer_size); - } else if (status.read_status == IOStatus::IOBlocked) { + buffer_size += k2::read(stream_d, batch_size, buffer + buffer_size); + } else if (status.read_status == k2::IOStatus::IOBlocked) { co_await wait_for_update_t{stream_d}; } - } while (status.read_status != IOStatus::IOClosed); + } while (status.read_status != k2::IOStatus::IOClosed); co_return std::make_pair(buffer, buffer_size); } std::pair read_nonblock_from_stream(uint64_t stream_d) noexcept { - const auto &platform_ctx = *get_platform_context(); constexpr int32_t batch_size = 32; int32_t buffer_capacity = batch_size; - auto *buffer = static_cast(platform_ctx.allocator.alloc(buffer_capacity)); + auto *buffer = static_cast(k2::alloc(buffer_capacity)); int32_t buffer_size = 0; - StreamStatus status{}; + k2::StreamStatus status{}; do { - GetStatusResult res = platform_ctx.get_stream_status(stream_d, std::addressof(status)); - if (res != GetStatusResult::GetStatusOk) { - php_warning("get stream status returned status %d", res); + k2::stream_status(stream_d, std::addressof(status)); + if (status.libc_errno != k2::errno_ok) { + php_warning("get stream status returned status %d", status.libc_errno); return std::make_pair(nullptr, 0); } - if (status.read_status == IOStatus::IOAvailable) { + if (status.read_status == k2::IOStatus::IOAvailable) { if (buffer_capacity - buffer_size < batch_size) { - auto *new_buffer = static_cast(platform_ctx.allocator.alloc(static_cast(buffer_capacity) * 2)); + auto *new_buffer = static_cast(k2::alloc(static_cast(buffer_capacity) * 2)); std::memcpy(new_buffer, buffer, buffer_size); - platform_ctx.allocator.free(buffer); + k2::free(buffer); buffer_capacity = buffer_capacity * 2; buffer = new_buffer; } - buffer_size += platform_ctx.read(stream_d, batch_size, buffer + buffer_size); + buffer_size += k2::read(stream_d, batch_size, buffer + buffer_size); } else { break; } - } while (status.read_status != IOStatus::IOClosed); + } while (status.read_status != k2::IOStatus::IOClosed); return std::make_pair(buffer, buffer_size); } task_t read_exact_from_stream(uint64_t stream_d, char *buffer, int32_t len) noexcept { - const PlatformCtx &platform_ctx = *get_platform_context(); - int32_t read = 0; - StreamStatus status{IOStatus::IOAvailable, IOStatus::IOAvailable, 0}; - while (read != len && status.read_status != IOStatus::IOClosed) { - GetStatusResult res = platform_ctx.get_stream_status(stream_d, std::addressof(status)); - if (res != GetStatusResult::GetStatusOk) { - php_warning("get stream status returned status %d", res); + k2::StreamStatus status{.read_status = k2::IOStatus::IOAvailable, + .write_status = k2::IOStatus::IOAvailable, + .please_shutdown_write = 0, + .libc_errno = k2::errno_ok}; + while (read != len && status.read_status != k2::IOStatus::IOClosed) { + k2::stream_status(stream_d, std::addressof(status)); + if (status.libc_errno != k2::errno_ok) { + php_warning("get stream status returned status %d", status.libc_errno); co_return 0; } - if (status.read_status == IOStatus::IOAvailable) { - read += platform_ctx.read(stream_d, len - read, buffer + read); - } else if (status.read_status == IOStatus::IOBlocked) { + if (status.read_status == k2::IOStatus::IOAvailable) { + read += k2::read(stream_d, len - read, buffer + read); + } else if (status.read_status == k2::IOStatus::IOBlocked) { co_await wait_for_update_t{stream_d}; } else { co_return read; @@ -107,24 +105,22 @@ task_t read_exact_from_stream(uint64_t stream_d, char *buffer, int32_t } task_t write_all_to_stream(uint64_t stream_d, const char *buffer, int32_t len) noexcept { - const auto &platform_ctx = *get_platform_context(); - int32_t written = 0; - StreamStatus status{}; + k2::StreamStatus status{}; do { - GetStatusResult res = platform_ctx.get_stream_status(stream_d, std::addressof(status)); - if (res != GetStatusResult::GetStatusOk) { - php_warning("get stream status returned status %d", res); + k2::stream_status(stream_d, std::addressof(status)); + if (status.libc_errno != k2::errno_ok) { + php_warning("get stream status returned status %d", status.libc_errno); co_return written; } if (status.please_shutdown_write) { php_debug("stream %" PRIu64 " set please_shutdown_write. Stop writing", stream_d); co_return written; - } else if (status.write_status == IOStatus::IOAvailable) { - written += platform_ctx.write(stream_d, len - written, buffer + written); - } else if (status.write_status == IOStatus::IOBlocked) { + } else if (status.write_status == k2::IOStatus::IOAvailable) { + written += k2::write(stream_d, len - written, buffer + written); + } else if (status.write_status == k2::IOStatus::IOBlocked) { co_await wait_for_update_t{stream_d}; } else { php_warning("stream closed while writing. Wrote %d. Size %d. Stream %" PRIu64, written, len, stream_d); @@ -137,20 +133,18 @@ task_t write_all_to_stream(uint64_t stream_d, const char *buffer, int32 } int32_t write_nonblock_to_stream(uint64_t stream_d, const char *buffer, int32_t len) noexcept { - const auto &platform_ctx = *get_platform_context(); - int32_t written = 0; - StreamStatus status{}; + k2::StreamStatus status{}; do { - GetStatusResult res = platform_ctx.get_stream_status(stream_d, std::addressof(status)); - if (res != GetStatusResult::GetStatusOk) { - php_warning("get stream status returned status %d", res); + k2::stream_status(stream_d, std::addressof(status)); + if (status.libc_errno != k2::errno_ok) { + php_warning("get stream status returned status %d", status.libc_errno); return 0; } - if (status.write_status == IOStatus::IOAvailable) { - written += platform_ctx.write(stream_d, len - written, buffer + written); + if (status.write_status == k2::IOStatus::IOAvailable) { + written += k2::write(stream_d, len - written, buffer + written); } else { break; } @@ -161,24 +155,25 @@ int32_t write_nonblock_to_stream(uint64_t stream_d, const char *buffer, int32_t } task_t write_exact_to_stream(uint64_t stream_d, const char *buffer, int32_t len) noexcept { - const auto &platform_ctx = *get_platform_context(); - int written = 0; - StreamStatus status{IOAvailable, IOAvailable, 0}; - while (written != len && status.write_status != IOStatus::IOClosed) { - GetStatusResult res = platform_ctx.get_stream_status(stream_d, std::addressof(status)); - if (res != GetStatusResult::GetStatusOk) { - php_warning("get stream status returned status %d", res); + k2::StreamStatus status{.read_status = k2::IOStatus::IOAvailable, + .write_status = k2::IOStatus::IOAvailable, + .please_shutdown_write = 0, + .libc_errno = k2::errno_ok}; + while (written != len && status.write_status != k2::IOStatus::IOClosed) { + k2::stream_status(stream_d, std::addressof(status)); + if (status.libc_errno != k2::errno_ok) { + php_warning("get stream status returned status %d", status.libc_errno); co_return written; } if (status.please_shutdown_write) { php_debug("stream %" PRIu64 " set please_shutdown_write. Stop writing", stream_d); co_return written; - } else if (status.write_status == IOStatus::IOAvailable) { - written += platform_ctx.write(stream_d, len - written, buffer + written); - } else if (status.write_status == IOStatus::IOBlocked) { + } else if (status.write_status == k2::IOStatus::IOAvailable) { + written += k2::write(stream_d, len - written, buffer + written); + } else if (status.write_status == k2::IOStatus::IOBlocked) { co_await wait_for_update_t{stream_d}; } else { co_return written; diff --git a/runtime-light/tl/tl-builtins.cpp b/runtime-light/tl/tl-builtins.cpp index b12fd1a0ff..16e2a33fee 100644 --- a/runtime-light/tl/tl-builtins.cpp +++ b/runtime-light/tl/tl-builtins.cpp @@ -14,11 +14,11 @@ void register_tl_storers_table_and_fetcher(const array &gen$ht, t } int32_t tl_parse_save_pos() { - return static_cast(RpcComponentContext::get().rpc_buffer.pos()); + return static_cast(RpcInstanceState::get().rpc_buffer.pos()); } bool tl_parse_restore_pos(int32_t pos) { - auto &rpc_buf{RpcComponentContext::get().rpc_buffer}; + auto &rpc_buf{RpcInstanceState::get().rpc_buffer}; if (pos < 0 || pos > rpc_buf.pos()) { return false; } diff --git a/runtime-light/utils/context.cpp b/runtime-light/utils/context.cpp deleted file mode 100644 index bba43de65a..0000000000 --- a/runtime-light/utils/context.cpp +++ /dev/null @@ -1,17 +0,0 @@ -// Compiler for PHP (aka KPHP) -// Copyright (c) 2024 LLC «V Kontakte» -// Distributed under the GPL v3 License, see LICENSE.notice.txt - -#include "runtime-light/utils/context.h" - -thread_local ImageState *mutableImageState; -const thread_local ImageState *imageState; -const thread_local PlatformCtx *platformCtx; -thread_local ComponentState *componentState; - -void reset_thread_locals() { - mutableImageState = nullptr; - imageState = nullptr; - platformCtx = nullptr; - componentState = nullptr; -} \ No newline at end of file diff --git a/runtime-light/utils/context.h b/runtime-light/utils/context.h deleted file mode 100644 index 65b1bad7c6..0000000000 --- a/runtime-light/utils/context.h +++ /dev/null @@ -1,30 +0,0 @@ -// Compiler for PHP (aka KPHP) -// Copyright (c) 2024 LLC «V Kontakte» -// Distributed under the GPL v3 License, see LICENSE.notice.txt - -#pragma once - -#include "runtime-light/header.h" - -extern thread_local ImageState *mutableImageState; -extern const thread_local ImageState *imageState; -extern const thread_local PlatformCtx *platformCtx; -extern thread_local ComponentState *componentState; - -inline const PlatformCtx *get_platform_context() { - return platformCtx; -} - -inline ComponentState *get_component_context() { - return componentState; -} - -inline const ImageState *get_image_state() { - return imageState; -} - -inline ImageState *get_mutable_image_state() { - return mutableImageState; -} - -void reset_thread_locals(); diff --git a/runtime-light/utils/json-functions.cpp b/runtime-light/utils/json-functions.cpp index 5fde8e0723..d736393bd1 100644 --- a/runtime-light/utils/json-functions.cpp +++ b/runtime-light/utils/json-functions.cpp @@ -5,8 +5,6 @@ #include "runtime-light/utils/json-functions.h" #include "common/algorithms/find.h" -#include "runtime-light/component/component.h" -// //#include "runtime/string_functions.h" // note: json-functions.cpp is used for non-typed json implementation: for json_encode() and json_decode() diff --git a/runtime-light/utils/logs.h b/runtime-light/utils/logs.h index fbc9c84561..8d8d360de9 100644 --- a/runtime-light/utils/logs.h +++ b/runtime-light/utils/logs.h @@ -4,10 +4,12 @@ #pragma once -#include "runtime-light/header.h" +#include -#define Error 1 -#define Warn 2 -#define Info 3 -#define Debug 4 -#define Trace 5 +enum class LogLevel : size_t { + Error = 1, + Warn = 2, + Info = 3, + Debug = 4, + Trace = 5, +}; diff --git a/runtime-light/utils/panic.cpp b/runtime-light/utils/panic.cpp index 0416135fc3..8342c1d6b3 100644 --- a/runtime-light/utils/panic.cpp +++ b/runtime-light/utils/panic.cpp @@ -2,22 +2,20 @@ // Copyright (c) 2024 LLC «V Kontakte» // Distributed under the GPL v3 License, see LICENSE.notice.txt -#include +#include +#include #include "runtime-common/core/utils/kphp-assert-core.h" -#include "runtime-light/component/component.h" -#include "runtime-light/header.h" -#include "runtime-light/utils/context.h" +#include "runtime-light/k2-platform/k2-api.h" +#include "runtime-light/state/instance-state.h" #include "runtime-light/utils/logs.h" void critical_error_handler() { - constexpr const char *message = "script panic"; - const auto &platform_ctx = *get_platform_context(); - platform_ctx.log(Debug, strlen(message), message); + constexpr std::string_view message = "script panic"; + k2::log(static_cast>(LogLevel::Debug), message.size(), message.data()); - if (get_component_context() != nullptr) { - get_component_context()->poll_status = PollStatus::PollFinishedError; + if (k2::instance_state() != nullptr) { + InstanceState::get().poll_status = k2::PollStatus::PollFinishedError; } - platform_ctx.abort(); - exit(1); + k2::exit(1); } diff --git a/runtime-light/utils/php_assert.cpp b/runtime-light/utils/php_assert.cpp index 0b236c5f00..fd03200d02 100644 --- a/runtime-light/utils/php_assert.cpp +++ b/runtime-light/utils/php_assert.cpp @@ -1,5 +1,5 @@ // Compiler for PHP (aka KPHP) -// Copyright (c) 2020 LLC «V Kontakte» +// Copyright (c) 2024 LLC «V Kontakte» // Distributed under the GPL v3 License, see LICENSE.notice.txt #include @@ -14,8 +14,7 @@ #include #include "runtime-common/core/utils/kphp-assert-core.h" -#include "runtime-light/header.h" -#include "runtime-light/utils/context.h" +#include "runtime-light/k2-platform/k2-api.h" #include "runtime-light/utils/logs.h" static void php_warning_impl(bool out_of_memory, int error_type, char const *message, va_list args) { @@ -24,8 +23,8 @@ static void php_warning_impl(bool out_of_memory, int error_type, char const *mes char buf[BUF_SIZE]; int size = vsnprintf(buf, BUF_SIZE, message, args); - get_platform_context()->log(error_type, size, buf); - if (error_type == Error) { + k2::log(error_type, size, buf); + if (error_type == static_cast>(LogLevel::Error)) { critical_error_handler(); } } @@ -33,33 +32,33 @@ static void php_warning_impl(bool out_of_memory, int error_type, char const *mes void php_debug(char const *message, ...) { va_list args; va_start(args, message); - php_warning_impl(false, Debug, message, args); + php_warning_impl(false, static_cast>(LogLevel::Debug), message, args); va_end(args); } void php_notice(char const *message, ...) { va_list args; va_start(args, message); - php_warning_impl(false, Info, message, args); + php_warning_impl(false, static_cast>(LogLevel::Info), message, args); va_end(args); } void php_warning(char const *message, ...) { va_list args; va_start(args, message); - php_warning_impl(false, Warn, message, args); + php_warning_impl(false, static_cast>(LogLevel::Warn), message, args); va_end(args); } void php_error(char const *message, ...) { va_list args; va_start(args, message); - php_warning_impl(false, Error, message, args); + php_warning_impl(false, static_cast>(LogLevel::Error), message, args); va_end(args); } void php_assert__(const char *msg, const char *file, int line) { php_error("Assertion \"%s\" failed in file %s on line %d", msg, file, line); critical_error_handler(); - _exit(1); + k2::exit(1); } diff --git a/runtime-light/utils/utils.cmake b/runtime-light/utils/utils.cmake index 3a7e93a054..b8e422732b 100644 --- a/runtime-light/utils/utils.cmake +++ b/runtime-light/utils/utils.cmake @@ -1,2 +1,2 @@ prepend(RUNTIME_LIGHT_UTILS_SRC utils/ panic.cpp php_assert.cpp - json-functions.cpp context.cpp) + json-functions.cpp)