Skip to content

Commit

Permalink
Add config class.
Browse files Browse the repository at this point in the history
  • Loading branch information
chriskohlhoff committed Oct 29, 2024
1 parent 387aa3b commit 89c1936
Show file tree
Hide file tree
Showing 24 changed files with 341 additions and 65 deletions.
3 changes: 3 additions & 0 deletions asio/include/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ nobase_include_HEADERS = \
asio/completion_condition.hpp \
asio/compose.hpp \
asio/composed.hpp \
asio/config.hpp \
asio/connect.hpp \
asio/connect_pipe.hpp \
asio/consign.hpp \
Expand Down Expand Up @@ -426,6 +427,8 @@ nobase_include_HEADERS = \
asio/impl/cancel_at.hpp \
asio/impl/cancellation_signal.ipp \
asio/impl/co_spawn.hpp \
asio/impl/config.hpp \
asio/impl/config.ipp \
asio/impl/connect.hpp \
asio/impl/connect_pipe.hpp \
asio/impl/connect_pipe.ipp \
Expand Down
1 change: 1 addition & 0 deletions asio/include/asio.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@
#include "asio/completion_condition.hpp"
#include "asio/compose.hpp"
#include "asio/composed.hpp"
#include "asio/config.hpp"
#include "asio/connect.hpp"
#include "asio/connect_pipe.hpp"
#include "asio/consign.hpp"
Expand Down
104 changes: 104 additions & 0 deletions asio/include/asio/config.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
//
// config.hpp
// ~~~~~~~~~~
//
// Copyright (c) 2003-2024 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//

#ifndef ASIO_CONFIG_HPP
#define ASIO_CONFIG_HPP

#if defined(_MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)

#include "asio/detail/config.hpp"
#include "asio/detail/throw_exception.hpp"
#include "asio/detail/type_traits.hpp"
#include "asio/execution_context.hpp"
#include <cstddef>

#include "asio/detail/push_options.hpp"

namespace asio {

/// Base class for configuration implementations.
class config_service : public execution_context::service
{
public:
typedef config_service key_type;

/// Constructor.
ASIO_DECL explicit config_service(execution_context& ctx);

/// Shutdown the service.
ASIO_DECL void shutdown() override;

/// Retrieve a configuration value.
virtual const char* get_value(const char* section, const char* key,
char* value, std::size_t value_len) const;
};

/// Provides access to the configuration values associated with an execution
/// context.
class config
{
public:
/// Constructor.
/**
* This constructor initialises a @c config object to retrieve configuration
* values associated with the specified execution context.
*/
explicit config(execution_context& context)
: service_(use_service<config_service>(context))
{
}

/// Copy constructor.
config(const config& other) noexcept
: service_(other.service_)
{
}

/// Retrieve an integral configuration value.
template <typename T>
constraint_t<is_integral<T>::value, T>
get(const char* section, const char* key, T default_value) const;

private:
config_service& service_;
};

/// Configures an execution context based on a concurrency hint.
class config_from_concurrency_hint : public execution_context::service_maker
{
public:
/// Construct with a default concurrency hint.
config_from_concurrency_hint();

/// Construct with a specified concurrency hint.
explicit config_from_concurrency_hint(int concurrency_hint)
: concurrency_hint_(concurrency_hint)
{
}

/// Add a concrete service to the specified execution context.
ASIO_DECL void make(execution_context& ctx) const override;

private:
int concurrency_hint_;
};

} // namespace asio

#include "asio/detail/pop_options.hpp"

#include "asio/impl/config.hpp"
#if defined(ASIO_HEADER_ONLY)
# include "asio/impl/config.ipp"
#endif // defined(ASIO_HEADER_ONLY)

#endif // ASIO_CONFIG_HPP
3 changes: 3 additions & 0 deletions asio/include/asio/detail/epoll_reactor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,9 @@ class epoll_reactor
// Whether the service has been shut down.
bool shutdown_;

// Whether I/O locking is enabled.
bool io_locking_;

// Mutex to protect access to the registered descriptors.
mutex registered_descriptors_mutex_;

Expand Down
8 changes: 4 additions & 4 deletions asio/include/asio/detail/impl/epoll_reactor.ipp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

#include <cstddef>
#include <sys/epoll.h>
#include "asio/config.hpp"
#include "asio/detail/epoll_reactor.hpp"
#include "asio/detail/scheduler.hpp"
#include "asio/detail/throw_error.hpp"
Expand All @@ -38,12 +39,12 @@ namespace detail {
epoll_reactor::epoll_reactor(asio::execution_context& ctx)
: execution_context_service_base<epoll_reactor>(ctx),
scheduler_(use_service<scheduler>(ctx)),
mutex_(ASIO_CONCURRENCY_HINT_IS_LOCKING(
REACTOR_REGISTRATION, scheduler_.concurrency_hint())),
mutex_(config(ctx).get("reactor", "registration_locking", true)),
interrupter_(),
epoll_fd_(do_epoll_create()),
timer_fd_(do_timerfd_create()),
shutdown_(false),
io_locking_(config(ctx).get("reactor", "io_locking", true)),
registered_descriptors_mutex_(mutex_.enabled())
{
// Add the interrupter's descriptor to epoll.
Expand Down Expand Up @@ -663,8 +664,7 @@ int epoll_reactor::do_timerfd_create()
epoll_reactor::descriptor_state* epoll_reactor::allocate_descriptor_state()
{
mutex::scoped_lock descriptors_lock(registered_descriptors_mutex_);
return registered_descriptors_.alloc(ASIO_CONCURRENCY_HINT_IS_LOCKING(
REACTOR_IO, scheduler_.concurrency_hint()));
return registered_descriptors_.alloc(io_locking_);
}

void epoll_reactor::free_descriptor_state(epoll_reactor::descriptor_state* s)
Expand Down
8 changes: 3 additions & 5 deletions asio/include/asio/detail/impl/io_uring_service.ipp
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,13 @@ namespace detail {
io_uring_service::io_uring_service(asio::execution_context& ctx)
: execution_context_service_base<io_uring_service>(ctx),
scheduler_(use_service<scheduler>(ctx)),
mutex_(ASIO_CONCURRENCY_HINT_IS_LOCKING(
REACTOR_REGISTRATION, scheduler_.concurrency_hint())),
mutex_(config(ctx).get("reactor", "registration_locking", true)),
outstanding_work_(0),
submit_sqes_op_(this),
pending_sqes_(0),
pending_submit_sqes_op_(false),
shutdown_(false),
io_locking_(config(ctx).get("reactor", "io_locking", true)),
timeout_(),
registration_mutex_(mutex_.enabled()),
reactor_(use_service<reactor>(ctx)),
Expand Down Expand Up @@ -612,9 +612,7 @@ void io_uring_service::register_with_reactor()
io_uring_service::io_object* io_uring_service::allocate_io_object()
{
mutex::scoped_lock registration_lock(registration_mutex_);
return registered_io_objects_.alloc(
ASIO_CONCURRENCY_HINT_IS_LOCKING(
REACTOR_IO, scheduler_.concurrency_hint()));
return registered_io_objects_.alloc(io_locking_);
}

void io_uring_service::free_io_object(io_uring_service::io_object* io_obj)
Expand Down
8 changes: 4 additions & 4 deletions asio/include/asio/detail/impl/kqueue_reactor.ipp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

#if defined(ASIO_HAS_KQUEUE)

#include "asio/config.hpp"
#include "asio/detail/kqueue_reactor.hpp"
#include "asio/detail/scheduler.hpp"
#include "asio/detail/throw_error.hpp"
Expand All @@ -46,11 +47,11 @@ namespace detail {
kqueue_reactor::kqueue_reactor(asio::execution_context& ctx)
: execution_context_service_base<kqueue_reactor>(ctx),
scheduler_(use_service<scheduler>(ctx)),
mutex_(ASIO_CONCURRENCY_HINT_IS_LOCKING(
REACTOR_REGISTRATION, scheduler_.concurrency_hint())),
mutex_(config(ctx).get("reactor", "registration_locking", true)),
kqueue_fd_(do_kqueue_create()),
interrupter_(),
shutdown_(false),
io_locking_(config(ctx).get("reactor", "io_locking", true)),
registered_descriptors_mutex_(mutex_.enabled())
{
struct kevent events[1];
Expand Down Expand Up @@ -562,8 +563,7 @@ int kqueue_reactor::do_kqueue_create()
kqueue_reactor::descriptor_state* kqueue_reactor::allocate_descriptor_state()
{
mutex::scoped_lock descriptors_lock(registered_descriptors_mutex_);
return registered_descriptors_.alloc(ASIO_CONCURRENCY_HINT_IS_LOCKING(
REACTOR_IO, scheduler_.concurrency_hint()));
return registered_descriptors_.alloc(io_locking_);
}

void kqueue_reactor::free_descriptor_state(kqueue_reactor::descriptor_state* s)
Expand Down
9 changes: 5 additions & 4 deletions asio/include/asio/detail/impl/resolver_service_base.ipp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)

#include "asio/detail/config.hpp"
#include "asio/config.hpp"
#include "asio/detail/resolver_service_base.hpp"

#include "asio/detail/push_options.hpp"
Expand Down Expand Up @@ -43,8 +44,9 @@ private:

resolver_service_base::resolver_service_base(execution_context& context)
: scheduler_(asio::use_service<scheduler_impl>(context)),
work_scheduler_(new scheduler_impl(context, -1, false)),
work_thread_(0)
work_scheduler_(new scheduler_impl(context, false)),
work_thread_(0),
scheduler_locking_(config(context).get("scheduler", "locking", true))
{
work_scheduler_->work_started();
}
Expand Down Expand Up @@ -126,8 +128,7 @@ void resolver_service_base::cancel(

void resolver_service_base::start_resolve_op(resolve_op* op)
{
if (ASIO_CONCURRENCY_HINT_IS_LOCKING(SCHEDULER,
scheduler_.concurrency_hint()))
if (scheduler_locking_)
{
start_work_thread();
scheduler_.work_started();
Expand Down
15 changes: 5 additions & 10 deletions asio/include/asio/detail/impl/scheduler.ipp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@

#include "asio/detail/config.hpp"

#include "asio/detail/concurrency_hint.hpp"
#include "asio/detail/config.hpp"
#include "asio/detail/event.hpp"
#include "asio/detail/limits.hpp"
#include "asio/detail/scheduler.hpp"
Expand Down Expand Up @@ -109,22 +109,17 @@ struct scheduler::work_cleanup
};

scheduler::scheduler(asio::execution_context& ctx,
int concurrency_hint, bool own_thread, get_task_func_type get_task)
bool own_thread, get_task_func_type get_task)
: asio::detail::execution_context_service_base<scheduler>(ctx),
one_thread_(concurrency_hint == 1
|| !ASIO_CONCURRENCY_HINT_IS_LOCKING(
SCHEDULER, concurrency_hint)
|| !ASIO_CONCURRENCY_HINT_IS_LOCKING(
REACTOR_IO, concurrency_hint)),
mutex_(ASIO_CONCURRENCY_HINT_IS_LOCKING(
SCHEDULER, concurrency_hint)),
one_thread_(config(ctx).get("scheduler", "concurrency_hint", 0) == 1),
mutex_(config(ctx).get("scheduler", "locking", true)),
task_(0),
get_task_(get_task),
task_interrupted_(true),
outstanding_work_(0),
stopped_(false),
shutdown_(false),
concurrency_hint_(concurrency_hint),
concurrency_hint_(config(ctx).get("scheduler", "concurrency_hint", 0)),
thread_(0)
{
ASIO_HANDLER_TRACKING_INIT;
Expand Down
7 changes: 3 additions & 4 deletions asio/include/asio/detail/impl/signal_set_service.ipp
Original file line number Diff line number Diff line change
Expand Up @@ -658,10 +658,9 @@ void signal_set_service::add_service(signal_set_service* service)
// scheduler used to create signal_set objects.
if (state->service_list_ != 0)
{
if (!ASIO_CONCURRENCY_HINT_IS_LOCKING(SCHEDULER,
service->scheduler_.concurrency_hint())
|| !ASIO_CONCURRENCY_HINT_IS_LOCKING(SCHEDULER,
state->service_list_->scheduler_.concurrency_hint()))
if (!config(service->context()).get("scheduler", "locking", true)
|| !config(state->service_list_->context()).get(
"scheduler", "locking", true))
{
std::logic_error ex(
"Thread-unsafe execution context objects require "
Expand Down
5 changes: 3 additions & 2 deletions asio/include/asio/detail/impl/win_iocp_io_context.ipp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

#if defined(ASIO_HAS_IOCP)

#include "asio/config.hpp"
#include "asio/error.hpp"
#include "asio/detail/cstdint.hpp"
#include "asio/detail/handler_alloc_helpers.hpp"
Expand Down Expand Up @@ -78,7 +79,7 @@ struct win_iocp_io_context::timer_thread_function
};

win_iocp_io_context::win_iocp_io_context(
asio::execution_context& ctx, int concurrency_hint, bool own_thread)
asio::execution_context& ctx, bool own_thread)
: execution_context_service_base<win_iocp_io_context>(ctx),
iocp_(),
outstanding_work_(0),
Expand All @@ -87,7 +88,7 @@ win_iocp_io_context::win_iocp_io_context(
shutdown_(0),
gqcs_timeout_(get_gqcs_timeout()),
dispatch_required_(0),
concurrency_hint_(concurrency_hint)
concurrency_hint_(config(ctx).get("scheduler", "concurrency_hint", -1))
{
ASIO_HANDLER_TRACKING_INIT;

Expand Down
3 changes: 3 additions & 0 deletions asio/include/asio/detail/io_uring_service.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,9 @@ class io_uring_service
// Whether the service has been shut down.
bool shutdown_;

// Whether I/O locking is enabled.
bool io_locking_;

// The timer queues.
timer_queue_set timer_queues_;

Expand Down
3 changes: 3 additions & 0 deletions asio/include/asio/detail/kqueue_reactor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,9 @@ class kqueue_reactor
// Whether the service has been shut down.
bool shutdown_;

// Whether I/O locking is enabled.
bool io_locking_;

// Mutex to protect access to the registered descriptors.
mutex registered_descriptors_mutex_;

Expand Down
1 change: 0 additions & 1 deletion asio/include/asio/detail/resolver_service.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@

#include "asio/ip/basic_resolver_query.hpp"
#include "asio/ip/basic_resolver_results.hpp"
#include "asio/detail/concurrency_hint.hpp"
#include "asio/detail/memory.hpp"
#include "asio/detail/resolve_endpoint_op.hpp"
#include "asio/detail/resolve_query_op.hpp"
Expand Down
3 changes: 3 additions & 0 deletions asio/include/asio/detail/resolver_service_base.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,9 @@ class resolver_service_base

// Thread used for running the work io_context's run loop.
asio::detail::scoped_ptr<asio::detail::thread> work_thread_;

// Whether the scheduler locking is enabled.
bool scheduler_locking_;
};

} // namespace detail
Expand Down
Loading

0 comments on commit 89c1936

Please sign in to comment.