Skip to content

Commit

Permalink
Remove runMode setting
Browse files Browse the repository at this point in the history
  • Loading branch information
dermesser committed Oct 8, 2024
1 parent 814e763 commit c34692b
Show file tree
Hide file tree
Showing 7 changed files with 12 additions and 56 deletions.
9 changes: 3 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,9 @@ Supported functionality:
Promises (backed by coroutines) are run eagerly; you don't have to schedule or await them for the
underlying coroutine to run.

Where I/O or other activity causes a coroutine to be resumed, the coroutine will typically be run by
the scheduler, which you don't need to care about. Depending on the `RunMode`, pending coroutines
are either run once per event loop turn, or immediately from the libuv callback (`Immediate`). By
default, they are run all at once in every event loop turn (`Deferred`). While you can set the run
mode for I/O events in `uvco::runMain()` (`Deferred` vs. `Immediate`), the externally visible
behavior should be the same, and code will work in both modes. If it doesn't: that's a bug in uvco.
Where I/O or other activity causes a coroutine to be resumed, the coroutine
will typically be run by the scheduler, which you don't need to care about.
Pending coroutines are resumed once per event loop turn.

Some types - like buffers filled by sockets - use simple types like strings, which are easy to
handle but not super efficient. This may need to be generalized.
Expand Down
9 changes: 1 addition & 8 deletions test/test_util.cc
Original file line number Diff line number Diff line change
@@ -1,19 +1,12 @@

#include <uv.h>

#include "uvco/loop/scheduler.h"
#include "uvco/promise/promise.h"
#include "uvco/run.h"

#include <functional>

namespace {

constexpr uvco::Scheduler::RunMode runMode = uvco::Scheduler::RunMode::Deferred;

} // namespace

void run_loop(
const std::function<uvco::Promise<void>(const uvco::Loop &)> &setup) {
uvco::runMain<void>(setup, runMode);
uvco::runMain<void>(setup);
}
4 changes: 2 additions & 2 deletions uvco/loop/loop.cc
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@

namespace uvco {

Loop::Loop(Scheduler::RunMode mode)
Loop::Loop()
: loop_{std::make_unique<uv_loop_t>()},
scheduler_{std::make_unique<Scheduler>(mode)} {
scheduler_{std::make_unique<Scheduler>()} {

if (defaultLoop != nullptr) {
throw UvcoException(UV_EBUSY,
Expand Down
3 changes: 1 addition & 2 deletions uvco/loop/loop.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,7 @@ namespace uvco {
class Loop {
public:
// Don't use this constructor. Use `runMain()` instead.
explicit Loop(Scheduler::RunMode mode = Scheduler::RunMode::Deferred);

Loop();
Loop(const Loop &) = delete;
Loop(Loop &&) = delete;
Loop &operator=(const Loop &) = delete;
Expand Down
10 changes: 1 addition & 9 deletions uvco/loop/scheduler.cc
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
// uvco (c) 2023 Lewin Bormann. See LICENSE for specific terms.

#include <array>
#include <fmt/core.h>
#include <uv.h>

#include "uvco/loop/scheduler.h"

#include <algorithm>
#include <coroutine>
#include <cstddef>
#include <span>

namespace uvco {
Expand Down Expand Up @@ -60,20 +58,14 @@ void Scheduler::close() { BOOST_ASSERT(resumableActive_.empty()); }
void Scheduler::enqueue(std::coroutine_handle<> handle) {
// Use of moved-out Scheduler?
BOOST_ASSERT(resumableActive_.capacity() > 0);

if (run_mode_ == RunMode::Immediate) {
handle.resume();
return;
}

resumableActive_.push_back(handle);
}

void Scheduler::setUpLoop(uv_loop_t *loop) { uv_loop_set_data(loop, this); }

Scheduler::~Scheduler() = default;

Scheduler::Scheduler(RunMode mode) : run_mode_{mode} {
Scheduler::Scheduler() {
resumableActive_.reserve(16);
resumableRunning_.reserve(16);
}
Expand Down
24 changes: 1 addition & 23 deletions uvco/loop/scheduler.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

#pragma once

#include <array>
#include <boost/assert.hpp>
#include <uv.h>

Expand Down Expand Up @@ -42,26 +41,7 @@ namespace uvco {
/// of coroutines), thus it is not introduced everywhere yet.
class Scheduler {
public:
enum class RunMode {
/// Run an enqueued coroutine immediately, in the stack of the
/// enqueuing function.
Immediate = 0,
/// Run all enqueued coroutines sequentially, after all I/O has been
/// completed, before the next I/O poll.
Deferred = 1,
};

/// Construct a scheduler.
///
/// If `immediate_resume` is true, resumed coroutines will be run
/// immediately in the call stack of the resuming function. Otherwise
/// the coroutine will be resumed upon the next turn of the event loop,
/// i.e. after all activity has finished and before the next I/O poll,
/// by call to `runAll()`.
///
/// Call `setUpLoop()` to attach the scheduler to a libuv event loop.
explicit Scheduler(RunMode mode = RunMode::Deferred);

Scheduler();
Scheduler(const Scheduler &) = delete;
Scheduler(Scheduler &&) = delete;
Scheduler &operator=(const Scheduler &) = delete;
Expand Down Expand Up @@ -93,8 +73,6 @@ class Scheduler {
std::vector<std::coroutine_handle<>> resumableActive_;
// Vector of coroutines currently being resumed (while in runAll()).
std::vector<std::coroutine_handle<>> resumableRunning_;

RunMode run_mode_;
};

} // namespace uvco
9 changes: 3 additions & 6 deletions uvco/run.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
#pragma once

#include "uvco/loop/loop.h"
#include "uvco/loop/scheduler.h"
#include "uvco/promise/multipromise.h"
#include "uvco/promise/promise.h"

Expand All @@ -24,8 +23,7 @@ MultiPromise<unsigned> yield(unsigned count);
template <typename F, typename R>
concept MainFunction = std::is_invocable_r_v<Promise<R>, F, const Loop &>;

template <typename R, MainFunction<R> F>
R runMain(F main, Scheduler::RunMode mode = Scheduler::RunMode::Deferred);
template <typename R, MainFunction<R> F> R runMain(F main);

/// Set up event loop, then run main function to set up promises.
/// Finally, clean up once the event loop has finished. An exception
Expand All @@ -47,9 +45,8 @@ R runMain(F main, Scheduler::RunMode mode = Scheduler::RunMode::Deferred);
/// });
/// ```
///
template <typename R, MainFunction<R> F>
R runMain(F main, Scheduler::RunMode mode) {
Loop loop{mode};
template <typename R, MainFunction<R> F> R runMain(F main) {
Loop loop;
Promise<R> promise = main(loop);
runLoop(loop);
return promise.unwrap();
Expand Down

0 comments on commit c34692b

Please sign in to comment.