Open chrysn opened 2 years ago
I'm not a fan of forcing implementation details onto all users. If we can pin data internally already, I would say keep things as-is.
How common of a use-case is pinning the socket? I haven't needed anything like this with smoltcp
yet
The internal pinning requires knowing (and explicitly stating) in advance how many sockets are to be created. Moreover, it forces a layer of indirection. All possible, but not too ergonomic.
I don't have stats on who needs it; given that pinning is often implicit in C, I'd guess it's more widespread in wrappers than in native stacks.
Is it an implementation detail? AFAIR we went from &sock to &mut sock, this may just be following the trend.
There might be a third way: If a stack just can not provide arbitrary sockets, it might just "not implement socket()" (ie panic -- just as my workaround does when more than the preallocated sockets are created), and offer an alternative factory for sockets (or, here, protosockets as the factory gives S but ST:Socket is Pin<&mut S>).
This reduces the utility of embedded-nal, but just a little, as libraries can be built to take (possibly even already connected) sockets, just as embedded-hal works. Stacks that do this would just document it; a split of traits into "socket creation" and "socket use" would be possible but not necessary.
One more downside remains being the double indirection, but I'd cross that bridge when a benchmark tells me to, no earlier.
Would that work for you? I'd give it a try. The consequence on the ecosystem would be that library authors are asked to let the application do the socket creation, or at least offer a way to work on pre-made sockets.
I'm a fan of trying to decouple Socket
from the Stack
, which I think might resolve this issue? However there's some complexity in trying to do that as well.
Some decoupling would certainly help -- once the expectation that just because you have a connected socket you can also create more sockets is out of the way, this would be easier.
As things are now (with bound sockets' accept giving new sockets), this only goes so far though; would that be part of the decoupling? (Is that #53, or are there further ideas not discussed there?)
Do we have a story for how to deal with stacks that need their sockets pinned?
For example, RIOT's sock_udp_t needs to stay in a place in memory from the time it is connected or bound -- aka be pinned.
The options I see are:
&mut socket
take aPin<&mut socket>
-- a breaking API change that'd require all general applications to pin their sockets (general applications that can't would require`ST: UdpStack, ST::Socket: Unpin
).Is 1. an option on the long run?