> Thus, you need to call accept() repeatedly to drain the backlog before returning to listening for signals.
It's not just accept. If your socket is non-blocking the same applies to read, write, and everything else. You keep syscalling until it returns EAGAIN.
> I described the general idea to Grok and it produced a beautiful implementation of this in Rust using the tokio "crate". The result had the same bug that the C++ code had, because it made the understandable assumption my younger self made that 1 SIGIO = 1 connection, but that is wrong.
I don't know what your general idea was but tokio uses epoll under the hood (correctly), so what you are describing could only have happened if you specifically instructed grok to use SIGIO.
> Finally, it is far more natural for C developers and C++ developers to use a binary format over network sockets (like I did) than HTTP.
Designing a custom protocol is way more work than just using HTTP. <insert reasons why http + json is so popular (everyone is familiar with it blah blah blah)>.
> It's not just accept. If your socket is non-blocking the same applies to read, write, and everything else. You keep syscalling until it returns EAGAIN.
You do not call read/write on a socket that is listening for connections.
> I don't know what your general idea was but tokio uses epoll under the hood (correctly), so what you are describing could only have happened if you specifically instructed grok to use SIGIO.
That is correct. There is no other way to handle SIGUSR1 in a sane way if you are not using SIGIO. At least, there was no other way until signalfd was invented, but that is not cross platform. epoll isn't either.
> Designing a custom protocol is way more work than just using HTTP. <insert reasons why http + json is so popular (everyone is familiar with it blah blah blah)>.
You are wrong about that. The code is just sending packed structures back and forth. HTTP would overcomplicate this, since you would need to implement code to go from binary to ASCII and ASCII to binary on both ends, while just sending the packed structures avoids that entirely. The only special handling this needs is to have functions that translate the structures from host byte order into network byte order and back, to ensure that endianness is not an issue should there ever be an opposite endian machine at one end of the connection, but those were trivial to write.
Do yourself a favor and stop responding. You have no idea what you are saying and it is immensely evident to anyone who has a clue about software engineering.
> You are wrong about that. The code is just sending packed structures back and forth.
Among other things, this would only work if your client is written in a language that supports C structures.
> Do yourself a favor and stop responding. You have no idea what you are saying and it is immensely evident to anyone who has a clue about software engineering.
Says the one who didn't know how to use non-blocking sockets.
> That is correct. There is no other way to handle SIGUSR1 in a sane way if you are not using SIGIO. At least, there was no other way until signalfd was invented, but that is not cross platform. epoll isn't either.
> Among other things, this would only work if your client is written in a language that supports C structures.
Such languages are used at both ends. Otherwise, this would not have been working in production for ~13 years.
> Says the one who didn't know how to use non-blocking sockets.
Neither did you until you learned it. If you successfully begin a career in software engineering and years later, have the humility to admit the mistakes you made when starting out for the benefit of others, you will deserve to have an incompetent know it all deride you for having been so kind to admit them, just like you are doing to me here.
Anyone with a modicum of programming knowledge can write code snippets free from mistakes immediately after being told about the mistakes that would be made when given a simplified explanation of one thing that is done in production software. The problem with software engineering is that nobody tells you everything you can do wrong before you do it, and you are not writing code snippets, but production software.
> If you successfully begin a career in software engineering and years later, have the humility to admit the mistakes you made when starting out for the benefit of others, you will deserve to have an incompetent know it all deride you for having been so kind to admit them, just like you are doing to me here.
I wouldn't "deride" you if you weren't acting arrogant and calling me incompetent or whatever.
> The problem with software engineering is that nobody tells you everything you can do wrong before you do it
Maybe, but the docs definitely tell you about EAGAIN and freeing memory after you're done using it. In Rust many kinds of logical errors you could potentially have made are eliminated by the type system though. For example I wrote a news scraper in Rust and ran it locally a couple times to see that it works, and it's been running for half a year now on a VPS and I never had to touch it or restart anything.
It's not just accept. If your socket is non-blocking the same applies to read, write, and everything else. You keep syscalling until it returns EAGAIN.
> I described the general idea to Grok and it produced a beautiful implementation of this in Rust using the tokio "crate". The result had the same bug that the C++ code had, because it made the understandable assumption my younger self made that 1 SIGIO = 1 connection, but that is wrong.
I don't know what your general idea was but tokio uses epoll under the hood (correctly), so what you are describing could only have happened if you specifically instructed grok to use SIGIO.
> Finally, it is far more natural for C developers and C++ developers to use a binary format over network sockets (like I did) than HTTP.
Designing a custom protocol is way more work than just using HTTP. <insert reasons why http + json is so popular (everyone is familiar with it blah blah blah)>.