-
Notifications
You must be signed in to change notification settings - Fork 5.3k
IoHandle readv and writev #6037
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
Changes from all commits
5ef14db
ac33143
91d8724
c1cdc6a
db7f0b8
1013570
f67a6d5
64d846c
e7d9dd0
dae1a6c
a2598b9
f4ca5b7
4093649
90700d6
a398154
774dc4c
cb062a9
aa79e43
d4fa86d
6306999
66580ae
d6bf143
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -9,16 +9,6 @@ | |
| namespace Envoy { | ||
| namespace Api { | ||
|
|
||
| class IoError; | ||
|
|
||
| // IoErrorCode::Again is used frequently. Define it to be a distinguishable address to avoid | ||
| // frequent memory allocation of IoError instance. | ||
| // If this is used, IoCallResult has to be instantiated with a deleter that does not | ||
| // deallocate memory for this error. | ||
| // TODO: This is probably not the best way to avoid allocations in the case of | ||
| // EAGAIN. This will be fixed as a part of #6037. | ||
| #define ENVOY_ERROR_AGAIN reinterpret_cast<Api::IoError*>(0x01) | ||
|
|
||
| /** | ||
| * Base class for any I/O error. | ||
| */ | ||
|
|
@@ -35,32 +25,13 @@ class IoError { | |
| InProgress, | ||
| // Permission denied. | ||
| Permission, | ||
| // Bad handle | ||
| BadHandle, | ||
| // Other error codes cannot be mapped to any one above in getErrorCode(). | ||
| UnknownError | ||
| }; | ||
| virtual ~IoError() {} | ||
|
|
||
| // Map platform specific error into IoErrorCode. | ||
| // Needed to hide errorCode() in case of ENVOY_ERROR_AGAIN. | ||
| static IoErrorCode getErrorCode(const IoError& err) { | ||
| if (&err == ENVOY_ERROR_AGAIN) { | ||
| return IoErrorCode::Again; | ||
| } | ||
| return err.errorCode(); | ||
| } | ||
|
|
||
| static std::string getErrorDetails(const IoError& err) { | ||
| if (&err == ENVOY_ERROR_AGAIN) { | ||
| return "Try again later"; | ||
| } | ||
| return err.errorDetails(); | ||
| } | ||
|
|
||
| protected: | ||
| virtual IoErrorCode errorCode() const PURE; | ||
| virtual std::string errorDetails() const PURE; | ||
| virtual IoErrorCode getErrorCode() const PURE; | ||
| virtual std::string getErrorDetails() const PURE; | ||
| }; | ||
|
|
||
| using IoErrorDeleterType = void (*)(IoError*); | ||
|
|
@@ -69,19 +40,39 @@ using IoErrorPtr = std::unique_ptr<IoError, IoErrorDeleterType>; | |
| /** | ||
| * Basic type for return result which has a return code and error code defined | ||
| * according to different implementations. | ||
| * If the call succeeds, ok() should return true and |rc_| is valid. Otherwise |err_| | ||
| * can be passed into IoError::getErrorCode() to extract the error. In this | ||
| * case, |rc_| is invalid. | ||
| */ | ||
| template <typename T> struct IoCallResult { | ||
| IoCallResult(T rc, IoErrorPtr err) : rc_(rc), err_(std::move(err)) {} | ||
| template <typename ReturnValue> struct IoCallResult { | ||
| IoCallResult(ReturnValue rc, IoErrorPtr err) : rc_(rc), err_(std::move(err)) {} | ||
|
|
||
| IoCallResult(IoCallResult<T>&& result) : rc_(result.rc_), err_(std::move(result.err_)) {} | ||
| IoCallResult(IoCallResult<ReturnValue>&& result) | ||
| : rc_(result.rc_), err_(std::move(result.err_)) {} | ||
|
|
||
| virtual ~IoCallResult() {} | ||
|
|
||
| T rc_; | ||
| IoCallResult& operator=(IoCallResult&& result) { | ||
| rc_ = result.rc_; | ||
| err_ = std::move(result.err_); | ||
| return *this; | ||
| } | ||
|
|
||
| /** | ||
| * @return true if the call succeeds. | ||
| */ | ||
| bool ok() const { return err_ == nullptr; } | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. add doxygen doc, & also reference ok() as the canonical way to determine if a response succeeded to the comment above, rather than looking at err != nullptr. I had recommended also in my earlier comment renaming rc_ to make it more meaningful, e.g.return_value. If you are concerned about CL growth changing other references, can you add a TODO and then do a follow-up? Also, can you rename template name T to ReturnValue? Once you do these I'll go ahead & merge. Thanks!
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done |
||
|
|
||
| // TODO(danzh): rename it to be more meaningful, i.e. return_value_. | ||
| ReturnValue rc_; | ||
| IoErrorPtr err_; | ||
| }; | ||
|
|
||
| using IoCallUintResult = IoCallResult<uint64_t>; | ||
| using IoCallUint64Result = IoCallResult<uint64_t>; | ||
|
|
||
| inline Api::IoCallUint64Result ioCallUint64ResultNoError() { | ||
| return IoCallUint64Result(0, IoErrorPtr(nullptr, [](IoError*) {})); | ||
| } | ||
|
|
||
| } // namespace Api | ||
| } // namespace Envoy | ||
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.
given this interface can you add method:
I had to also read below at usages to understand that rc is really the interface-dependent return value. Can you call it return_value_ instead of rc_ (which sounds like it might be errno or something), and use ReturnValue rather than T as your template param?
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.
and of course use that method at call-sites rather than directly dereferencing err_.
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.
This renaming will touch even larger scope of files which is not related to socket read/write, since IoError is used in filesystem now. I would prefer do it separately so that this PR doesn't looks confusing.
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.
Can we add the ok() method now and change usage in files already in this PR, and follow up with the file-system changes later?
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.
Adding ok() sounds good to me
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.
done