The idea is simple: you allocate a buffer in an area of memory that has been made directly accessible both to your process and to the kernel. You are obliged to initialize that area of memory in the form of a linked list of equal-sized slots. Now, when you access the socket (which you do using the same "poll()" based logic as before), the kernel moves the data directly into that agreed-upon area of memory, thereby occupying zero-or-more of those slots. Your process wakes up to (maybe...) discover that zero or more of those slots are now "magically" filled with data. It processes the content of the slots in the required way, then goes to sleep again.
The advantages of this arrangement are that (a) the data only has to be copied once (by the kernel, directly to/from a location that is agreeable to you both); and (b) more than one piece of data can be exchanged between your process and the kernel using only one "wakeup call." The number of trips through the system dispatcher and the number of system-calls in general is greatly reduced.
The source-code in lincap.c illustrates the procedure. The user-land process allocates the buffer, initializes it, announces it to the kernel when opening the socket, then enters an endless loop which consists first of processing the zero-or-more chunks of data that it might find there, then waiting for more. The loop is constructed in the manner that it is (with the poll call at the bottom) in recognition of the fact that the buffer might be filled with some data when the socket is successfully opened.
Last edited by sundialsvcs; 05-30-2012 at 05:19 PM.
|