Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

change UserDataDeleter type from function ptr to std::function #2431

Merged
merged 4 commits into from
Jan 23, 2024

Conversation

coyorkdow
Copy link
Contributor

@coyorkdow coyorkdow commented Oct 28, 2023

What problem does this PR solve?

Issue Number:

#2430

Problem Summary:

IOBuf is brpc's buffer type, which is designed to be compatible with many forms of the underlying data. For example, the append_user_data can append a piece of user data into an IOBuf without making any copy.

But this interface still has a limitation. Because it accepts deleter of type void(*)(void*) only, so that the deleter is unable to save any state or context.

Assume that the user uses a custom memory resource, such as c++17's pmr or some implementations of arena. User requests a large chunk of memory at once, then allocates the memory block monotonically from this chunk. It won't releases any memory unless the chunk is exhausted and all the allocated blocks are marked as "deleted". The usage std::pmr::monotonic_buffer_resource could have such behaviour.

However, currently since the deleter cannot carry state or context. It's impossible to perceive whether such a memory resource can be released. Because we cannot notify the owner of the resource that the last reference on that memory resource has been freed and the memory can now be released.

IOBuf是brpc通用的buffer类型,它被设计为可以兼容多种可能的底层数据形式。比如append_user_data接口可以将用户的一段数据拼接到IOBuf中而不产生任何拷贝。

但是这个接口仍然存在局限性。因为它接受的delete仅为void(void*)类型,这导致deleter无法保存任何状态或者上下文。

设想用户使用了一种自定义的内存资源,比如c++17的pmr或者自己实现的arena。用户一次性申请了大块内存,然后将该内存块线性分配给不同的请求,当内存块耗尽且所有分配出去的内存都被标记为释放时时再一次性释放。std::pmr::monotonic_buffer_resource的使用就可能存在这样的行为。

然而由于deleter无法携带状态或者上下文,因此程序无法感知到何时内存资源可以被释放。因为我们无法在deleter中通知资源的持有者,最后一个在该内存资源上的引用已经被释放,现在可以回收内存了。

What is changed and the side effects?

Changed:

UserDataDeleter 的类型替换为std::function.

Side effects:

  • Performance effects(性能影响):
    std::function可以本地存储函数指针(small object optimization,取决于编译器,但是较新版本的gcc和clang都有实现)。对于已经存在的使用函数指针的代码的性能影响几乎可以忽略不计。overhead只存在于影响了编译器内联。
  • Breaking backward compatibility(向后兼容性):
    不破坏任何已有功能。

Check List:

  • Please make sure your changes are compilable(请确保你的更改可以通过编译). checked
  • When providing us with a new feature, it is best to add related tests(如果你向我们增加一个新的功能, 请添加相关测试). checked
  • Please follow Contributor Covenant Code of Conduct.(请遵循贡献者准则).

@wwbmmm
Copy link
Contributor

wwbmmm commented Oct 30, 2023

LGTM

@coyorkdow
Copy link
Contributor Author

@wwbmmm can this PR be merged? Thank you.

@wwbmmm wwbmmm merged commit a3280c6 into apache:master Jan 23, 2024
18 checks passed
jiangdongzi pushed a commit to jiangdongzi/brpc that referenced this pull request Jan 31, 2024
…e#2431)

* change UserDataDeleter type from function ptr to std::function

* add unittest

* check that no copy happen when append the stateful user data

* check the destruction is performed correctly
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants