-
Notifications
You must be signed in to change notification settings - Fork 715
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
[WASI]: Unify the write and the read function. #2643
base: master
Are you sure you want to change the base?
Conversation
Hello, I am a code review bot on flows.network. Here are my reviews of code commits in this PR. Overall, the GitHub Pull Request is aimed at unifying the read and write functions in the WASI module, extending compatibility beyond Linux to MacOS and Windows systems. This is done mainly through introducing a 'process' function that takes care of read and write operations on file descriptors, expanding the 'inode-linux.cpp' code to handle this function, and refactoring 'pollOneoff' in the 'WasiFunc.cpp' file to alter how it handles read and write events. The most eminent issues in the pull request are tied to error handling, code duplication, performance, and testing. Firstly, there are a variety of points where exceptions might be thrown leading to potential bugs and security risks, which the current error handling is not equipped to deal with robustly. The use of epoll_ctl is particularly troubling, as errors are assumed to be rare and aren't handled in a robust manner. This, coupled with the lack of unit tests to confirm the reliability and correctness of new features, results in serious concerns over future stability. Secondly, there is an issue with code duplication, as the 'process' function in 'inode-macos.cpp' and 'inode-win.cpp' contain identical patterns which could instead be refactored into a helper function. Lastly, the current patch could lead to performance issues. There are potential inefficiencies linked to the use of an unordered_map dependent on the File Descriptor in the loop within the Therefore, while the pull request proposes useful functional unifications, the absence of robust error handling, adequate testing, efficient coding and performance considerations may invite future bugs and bottlenecks. DetailsCommit fb00f8bf4724824d613ed2e7d91befafb93afa46The proposed GitHub patch attempts to unify the write and read functions in the WASI module of the application. First, it introduces the 'process' using function to manage the read/write processes throughout the 'include/host/wasi/environ.h', 'include/host/wasi/inode.h', and 'include/host/wasi/vinode.h' files. Major changes include:
However, there could be potential problems with this patch. One major concern is the error handling and exception safety. The newly-added code contains several potential points where an exception may be thrown ( Also, the patch doesn't provide test cases for the new functionality. It's risky to integrate new changes without having proper tests constructed to ensure that everything works as expected. Lastly, some code may cause performance issues due to the loop in the In summary, while the patch attempts to unify the write and read functions, without robust error handling, exception safety, performance assessment, and test cases, it may introduce future bugs and potential performance bottlenecks. Commit 58e643ac6009adb5eef742ad6788f00f1f001852Summary: The pull request aims to unify the "read" and "write" functions in the WebAssembly System Interface (WASI) for different operating systems like MacOS and Windows. The developer removed some of the Linux-specific preprocessor directives in "inode.h" and "inode-linux.cpp" files and added generic function process() . The functionality for checking if both the read and write flags are set, previously available only for Linux, is now implemented for MacOS and Windows as well. Potential Issues:
|
Codecov Report
@@ Coverage Diff @@
## master #2643 +/- ##
==========================================
- Coverage 81.20% 80.84% -0.37%
==========================================
Files 148 148
Lines 21473 21614 +141
Branches 4313 4369 +56
==========================================
+ Hits 17437 17473 +36
- Misses 2877 2975 +98
- Partials 1159 1166 +7
... and 2 files with indirect coverage changes 📣 We’re building smart automated test selection to slash your CI/CD build times. Learn more |
Signed-off-by: Tricster <mediosrity@gmail.com>
Signed-off-by: Tricster <mediosrity@gmail.com>
Hi @MediosZ Case 1. If it's new, just apply |
I feels like it's hard to cover all the cases with these two functions. Let's say we have registered That's why I was think of unify these two functions as that's how epoll works. |
@@ -758,6 +759,35 @@ class VPoller : protected Poller { | |||
Poller::write(Fd->Node, Trigger, UserData); | |||
} | |||
} | |||
|
|||
void process(std::shared_ptr<VINode> Fd [[maybe_unused]], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we need so many [[maybe_unused]]
attributes here?
bool ReadFlag [[maybe_unused]], bool WriteFlag [[maybe_unused]], | ||
__wasi_userdata_t ReadUserData [[maybe_unused]], | ||
__wasi_userdata_t WriteUserData [[maybe_unused]]) noexcept { | ||
auto TempReadFlag = ReadFlag; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Temp
is so confusing. Please use a precise name.
|
||
epoll_event EPollEvent; | ||
EPollEvent.events = EPOLLIN; | ||
EPollEvent.events |= EPOLLOUT; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not:
EPollEvent.events = EPOLLIN | EPOLLOUT;
return; | ||
} | ||
} else { | ||
// |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Redundant comments.
WriteEvent.error = __WASI_ERRNO_NOMEM; | ||
return; | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Redundant empty line.
} | ||
} else { | ||
if ((ReadFlag && OldIter->second.ReadEvent == nullptr) || | ||
(WriteFlag && OldIter->second.WriteEvent == nullptr)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please simplify the statement in the current condition (ReadFlag = false && WriteFlag = true
).
auto Iter = SubInfoMap.find(WasiFd); | ||
const bool NotFound = Iter == SubInfoMap.end(); | ||
if (NotFound) { | ||
SubInfo Info = {.ReadFlag = true, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't use this pattern. It's not in the C++17 standard. It's c99 standard, and will be shipped in C++20 (ref: https://www.cppstories.com/2021/designated-init-cpp20/)
Iter->second.ReadData = WasiUserData; | ||
} | ||
} | ||
// Poller.read(WasiFd, Trigger, WasiUserData); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why comment this out?
auto Iter = SubInfoMap.find(WasiFd); | ||
const bool NotFound = Iter == SubInfoMap.end(); | ||
if (NotFound) { | ||
SubInfo Info = {.ReadFlag = false, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ditto.
Iter->second.WriteData = WasiUserData; | ||
} | ||
} | ||
// Poller.write(WasiFd, Trigger, WasiUserData); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ditto.
This PR trys to unify the read and write function to address the issue when using epoll.
The current implementation causes epoll being triggered endlessly.