sockpp icon indicating copy to clipboard operation
sockpp copied to clipboard

Moving toward stateless I/O without exceptions

Open fpagliughi opened this issue 1 year ago • 2 comments

Commit 784dc0958c08f4894258c8a2f5b411e36b38fad4 in PR #17 introduced stateless I/O functions, like read_r() and writre_r(), which return an ioresult type that wrap the success and specific error values derived from errno or GetLastError().

On an unrelated note, in Issue #72, @JakeSays suggested getting rid of exceptions in the few places they're used, and @ldgeng, suggested using std::error_code.

I was not even aware std::error_code existed, but it looks very appropriate for this library. It would be a good way to eliminate platform-specific differences of checking errors on Win32 that has been plaguing us already. And it would present a road forward for handling errors when TLS libraries are introduced in a future version of sockpp.

So, taken all together, I'm thinking of doing this...

  1. Convert the "last error" in the library to return an error code, like:
    std::error_code socket::get_last_error();
  1. Make a generic result<T> type where T is the success variant and error_code is the error.
    template <typename T>
    class result {
        /** The return value of an operation, if successful */
        T val_;
        /** The error returned from an operation, if failed */
        error_code err_;
    // ...
    };
  1. An ioresult would be a specialization of result<int>:
    using ioresul = result<int>;
  1. Remove exceptions and return a result<T> in their place. The whole API will be noexcept.
  2. Constructors that would have thrown now just set the last error, and thus would need to be checked (similar to iostreams, I guess).
  3. Phase out the need for maintaining the error state. In the next major release, move to all I/O operations being stateless, returning an ioresult. The only explicit need for the state would be checking the object after construction.

The last point would allow a single socket to be thread-safe for two threads where one reads from the socket and the other writes to it. This is a common pattern in socket apps in C, but couldn't be done in sockpp since get_last_error() is not thread safe.

fpagliughi avatar Mar 19 '23 18:03 fpagliughi