Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions runtime-light/state/image-state.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include "runtime-light/allocator/allocator-state.h"
#include "runtime-light/core/reference-counter/reference-counter-functions.h"
#include "runtime-light/k2-platform/k2-api.h"
#include "runtime-light/stdlib/curl/curl-state.h"
#include "runtime-light/stdlib/diagnostics/logs.h"
#include "runtime-light/stdlib/file/file-system-state.h"
#include "runtime-light/stdlib/math/math-state.h"
Expand Down Expand Up @@ -46,6 +47,7 @@ struct ImageState final : private vk::not_copyable {
TimeImageState time_image_state;
MathImageState math_image_state;
RpcImageState rpc_image_state;
CurlImageState curl_image_state;

ImageState() noexcept {
if (const int64_t sysconf_max_buffer_size{k2::sysconf(_SC_GETPW_R_SIZE_MAX)}; sysconf_max_buffer_size != -1) {
Expand Down
55 changes: 38 additions & 17 deletions runtime-light/stdlib/curl/curl-multi-functions.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ inline auto f$curl_multi_add_handle(kphp::web::curl::multi_type multi_id, kphp::

auto res{co_await kphp::forks::id_managed(kphp::web::composite_transfer_add(kphp::web::composite_transfer{multi_id}, kphp::web::simple_transfer{easy_id}))};
if (!res.has_value()) [[unlikely]] {
multi_ctx.set_errno(res.error().code, res.error().description);
multi_ctx.set_errno(res.error().code);
kphp::web::curl::print_error("could not add a curl easy handler into multi handle", std::move(res.error()));
co_return multi_ctx.error_code;
}
Expand All @@ -67,7 +67,7 @@ inline auto f$curl_multi_remove_handle(kphp::web::curl::multi_type multi_id,
auto res{
co_await kphp::forks::id_managed(kphp::web::composite_transfer_remove(kphp::web::composite_transfer{multi_id}, kphp::web::simple_transfer{easy_id}))};
if (!res.has_value()) [[unlikely]] {
multi_ctx.set_errno(res.error().code, res.error().description);
multi_ctx.set_errno(res.error().code);
kphp::web::curl::print_error("could not remove a curl easy handler from multi handle", std::move(res.error()));
co_return multi_ctx.error_code;
}
Expand Down Expand Up @@ -100,7 +100,7 @@ inline auto f$curl_multi_setopt(kphp::web::curl::multi_type multi_id, int64_t op
return true;
}
default:
multi_ctx.set_errno(kphp::web::curl::CURLME::UNKNOWN_OPTION, "a libcurl function was given an incorrect PROXYTYPE kind");
multi_ctx.set_errno(kphp::web::curl::CURLME::UNKNOWN_OPTION);
return false;
}
}
Expand Down Expand Up @@ -130,7 +130,7 @@ inline auto f$curl_multi_exec(kphp::web::curl::multi_type multi_id, int64_t& sti
auto res{co_await kphp::forks::id_managed(kphp::web::composite_transfer_perform(kphp::web::composite_transfer{multi_id}))};
auto& multi_ctx{curl_state.multi_ctx.get_or_init(multi_id)};
if (!res.has_value()) [[unlikely]] {
multi_ctx.set_errno(res.error().code, res.error().description);
multi_ctx.set_errno(res.error().code);
kphp::web::curl::print_error("could not execute curl multi handle", std::move(res.error()));
co_return multi_ctx.error_code;
}
Expand All @@ -148,7 +148,7 @@ inline auto f$curl_multi_getcontent(kphp::web::curl::easy_type easy_id) noexcept
if (easy_ctx.return_transfer) {
auto res{co_await kphp::forks::id_managed(kphp::web::simple_transfer_get_response(kphp::web::simple_transfer{easy_id}))};
if (!res.has_value()) [[unlikely]] {
easy_ctx.set_errno(res.error().code, res.error().description);
easy_ctx.set_errno(res.error().code);
kphp::web::curl::print_error("could not get response of curl easy handle", std::move(res.error()));
co_return false;
}
Expand All @@ -165,26 +165,47 @@ inline auto f$curl_multi_close(kphp::web::curl::multi_type multi_id) noexcept ->
auto& multi_ctx{curl_state.multi_ctx.get_or_init(multi_id)};
auto res{co_await kphp::forks::id_managed(kphp::web::composite_transfer_close(kphp::web::composite_transfer{multi_id}))};
if (!res.has_value()) [[unlikely]] {
multi_ctx.set_errno(res.error().code, res.error().description);
multi_ctx.set_errno(res.error().code);
kphp::web::curl::print_error("could not close curl multi handle", std::move(res.error()));
co_return;
}
multi_ctx.set_errno(kphp::web::curl::CURLE::OK);
co_return;
}

inline auto f$curl_multi_strerror(kphp::web::curl::multi_type multi_id) noexcept -> Optional<string> {
auto& curl_state{CurlInstanceState::get()};
if (!curl_state.multi_ctx.has(multi_id)) [[unlikely]] {
inline auto f$curl_multi_strerror(int64_t error_num) noexcept -> Optional<string> {
switch (static_cast<kphp::web::curl::CURLME>(error_num)) {
case kphp::web::curl::CURLME::CALL_MULTI_PERFORM:
return CurlImageState::get().CURLME_CALL_MULTI_PERFORM;
case kphp::web::curl::CURLME::OK:
return CurlImageState::get().CURLME_OK;
case kphp::web::curl::CURLME::BAD_HANDLE:
return CurlImageState::get().CURLME_BAD_HANDLE;
case kphp::web::curl::CURLME::BAD_EASY_HANDLE:
return CurlImageState::get().CURLME_BAD_EASY_HANDLE;
case kphp::web::curl::CURLME::OUT_OF_MEMORY:
return CurlImageState::get().CURLME_OUT_OF_MEMORY;
case kphp::web::curl::CURLME::INTERNAL_ERROR:
return CurlImageState::get().CURLME_INTERNAL_ERROR;
case kphp::web::curl::CURLME::BAD_SOCKET:
return CurlImageState::get().CURLME_BAD_SOCKET;
case kphp::web::curl::CURLME::UNKNOWN_OPTION:
return CurlImageState::get().CURLME_UNKNOWN_OPTION;
case kphp::web::curl::CURLME::ADDED_ALREADY:
return CurlImageState::get().CURLME_ADDED_ALREADY;
case kphp::web::curl::CURLME::RECURSIVE_API_CALL:
return CurlImageState::get().CURLME_RECURSIVE_API_CALL;
case kphp::web::curl::CURLME::WAKEUP_FAILURE:
return CurlImageState::get().CURLME_WAKEUP_FAILURE;
case kphp::web::curl::CURLME::BAD_FUNCTION_ARGUMENT:
return CurlImageState::get().CURLME_BAD_FUNCTION_ARGUMENT;
case kphp::web::curl::CURLME::ABORTED_BY_CALLBACK:
return CurlImageState::get().CURLME_ABORTED_BY_CALLBACK;
case kphp::web::curl::CURLME::UNRECOVERABLE_POLL:
return CurlImageState::get().CURLME_UNRECOVERABLE_POLL;
default:
return {};
}
auto& multi_ctx{curl_state.multi_ctx.get_or_init(multi_id)};
if (multi_ctx.error_code != static_cast<int64_t>(kphp::web::curl::CURLME::OK)) [[likely]] {
const auto* const desc_data{reinterpret_cast<const char*>(multi_ctx.error_description.data())};
const auto desc_size{static_cast<string::size_type>(multi_ctx.error_description.size())};
return string{desc_data, desc_size};
}
return {};
}

inline auto f$curl_multi_errno(kphp::web::curl::multi_type multi_id) noexcept -> Optional<int64_t> {
Expand All @@ -205,7 +226,7 @@ inline auto f$curl_multi_select(kphp::web::curl::multi_type multi_id, double tim
auto res{co_await kphp::forks::id_managed(kphp::web::composite_transfer_wait_updates(
kphp::web::composite_transfer{multi_id}, std::chrono::duration_cast<std::chrono::seconds>(std::chrono::duration<double>{timeout})))};
if (!res.has_value()) [[unlikely]] {
multi_ctx.set_errno(res.error().code, res.error().description);
multi_ctx.set_errno(res.error().code);
kphp::web::curl::print_error("could not select curl multi handle", std::move(res.error()));
co_return multi_ctx.error_code;
}
Expand Down
5 changes: 5 additions & 0 deletions runtime-light/stdlib/curl/curl-state.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,13 @@

#include "runtime-light/stdlib/curl/curl-state.h"

#include "runtime-light/state/image-state.h"
#include "runtime-light/state/instance-state.h"

CurlInstanceState& CurlInstanceState::get() noexcept {
return InstanceState::get().curl_instance_state;
}

const CurlImageState& CurlImageState::get() noexcept {
return ImageState::get().curl_image_state;
}
53 changes: 53 additions & 0 deletions runtime-light/stdlib/curl/curl-state.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@
#include "common/mixin/not_copyable.h"
#include "runtime-common/core/allocator/script-allocator.h"
#include "runtime-common/core/std/containers.h"
#include "runtime-light/core/reference-counter/reference-counter-functions.h"
#include "runtime-light/stdlib/curl/curl-context.h"
#include "runtime-light/stdlib/curl/defs.h"
#include "runtime-light/stdlib/diagnostics/logs.h"

struct CurlInstanceState final : private vk::not_copyable {
public:
Expand Down Expand Up @@ -58,3 +60,54 @@ inline auto CurlInstanceState::multi_ctx::get_or_init(kphp::web::curl::multi_typ
inline auto CurlInstanceState::multi_ctx::has(kphp::web::curl::multi_type multi_id) noexcept -> bool {
return ctx.find(multi_id) != ctx.end();
}

struct CurlImageState final : private vk::not_copyable {
string CURLME_CALL_MULTI_PERFORM{kphp::web::curl::details::CURLME_CALL_MULTI_PERFORM.data(), kphp::web::curl::details::CURLME_CALL_MULTI_PERFORM.size()};
string CURLME_OK{kphp::web::curl::details::CURLME_OK.data(), kphp::web::curl::details::CURLME_OK.size()};
string CURLME_BAD_HANDLE{kphp::web::curl::details::CURLME_BAD_HANDLE.data(), kphp::web::curl::details::CURLME_BAD_HANDLE.size()};
string CURLME_BAD_EASY_HANDLE{kphp::web::curl::details::CURLME_BAD_EASY_HANDLE.data(), kphp::web::curl::details::CURLME_BAD_EASY_HANDLE.size()};
string CURLME_OUT_OF_MEMORY{kphp::web::curl::details::CURLME_OUT_OF_MEMORY.data(), kphp::web::curl::details::CURLME_OUT_OF_MEMORY.size()};
string CURLME_INTERNAL_ERROR{kphp::web::curl::details::CURLME_INTERNAL_ERROR.data(), kphp::web::curl::details::CURLME_INTERNAL_ERROR.size()};
string CURLME_BAD_SOCKET{kphp::web::curl::details::CURLME_BAD_SOCKET.data(), kphp::web::curl::details::CURLME_BAD_SOCKET.size()};
string CURLME_UNKNOWN_OPTION{kphp::web::curl::details::CURLME_UNKNOWN_OPTION.data(), kphp::web::curl::details::CURLME_UNKNOWN_OPTION.size()};
string CURLME_ADDED_ALREADY{kphp::web::curl::details::CURLME_ADDED_ALREADY.data(), kphp::web::curl::details::CURLME_ADDED_ALREADY.size()};
string CURLME_RECURSIVE_API_CALL{kphp::web::curl::details::CURLME_RECURSIVE_API_CALL.data(), kphp::web::curl::details::CURLME_RECURSIVE_API_CALL.size()};
string CURLME_WAKEUP_FAILURE{kphp::web::curl::details::CURLME_WAKEUP_FAILURE.data(), kphp::web::curl::details::CURLME_WAKEUP_FAILURE.size()};
string CURLME_BAD_FUNCTION_ARGUMENT{kphp::web::curl::details::CURLME_BAD_FUNCTION_ARGUMENT.data(),
kphp::web::curl::details::CURLME_BAD_FUNCTION_ARGUMENT.size()};
string CURLME_ABORTED_BY_CALLBACK{kphp::web::curl::details::CURLME_ABORTED_BY_CALLBACK.data(), kphp::web::curl::details::CURLME_ABORTED_BY_CALLBACK.size()};
string CURLME_UNRECOVERABLE_POLL{kphp::web::curl::details::CURLME_UNRECOVERABLE_POLL.data(), kphp::web::curl::details::CURLME_UNRECOVERABLE_POLL.size()};

CurlImageState() noexcept {
kphp::log::assertion((kphp::core::set_reference_counter_recursive(CURLME_CALL_MULTI_PERFORM, ExtraRefCnt::for_global_const),
kphp::core::is_reference_counter_recursive(CURLME_CALL_MULTI_PERFORM, ExtraRefCnt::for_global_const)));
kphp::log::assertion((kphp::core::set_reference_counter_recursive(CURLME_OK, ExtraRefCnt::for_global_const),
kphp::core::is_reference_counter_recursive(CURLME_OK, ExtraRefCnt::for_global_const)));
kphp::log::assertion((kphp::core::set_reference_counter_recursive(CURLME_BAD_HANDLE, ExtraRefCnt::for_global_const),
kphp::core::is_reference_counter_recursive(CURLME_BAD_HANDLE, ExtraRefCnt::for_global_const)));
kphp::log::assertion((kphp::core::set_reference_counter_recursive(CURLME_BAD_EASY_HANDLE, ExtraRefCnt::for_global_const),
kphp::core::is_reference_counter_recursive(CURLME_BAD_EASY_HANDLE, ExtraRefCnt::for_global_const)));
kphp::log::assertion((kphp::core::set_reference_counter_recursive(CURLME_OUT_OF_MEMORY, ExtraRefCnt::for_global_const),
kphp::core::is_reference_counter_recursive(CURLME_OUT_OF_MEMORY, ExtraRefCnt::for_global_const)));
kphp::log::assertion((kphp::core::set_reference_counter_recursive(CURLME_INTERNAL_ERROR, ExtraRefCnt::for_global_const),
kphp::core::is_reference_counter_recursive(CURLME_INTERNAL_ERROR, ExtraRefCnt::for_global_const)));
kphp::log::assertion((kphp::core::set_reference_counter_recursive(CURLME_BAD_SOCKET, ExtraRefCnt::for_global_const),
kphp::core::is_reference_counter_recursive(CURLME_BAD_SOCKET, ExtraRefCnt::for_global_const)));
kphp::log::assertion((kphp::core::set_reference_counter_recursive(CURLME_UNKNOWN_OPTION, ExtraRefCnt::for_global_const),
kphp::core::is_reference_counter_recursive(CURLME_UNKNOWN_OPTION, ExtraRefCnt::for_global_const)));
kphp::log::assertion((kphp::core::set_reference_counter_recursive(CURLME_ADDED_ALREADY, ExtraRefCnt::for_global_const),
kphp::core::is_reference_counter_recursive(CURLME_ADDED_ALREADY, ExtraRefCnt::for_global_const)));
kphp::log::assertion((kphp::core::set_reference_counter_recursive(CURLME_RECURSIVE_API_CALL, ExtraRefCnt::for_global_const),
kphp::core::is_reference_counter_recursive(CURLME_RECURSIVE_API_CALL, ExtraRefCnt::for_global_const)));
kphp::log::assertion((kphp::core::set_reference_counter_recursive(CURLME_WAKEUP_FAILURE, ExtraRefCnt::for_global_const),
kphp::core::is_reference_counter_recursive(CURLME_WAKEUP_FAILURE, ExtraRefCnt::for_global_const)));
kphp::log::assertion((kphp::core::set_reference_counter_recursive(CURLME_BAD_FUNCTION_ARGUMENT, ExtraRefCnt::for_global_const),
kphp::core::is_reference_counter_recursive(CURLME_BAD_FUNCTION_ARGUMENT, ExtraRefCnt::for_global_const)));
kphp::log::assertion((kphp::core::set_reference_counter_recursive(CURLME_ABORTED_BY_CALLBACK, ExtraRefCnt::for_global_const),
kphp::core::is_reference_counter_recursive(CURLME_ABORTED_BY_CALLBACK, ExtraRefCnt::for_global_const)));
kphp::log::assertion((kphp::core::set_reference_counter_recursive(CURLME_UNRECOVERABLE_POLL, ExtraRefCnt::for_global_const),
kphp::core::is_reference_counter_recursive(CURLME_UNRECOVERABLE_POLL, ExtraRefCnt::for_global_const)));
}

static const CurlImageState& get() noexcept;
};
25 changes: 25 additions & 0 deletions runtime-light/stdlib/curl/defs.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#pragma once

#include <cstdint>
#include <string_view>

#include "runtime-light/stdlib/web-transfer-lib/defs.h"

Expand Down Expand Up @@ -259,6 +260,11 @@ enum class CURLME : int16_t {
BAD_SOCKET = 5,
UNKNOWN_OPTION = 6,
ADDED_ALREADY = 7,
RECURSIVE_API_CALL = 8,
WAKEUP_FAILURE = 9,
BAD_FUNCTION_ARGUMENT = 10,
ABORTED_BY_CALLBACK = 11,
UNRECOVERABLE_POLL = 12,
};

enum class CURMLOPT : uint64_t {
Expand All @@ -278,3 +284,22 @@ enum class CURLPIPE : uint8_t {
};

} // namespace kphp::web::curl

namespace kphp::web::curl::details {

inline constexpr std::string_view CURLME_CALL_MULTI_PERFORM{"Please call curl_multi_perform() soon"};
inline constexpr std::string_view CURLME_OK{"No error"};
inline constexpr std::string_view CURLME_BAD_HANDLE{"Invalid multi handle"};
inline constexpr std::string_view CURLME_BAD_EASY_HANDLE{"Invalid easy handle"};
inline constexpr std::string_view CURLME_OUT_OF_MEMORY{"Out of memory"};
inline constexpr std::string_view CURLME_INTERNAL_ERROR{"Internal error"};
inline constexpr std::string_view CURLME_BAD_SOCKET{"Invalid socket argument"};
inline constexpr std::string_view CURLME_UNKNOWN_OPTION{"Unknown option"};
inline constexpr std::string_view CURLME_ADDED_ALREADY{"The easy handle is already added to a multi handle"};
inline constexpr std::string_view CURLME_RECURSIVE_API_CALL{"API function called from within callback"};
inline constexpr std::string_view CURLME_WAKEUP_FAILURE{"Wakeup is unavailable or failed"};
inline constexpr std::string_view CURLME_BAD_FUNCTION_ARGUMENT{"A libcurl function was given a bad argument"};
inline constexpr std::string_view CURLME_ABORTED_BY_CALLBACK{"Operation was aborted by an application callback"};
inline constexpr std::string_view CURLME_UNRECOVERABLE_POLL{"Unrecoverable error in select/poll"};

} // namespace kphp::web::curl::details
4 changes: 3 additions & 1 deletion tests/phpt/curl/11_curl_multi_error.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@

function test_no_error() {
$mh = curl_multi_init();
var_dump(curl_multi_errno($mh));
$errno = curl_multi_errno($mh);
var_dump($errno);
var_dump(curl_multi_strerror($errno));
curl_multi_close($mh);
}

Expand Down
Loading