Closed svladykin closed 1 year ago
Merging #99 (7153a7f) into master (611a97d) will decrease coverage by
0.32%
. The diff coverage is89.18%
.
@tezc Please review.
As expected epoll/kqueue implementations got simplified (no poll->events
resizing), windows got complicated (but I tried to comment extensively).
There are no backward incompatible changes from the API point of view: poll->err
was replaced with a static thread-local, so now it is thread safe without any change in semantics. Maybe it is worth using this approach for sockets as well to avoid having 128 bytes long err
in every socket.
I understand the PR is large, I can try to split it into multiple smaller ones, but the biggest part there is Windows and it would be hard to split.
@svladykin Thanks, I'll have a look in a couple of days.
@tezc Did you have a chance to take a look?
@svladykin Sorry for the delay. I was a bit busy these days. I had a quick look and pushed some minor changes mostly about style. I need some more time to wrap my head around, hopefully I'll complete the review by tomorrow.
@tezc No rush, I just wanted to make sure you did not forget about this PR :)
@svladykin Sorry for the delay. I didn't have much time to review and probably it will take more time to wrap my head around the changes fully. Not to make this review longer, considering API is compatible and most changes are on Windows, I think we can merge it and I'll take a look in parallel and ask you questions if I need :)
__thread
for sock err, I didn't want to use anything compiler specific initially but socket code won't be quite portable anyway (at least not as much as a linkedlist impl). So, I guess we can use __thread
for sockets as well. Added a few comments in the PR regarding return value checks, after those, we can merge the PR I guess. Thanks for the PR and sorry for late review. Last month was a bit busy and looks like there is another busy month upcoming for me :)
@tezc Thanks for the review. I will address your comments shortly.
@tezc I have made the requested adjustments. Also I fixed a WSAPoll
error handling issue on Windows. Please look.
@svladykin Thank you very much, looks good to me. We have %100 branch coverage on Linux but other OSes like Windows, damn there are many bugs. Thank you for the fixes.
Is there anything else we need to do for this PR? Btw could you add a few lines to the top comment and briefly describe the changes?
@tezc I believe this PR is good to go. The epoll
/kqueue
changes seems to be safe, Windows is less safe, but if any issues arise I will fix them.
Fixes https://github.com/tezc/sc/issues/98
For all implementations:
err
with a static thread-localsc_sock_poll_errstr
to make suresc_sock_poll_err()
will return correct error message for different threads;SC_SOCK_POLL_MAX_EVENTS
events, which is1024
by default.For Linux/FreeBSD/MacOS (
epoll
andkqueue
) :count
andcap
as well asevents
expanding to allow safe concurrent access (epoll
andkqueue
themselves are thread-safe);sc_sock_fd
are done beforeepoll_ctl
/kevent
call to avoid possible data races, if the kernel call failed rollback to the original state;For Windows (
WSAPoll
):lock
to protect shared state;results
buffer which is filled under the lock withsc_sock_poll_fill_results()
to allowsc_sock_poll_event()
andsc_sock_poll_data()
access results outside of thelock
;sc_sock_poll_wait()
is the actual number of events collected, not the capacity ofevents
;sc_sock_poll_data
struct which containsindex
offd
inevents
,data
pointer and also volatileedge_mask
which is updated by atomic instructions to allow Edge-Triggered mode work without acquiring thelock
;data
as a data structure that does not userealloc
to expand: this is needed to have a stable pointer fromsc_sock_fd
tosc_sock_poll_data
(again no need to acquirelock
on every access);ops
buffer to store the socket operations submitted by other threads while polling is in progress;polling
flag that marks "polling is in progress" state and protectsevents
from concurrent modifications;wakeup_pipe
which is registered to the samesc_sock_poll
to be able to wake up the poller thread when submitting socket operations from parallel threads;sc_sock_poll
then no reference to the socket fdt is held inops
, so it is safe to dosc_sock_term()
andfree()
on the socket right after successful call tosc_sock_poll_del()
in any thread without waiting until the poller thread actually processes that operation.WSAPoll
: useWSAGetLastError()
instead oferrno
;sc_sock_pipe_read()
andsc_sock_pipe_write()
: no need to checkrc != len
;sc_sock_pipe_init()
: need to assign read fd to fdt;