Thanks for the added comments. Looks good.

Coding style says we should not use "//", but not sure if this applies to
comments.




On Mon, Aug 12, 2013 at 1:45 PM, Ben Pfaff <b...@nicira.com> wrote:

> Signed-off-by: Ben Pfaff <b...@nicira.com>
> ---
>  lib/seq.c |   12 ++++++++++--
>  lib/seq.h |   40 +++++++++++++++++++++++++++++++++++++++-
>  2 files changed, 49 insertions(+), 3 deletions(-)
>
> diff --git a/lib/seq.c b/lib/seq.c
> index abe1ad8..36e5065 100644
> --- a/lib/seq.c
> +++ b/lib/seq.c
> @@ -106,7 +106,11 @@ seq_change(struct seq *seq)
>      ovs_mutex_unlock(&seq_mutex);
>  }
>
> -/* Returns 'seq''s current sequence number (which could change
> immediately). */
> +/* Returns 'seq''s current sequence number (which could change
> immediately).
> + *
> + * seq_read() and seq_wait() can be used together to yield a race-free
> wakeup
> + * when an object changes, even without an ability to lock the object.
>  See
> + * Usage in seq.h for details. */
>  uint64_t
>  seq_read(const struct seq *seq)
>      OVS_EXCLUDED(seq_mutex)
> @@ -156,7 +160,11 @@ seq_wait__(struct seq *seq, uint64_t value)
>
>  /* Causes the following poll_block() to wake up when 'seq''s sequence
> number
>   * changes from 'value'.  (If 'seq''s sequence number isn't 'value', then
> - * poll_block() won't block at all.) */
> + * poll_block() won't block at all.)
> + *
> + * seq_read() and seq_wait() can be used together to yield a race-free
> wakeup
> + * when an object changes, even without an ability to lock the object.
>  See
> + * Usage in seq.h for details. */
>  void
>  seq_wait(const struct seq *seq_, uint64_t value)
>      OVS_EXCLUDED(seq_mutex)
> diff --git a/lib/seq.h b/lib/seq.h
> index 3423e21..c764809 100644
> --- a/lib/seq.h
> +++ b/lib/seq.h
> @@ -20,7 +20,7 @@
>  /* Thread-safe, pollable sequence number.
>   *
>   *
> - * Background
> + * Motivation
>   * ==========
>   *
>   * It is sometimes desirable to take an action whenever an object changes.
> @@ -66,6 +66,44 @@
>   *    poll_block();
>   *
>   *
> + * Alternate Usage
> + * ===============
> + *
> + * struct seq can also be used as a sort of pollable condition variable.
> + * Suppose that we want a thread to process items in a queue, and thus to
> be
> + * able to wake up whenever the queue is nonempty.  This requires a lock
> to
> + * protect the queue and a seq to signal that the queue has become
> nonempty,
> + * e.g.:
> + *
> + *    struct ovs_mutex mutex;
> + *    struct list queue OVS_GUARDED_BY(mutex);
> + *    struct seq nonempty_seq;
> + *
> + * To add an element to the queue:
> + *
> + *    ovs_mutex_lock(&mutex);
> + *    list_push_back(&queue, ...element...);
> + *    if (list_is_singleton(&queue)) {   // The 'if' test here is
> optional.
> + *        seq_change(&nonempty_seq);
> + *    }
> + *    ovs_mutex_unlock(&mutex);
> + *
> + * To wait for the queue to become nonempty:
> + *
> + *    ovs_mutex_lock(&mutex);
> + *    if (list_is_empty(&queue)) {
> + *        seq_wait(&nonempty_seq, seq_read(&nonempty_seq));
> + *    } else {
> + *        poll_immediate_wake();
> + *    }
> + *    ovs_mutex_unlock(&mutex);
> + *
> + * (In the above code 'mutex' prevents the queue from changing between
> + * seq_read() and seq_wait().  Otherwise, it would be necessary to
> seq_read(),
> + * check for a nonempty queue, and then seq_wait() on the previously read
> + * sequence number, as under Usage above.)
> + *
> + *
>   * Thread-safety
>   * =============
>   *
> --
> 1.7.10.4
>
> _______________________________________________
> dev mailing list
> dev@openvswitch.org
> http://openvswitch.org/mailman/listinfo/dev
>
_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev

Reply via email to