site_archiver@lists.apple.com Delivered-To: darwin-kernel@lists.apple.com Hi Josh, Sam On 26/07/2005, at 4:03 AM, Josh Graessley wrote: Hi Sam, -josh On Jul 25, 2005, at 12:58 AM, Sam Vaughan wrote: soreceive(so, NULL, uiop, NULL, NULL, flagsp); My first attempt at a KPI replacement looked like this: size_t bytes = uio->uio_resid; struct msghdr msg = {0}; msg.msg_iov = uiop->uio_iov; msg.msg_iovlen = uiop->uio_iovcnt; error = sock_receive(so, &msg, 0, &bytes); if (!error) { uiop->uio_offset += bytes; uiop->uio_resid -= bytes; ASSERT(uiop->uio_resid >= 0); } This email sent to jgraessley@apple.com _______________________________________________ Do not post admin requests to the list. They will be ignored. Darwin-kernel mailing list (Darwin-kernel@lists.apple.com) Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/darwin-kernel/site_archiver%40lists.a... Thanks for the speedy reply. I'm only interested in sending/ receiving to/from kernel memory here so that's not a concern right now. Don't you agree however that in moving from soreceive() to sock_receive(), the interface has dropped in usefulness? The idea of allocating yet another uio, walking the iovecs in my own one and adding new iovecs with the appropriate addresses and lengths to the new one makes me shudder. That'd be three uios allocated, prepared and freed just to do one I/O operation - one in our platform-common code, one in the 10.4 wrapper around sock_receive(), and another in sock_receive_internal(). One more entry point that takes a uio and passes it straight to soreceive would be a real bonus, for elegance, performance AND sanity ;o) The socket KPI was written to simplify the use of sockets in the kernel. The new socket KPI is based more on the user space APIs for interacting with sockets. sock_send is very much like sendmsg, sock_receive is like recvmsg. You may create a new iovec array to point to the buffers you're interested in copying in to. One other thing to be aware of is that the pointers in the iovec array must point to data that resides in the kernel's address space. If you need to receive in to a buffer in another process you will need to copy the data yourself. To avoid copying the data twice, you can use the sock_receivembuf variant which will receive the mbuf chain without performing a copy. I'm trying to clean up the areas in our code where I'm using symbols from mach_kernel instead of the 10.4 KPI. One of these is the use of soreceive() and sosend(). I avoided using the KPI on these two initially because the new interface that uses struct msghdr looked confusing. Now that I've delved into it a bit more it looks pretty much unworkable. Let me use sock_receive() here as an example. When linking directly to the kernel, I can simply pass a uio pointer to soreceive() as follows: I can do this safe in the knowledge that it will use uio_move() to transfer the data it reads into my uio, using and updating my uio_offset and uio_resid fields as appropriate. But it's clearly deficient because the uio_offset isn't being passed into sock_receive(). It's also not clear that it will use my uio_resid value. Sure enough when you run it up, this code asserts pretty quickly, having read more than I wanted it to. The problem as I see it is that the new socket KPI doesn't allow you to specify an offset and a resid along with your iovecs. It's therefore not possible to read into a range of memory somewhere in the middle of the buffers represented by your iovecs. If you use sock_receivembuf(), the data argument to sock_receive_internal() won't be NULL and the value in recvdlen will get used as the uio's resid. This solves one of the problems. Unfortunately the call to uio_createwithbuffer() will still specify 0 for the initial offset of the uio, so this is no good if you want to read into somewhere in the middle of your buffers. The only solution I can see at the moment is to create yet another uio structure before calling sock_receive(). This uio would be given iovecs with data addresses and lengths that represent the region of the original buffers to be received into. This is clearly not an optimal solution, given the extra overhead and unnecessary code to write and debug. It seems odd to me that the shiny new uio KPI wasn't used in the sock_receive() and sock_send() interfaces, since this is exactly the functionality that uios are designed (and were previously used) for. I've raised a radar bug requesting sock_receive_uio() and sock_send_uio() to be added, (#4191646) but I'd be interested to hear other people's opinions on this. Sam _______________________________________________ Do not post admin requests to the list. They will be ignored. Darwin-kernel mailing list (Darwin-kernel@lists.apple.com) Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/darwin-kernel/jgraessley% 40apple.com This email sent to site_archiver@lists.apple.com