Tags: EmilyOmier/YDB
Tags
[#1100] Speed up untimed READ for SOCKET device with no delimiters; R… …emove unnecessary fcntl() calls Background ---------- Below is pasted from https://gitlab.com/YottaDB/DB/YDB/-/issues/1100#description * See https://gitlab.com/YottaDB/DB/YDBXider/-/merge_requests/50#note_2176150894 for more details. * In short, Xider was used a timed READ on a SOCKET device while waiting for a message from the client. I noticed from `strace` logs that various system calls were invoked for every timed READ to start a timer and later cancel the timer. Therefore, wanted a way to read from a socket device without having to start a timer. * So looked at https://docs.yottadb.com/ProgrammersGuide/ioproc.html#read-commands and realized that the terminating conditions for a read that will let me do an untimed read is if a `Delimiter is seen`. * But in Xider, we open the SOCKET device with NO delimiter as we want all the input data to be returned by the READ whereas with a DELIMITER, the delimiter that was read is discarded by the READ. * Therefore, it seemed like even if Xider received say 32 bytes corresponding to a full Redis message with a `\r\n` terminator, we would still be waiting for a timeout to finish the READ when actually there is no need to sleep any more. * This means we need a way to terminate an untimed READ even if the socket device has no DELIMITER as long as `some` data was received. * Doing so would ensure we avoid unnecessarily sleeping for more data if we got some data to return from the READ. Changes ------- * `sr_port/iosocket_readfl.c` is modified to set the `more_data` variable to `FALSE` in the case the socket device has no delimiter defined (i.e. `has_delimiter` is FALSE), and it is an untimed READ (i.e. `timed` variable is FALSE) and there has been some non-zero data that was read (i.e. `bytes_read` variable is non-zero). This is the main change that would speed up READs by avoiding time spent unnecessarily sleeping for a timeout to happen or for a delimiter to show up. * Due to the way `more_data` is now initialized even when `terminator` variable is TRUE, it was no longer necessary to initialize it to TRUE before the `for` loop and so that was removed. * And lastly, I noticed a few `fcntl()` calls (done using the `FCNTL2` or `FCNTL3` macros) were unnecessary as they were done unconditionally even though they needed to be done only if it was a `nonblocking` socket device. Therefore, added a check of whether `socketptr->nonblocking` is TRUE and only in that case is the `fcntl()` call done. A new `reset_nonblocking` variable helps with this implementation.
PreviousNext