Skip to content

Commit

Permalink
add callback getter. add examples. bug fix.
Browse files Browse the repository at this point in the history
  • Loading branch information
levalup committed Jul 2, 2024
1 parent c522d9d commit caccddb
Show file tree
Hide file tree
Showing 26 changed files with 428 additions and 36 deletions.
26 changes: 25 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,30 @@

--------------------------------

## v0.1.3

> Since: 2024-07-02
### New features

- Add `callback` method on handles.
- Use `callback` method to directly obtain callback for such as `async`, `check` or `timer`.
- Use `listen_callback` method to obtain the callback for stream's `listen`.
- You can set up handling functions independently before performing any work.
- This can be very useful when operations may involve multiple starts and stops.
- Add examples.

## Bug fix

- Fix the variable usage error in the `lib_t::open(string)` method.

## Break changes

- Change return value of `signal_t::start_oneshot`.
- `callback<int>` -> `promise<int>`

--------------------------------

## v0.1.2

> Date: 2024-07-01
Expand All @@ -25,7 +49,7 @@

--------------------------------

## v0.1.2
## v0.1.1

> Date: 2024-06-28
Expand Down
61 changes: 57 additions & 4 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
cmake_minimum_required(VERSION 3.9)
project(libuvcxx)

# -------------------------------------------------------------------------------
# Options
# -------------------------------------------------------------------------------

# default using std=c++17 as libuvcxx has compatibility to C++11
set(STD "17" CACHE STRING "Set CMAKE_CXX_STANDARD")

Expand All @@ -9,7 +13,10 @@ option(WERROR "If treat all warning as error" OFF)

set(EXECUTABLE_OUTPUT_PATH "${PROJECT_SOURCE_DIR}/bin")

# -------------------------------------------------------------------------------
# Load libuv from submodule or system
# -------------------------------------------------------------------------------

if (EXISTS "${PROJECT_SOURCE_DIR}/libuv/CMakeLists.txt")
# compile static libuv
option(LIBUV_BUILD_SHARED "" OFF)
Expand Down Expand Up @@ -50,8 +57,9 @@ else ()
message(STATUS "Using system libuv")
endif ()

include_directories("${PROJECT_SOURCE_DIR}/include")
file(GLOB_RECURSE HEADERS "${PROJECT_SOURCE_DIR}/include/*.h")
# -------------------------------------------------------------------------------
# Message configuration items
# -------------------------------------------------------------------------------

if (STD)
message(STATUS "Using --std=c++${STD}")
Expand All @@ -66,9 +74,54 @@ if (WERROR)
message(STATUS "Enabled -Werror")
endif ()

# build examples
# -------------------------------------------------------------------------------
# Collect header files
# -------------------------------------------------------------------------------

include_directories("${PROJECT_SOURCE_DIR}/include")
file(GLOB_RECURSE HEADERS "${PROJECT_SOURCE_DIR}/include/uvcxx/*.h")

# -------------------------------------------------------------------------------
# Generate single header
# -------------------------------------------------------------------------------

find_package(Python 3 COMPONENTS Interpreter)

set(ENTRY_HEADER "${PROJECT_SOURCE_DIR}/include/uvcxx.h")
set(SINGLE_HEADER "${PROJECT_SOURCE_DIR}/include/uvcxx-single.h")

if (Python_FOUND)
if ("${Python_VERSION_MAJOR}" GREATER 3
OR ("${Python_VERSION_MAJOR}" EQUAL 3 AND "${Python_VERSION_MINOR}" GREATER_EQUAL 6))
message(STATUS "Generating the Single-Header")
# Use python3 generate single header
add_custom_command(OUTPUT "${SINGLE_HEADER}"
COMMAND ${Python_EXECUTABLE} "${PROJECT_SOURCE_DIR}/scripts/merge.py"
DEPENDS ${HEADERS}
COMMENT "python3 scripts/merge.py"
PRE_BUILD # generate single header before any thing
VERBATIM
)
set_source_files_properties("${SINGLE_HEADER}" PROPERTIES GENERATED TRUE)
add_custom_target(single-header DEPENDS "${SINGLE_HEADER}")
else ()
message(WARNING "Requires Python 3.6 but only Python ${Python_VERSION} was found.")
endif ()
else ()
message(WARNING "Since the Python is not found, the test case for Single-Header will not be generated.")
endif ()

list(APPEND HEADERS "${ENTRY_HEADER}")

# -------------------------------------------------------------------------------
# Build examples
# -------------------------------------------------------------------------------

add_subdirectory(examples)

# add tests
# -------------------------------------------------------------------------------
# Add tests
# -------------------------------------------------------------------------------

enable_testing()
add_subdirectory(tests)
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ The `handle` can continue to work without any external references, so that expli

See [lifecycle.md](docs/lifecycle.md) for more details.

**Be careful** not to capture the handle itself by value in the lambda of the callback function, unless you are very clear about the lifecycle of the handle.

## 2. Compatibility

`libuvcxx` requires at least `C++11` and is also compatible with the new features in `C++14` and `C++17`.
Expand Down
16 changes: 15 additions & 1 deletion examples/async.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,22 @@
// L.eval: Let programmer get rid of only work jobs.
//

#include <iostream>

#include "uvcxx/async.h"

int main() {
return 0;
uv::loop_t loop;

uv::async_t async;
async.init(loop).call([]() {
std::cout << "async call" << std::endl;

throw uvcxx::close_handle(); //< close handle after once call
});

async.send();
std::cout << "async send" << std::endl;

return loop.run();
}
38 changes: 38 additions & 0 deletions examples/barrier.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
//
// Created by Levalup.
// L.eval: Let programmer get rid of only work jobs.
//

#include <iostream>
#include <chrono>

#include "uvcxx/barrier.h"
#include "uvcxx/thread.h"
#include "uvcxx/utilities.h"

int main() {
uv::barrier_t barrier(2);
auto beg = std::chrono::steady_clock::now();

uv::thread_t thread1([&barrier, beg]() {
std::cout << uvcxx::catstr("thread-1 wait ", 0, "ms\n") << std::flush;
barrier.wait();
auto end = std::chrono::steady_clock::now();
auto spent = std::chrono::duration_cast<std::chrono::milliseconds>(end - beg).count();
std::cout << uvcxx::catstr("thread-1 exit after ", spent, "ms\n") << std::flush;
});

uv::thread_t thread2([&barrier, beg]() {
std::cout << uvcxx::catstr("thread-2 wait ", 100, "ms\n") << std::flush;
uv::sleep(100);
barrier.wait();
auto end = std::chrono::steady_clock::now();
auto spent = std::chrono::duration_cast<std::chrono::milliseconds>(end - beg).count();
std::cout << uvcxx::catstr("thread-2 exit after ", spent, "ms\n") << std::flush;
});

thread1.join();
thread2.join();

return 0;
}
56 changes: 48 additions & 8 deletions examples/fs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,33 +4,73 @@
//

#include "uvcxx/fs.h"
#include "uvcxx/buf.h"
#include "uvcxx/cxx/to_string.h"

int main() {
std::cout << "----" << std::endl;
std::string content = "!!!!404!!!!";

uv::fs::open("a.txt", O_CREAT | O_WRONLY, 0777).then([&](int fd) {
// create a.txt and write content into it.
uv::fs::open("a.txt", UV_FS_O_CREAT | UV_FS_O_WRONLY, 0777).then([&](int fd) {
std::cout << "open fd = " << fd << std::endl;
uv::fs::write(fd, "!!!!404!!!!", 0).then([fd](ssize_t) {
uv::fs::write(fd, content, 0).then([](ssize_t size) {
std::cout << "write size " << size << std::endl;
}).finally([fd]() {
// close file in finally, whether write succeed or not.
(void) uv::fs::close(fd);
});
// throw uvcxx::exception(UV_EAGAIN);
// throw std::logic_error("throw logic after close");
}).except<uvcxx::errcode>([](const uvcxx::errcode &e) {
std::cerr << "errcode = " << e.code() << std::endl;
}).except<std::exception>([](const std::exception &e) {
std::cerr << e.what() << std::endl;
exit(-1);
});

uv::default_loop().run();

// read a.txt content
uv::fs::open("a.txt", UV_FS_O_RDONLY).then([&](int fd) {
uv::buf_t buf(1024);
uv::fs::read(fd, buf, 0).then([buf](ssize_t size) {
std::cout << "read size " << size << std::endl;
std::cout << "read content: " << std::string(buf.data(), size) << std::endl;
}).finally([fd]() {
// close file in finally, whether write succeed or not.
(void) uv::fs::close(fd);
});
});

uv::default_loop().run();

{
// call sync version mkdir
uv::fs_t tmp;
uv::fs::mkdir(nullptr, tmp, "tmp", 0755, nullptr);
}

uv::fs::mkdtemp(std::string("tmp") + "/tfolder.XXXXXX").then([](const char *path) {
// make temp folder
uv::fs::mkdtemp(std::string("tmp") + "/folder.XXXXXX").then([](const char *path) {
std::cout << "mkdtemp " << path << std::endl;
uv::fs_t tmp;
uv::fs::rmdir(nullptr, tmp, path, nullptr);
});

// readdir
uv::fs::opendir("tmp").then([](uv_dir_t *dir) {
uv::fs::readdir(dir, 1024).then([](uv_dirent_t *file, size_t size) {
for (decltype(size) i = 0; i < size; ++i) {
std::cout << "<" << uvcxx::to_string(file[i].type) << "> " << file[i].name << std::endl;
}
}).finally([dir]() {
(void) uv::fs::closedir(dir);
});
});

// scandir
uv::fs::scandir("tmp", 0).then([](const uv::fs::scan_next &next) {
uv_dirent_t file{};
while (next(&file) >= 0) {
std::cout << "<" << uvcxx::to_string(file.type) << "> " << file.name << std::endl;
}
});

return uv::default_loop().run();
}
8 changes: 7 additions & 1 deletion examples/fs_event.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,25 @@ int main() {

{ std::ofstream touch(target); }

// setup event watch callback
uv::fs_event_t fs_event;
fs_event.start(target, UV_FS_EVENT_RECURSIVE).call([](const char *filename, uv_fs_event events) {
std::cout << filename << " " << uvcxx::to_string(events) << std::endl;
});

// change file after 1 second
uv::timer_t().start(1 * 1000, 1).call([&]() {
std::ofstream touch(target);
throw uvcxx::close_handle();
});

// close fs_event
uv::timer_t().start(2 * 1000, 1).call([&]() {
fs_event.close(nullptr);
throw uvcxx::close_handle();
});
// 2 seconds to close

// wait about 2 seconds before run finished
uv::default_loop().run();
return 0;
}
5 changes: 2 additions & 3 deletions examples/getaddrinfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

#include "uvcxx/getaddrinfo.h"
#include "uvcxx/getnameinfo.h"
#include "uvcxx/utilities.h"

int main() {
addrinfo hints = {};
Expand All @@ -16,10 +17,8 @@ int main() {
uv::getaddrinfo(
"baidu.com", nullptr, &hints
).then([](addrinfo *ai) {
char addr[INET6_ADDRSTRLEN];
for (addrinfo *info = ai; info != nullptr; info = info->ai_next) {
uv_ip4_name((struct sockaddr_in *) info->ai_addr, addr, sizeof(addr));
std::cout << "Found address: " << addr << std::endl;
std::cout << "Found address: " << uv::ip4_name((struct sockaddr_in *) info->ai_addr) << std::endl;
uv::getnameinfo(info->ai_addr, 0).then([](const char *hostname, const char *service) {
std::cout << "Name: " << hostname << " " << service << std::endl;
});
Expand Down
Loading

0 comments on commit caccddb

Please sign in to comment.