Quick Start
Add Dependency
First, choose your build system. ilias supports both xmake and cmake.
TIP
Xmake is the primary build system, maintained more frequently, and is recommended for priority use.
Using xmake
lua
add_repositories("btk-repo https://github.com/Btk-Project/xmake-repo.git")
add_requires("ilias")
target("your_app")
add_packages("ilias")Using cmake
cmake
include(FetchContent)
FetchContent_Declare(
ilias
GIT_REPOSITORY https://github.com/BusyStudent/Ilias.git
GIT_TAG main
)
FetchContent_MakeAvailable(ilias)
add_executable(my_app main.cpp)
target_link_libraries(my_app PRIVATE ilias::ilias)Write Your First Program
Let's start with a very simple example.
cpp
#include <ilias/platform.hpp>
#include <ilias/task.hpp>
auto task() -> ilias::Task<int> {
co_return 0;
}
auto main(int argc, char **argv) -> int {
ilias::PlatformContext ctxt {}; // Create an executor for scheduling
ctxt.install(); // Then install it into thread_local storage
return task().wait(); // Create the task and block until it completes
}This uses two major modules:
task: Provides the main stackless coroutine APIs, includingTask,Generator,TaskGroup,spawn, etc.platform: Provides platform-specific executor APIs, includingIocpContext,EpollContext,UringContext.PlatformContextis an alias.
platform also provides a helper macro to simplify writing the main function.
cpp
void ilias_main() {
co_return;
}Write an Asynchronous Network Program
The program above doesn't do anything and seems a bit boring. Let's add something to it.
cpp
#include <ilias/platform.hpp>
#include <ilias/task.hpp>
#include <ilias/net.hpp>
// Note: All functions that can fail return Result<T, E> (std::expected<T, E>)
// In this example, we lazily unwrap it directly using .value()
using namespace std::literals;
auto handle(ilias::TcpStream stream) -> ilias::Task<void> {
auto content = ilias::makeBuffer("hello world\n"sv);
(co_await stream.writeAll(content)).value();
(co_await stream.flush()).value();
}
void ilias_main() {
// First, create a listener
auto listener = (co_await ilias::TcpListener::bind("127.0.0.1:8080")).value();
while (true) {
auto [stream, endpoint] = (co_await listener.accept()).value();
// Create a child task to handle the connection. For better management, you can use TaskScope.
ilias::spawn(handle(std::move(stream)));
}
}We find that letting the program run in an infinite loop like this is a bit annoying. Let's add an exit signal to it.
cpp
#include <ilias/platform.hpp>
#include <ilias/signal.hpp>
#include <ilias/task.hpp>
#include <ilias/net.hpp>
#include <print>
// Same as the code above
auto handle(ilias::TcpStream stream) -> ilias::Task<void>;
auto accept(ilias::IPEndpoint endpoint) -> ilias::Task<void>;
void ilias_main() {
auto [_, ctrlc] = co_await ilias::whenAny(
accept("127.0.0.1:8080"),
ilias::signal::ctrlC(),
);
if (ctrlc) {
std::println("Server is shutting down...");
}
}