Hi Alfred,

On 05/01/13 14:10, Alfred Perlstein wrote:
> On 4/30/13 8:57 PM, Lawrence Stewart wrote:
>> [reposting from freebsd-arch@ - was probably the wrong list]
>>
>> Hi all,
>>
>> I've had use for these a few times now when wanting to restart a loop at
>> a previously found element, and wonder if there are any thoughts about
>> sticking them (and equivalents for other list types) in <sys/queue.h>?
>>
>> Cheers,
>> Lawrence
>>
>> #define TAILQ_FOREACH_CONTINUE(var, head, field)        \
>>     for ((var) = ((var) ? (var) : TAILQ_FIRST((head)));    \
>>     (var);                            \
>>     (var) = TAILQ_NEXT((var), field))
>>
>>
>> #define SLIST_FOREACH_CONTINUE(var, head, field)        \
>>     for ((var) = ((var) ? (var) : SLIST_FIRST((head)));    \
>>     (var);                            \
>>     (var) = SLIST_NEXT((var), field))
> 
> Can you show a few uses please?  If it can significantly cut down on
> extra code it seems wise.

Sure.

Here is an excerpt from the MPTCP patch at [1] related to TCP reassembly
(more uses are in the patch if you search for FOREACH_CONTINUE):

+ /*
+  * Search from segment just inserted towards end of list looking
+  * for a hole.
+  */
+ q = te;
+ TAILQ_FOREACH_CONTINUE(q, tp->t_segq, tqe_q) {
+       nq = TAILQ_NEXT(q, tqe_q);
+       if (nq != NULL &&
+           q->tqe_th->th_seq + q->tqe_len != nq->tqe_th->th_seq) {
+               /* Found the first out of sequence segment in the reass list. */
+               tp->t_segq->disordered = nq;
+               break;
+       }
+ }
+ if (q == NULL)
+       tp->t_segq->disordered = NULL;


Here is an excerpt from some unreleased code I'm working on that writes
a full sysctl MIB path (e.g. "a.b.c.d") into a string buffer "name",
progressing through the sysctl tree one MIB path at a time each time the
function is called (oid is initialised to be the point in the sysctl
tree from the last time the function was called):

+ again:
+       /* Depth first traversal of tree. */
+       SLIST_FOREACH_CONTINUE(oid, lsp, oid_link) {
+               if (layer == 0 && strcmp(oid->oid_name, "sysctl") == 0)
+                       continue;
+
+               namelen = strlcat(name, oid->oid_name, remain);
+               remain -= namelen;
+               layer_state[layer].layer = lsp;
+               layer_state[layer].branch = oid;
+
+               if (((oid->oid_kind & CTLTYPE) == CTLTYPE_NODE) &&
+                   !SLIST_EMPTY(SYSCTL_CHILDREN(oid))) {
+                       layer++;
+                       lsp = SYSCTL_CHILDREN(oid);
+                       oid = NULL;
+                       *(name + namelen) = '.';
+                       namelen++;
+                       *(name + namelen) = '\0';
+                       remain -= 1;
+                       goto again;
+               } else {
+                       /* Leaf node. */
+                       return (namelen);
+               }
+       }


Cheers,
Lawrence

[1]
http://caia.swin.edu.au/urp/newtcp/mptcp/tools/mptcp_v0.3_10.x.248226.patch
_______________________________________________
[email protected] mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-hackers
To unsubscribe, send any mail to "[email protected]"

Reply via email to