diff options
author | David Robillard <d@drobilla.net> | 2007-04-02 00:26:21 +0000 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2007-04-02 00:26:21 +0000 |
commit | a23b21908e4d0fab277a9f6f7d5a3b5a69746740 (patch) | |
tree | a12085c9eb5873d48ecf08ffe030fa2b459d6ef6 /raul/List.h | |
parent | 69559bddc0ae41f1f81241d92675009f86fa79b1 (diff) | |
download | raul-a23b21908e4d0fab277a9f6f7d5a3b5a69746740.tar.gz raul-a23b21908e4d0fab277a9f6f7d5a3b5a69746740.tar.bz2 raul-a23b21908e4d0fab277a9f6f7d5a3b5a69746740.zip |
List appending.
Make SMFReader abort gracefully on non-SMF files.
git-svn-id: http://svn.drobilla.net/lad/raul@389 a436a847-0d15-0410-975c-d299462d15a1
Diffstat (limited to 'raul/List.h')
-rw-r--r-- | raul/List.h | 46 |
1 files changed, 45 insertions, 1 deletions
diff --git a/raul/List.h b/raul/List.h index e7e2158..79748ba 100644 --- a/raul/List.h +++ b/raul/List.h @@ -55,7 +55,7 @@ private: -/** A realtime safe, (partially) thread safe doubly linked list. +/** A realtime safe, (partially) thread safe doubly-linked list. * * Elements can be added safely while another thread is reading the list. * Like a typical ringbuffer, this is single-reader single-writer threadsafe @@ -75,6 +75,8 @@ public: void push_back(ListNode<T>* elem); // realtime safe void push_back(T& elem); // NOT realtime safe + void append(List<T>& list); + void clear(); /// Valid only in the write thread @@ -235,6 +237,48 @@ List<T>::push_back(T& elem) } +/** Append a list to this list. + * + * This operation is fast ( O(1) ). + * The appended list is not safe to use concurrently with this call. + * + * The appended list will be empty after this call. + * + * Thread safe (may be called while another thread is reading the list). + * Realtime safe. + */ +template <typename T> +void +List<T>::append(List<T>& list) +{ + ListNode<T>* const my_head = _head.get(); + ListNode<T>* const my_tail = _tail.get(); + ListNode<T>* const other_head = list._head.get(); + ListNode<T>* const other_tail = list._tail.get(); + + // Appending to an empty list + if (my_head == NULL && my_tail == NULL) { + _head = other_head; + _tail = other_tail; + _size = list._size; + } else if (other_head != NULL && other_tail != NULL) { + + other_head->prev(my_tail); + + // FIXME: atomicity an issue? _size < true size is probably fine... + // no gurantee an iteration runs exactly size times though. verify/document this. + // assuming comment above that says tail is writer only, this is fine + my_tail->next(other_head); + _tail = other_tail; + _size += list.size(); + } + + list._head = NULL; + list._tail = NULL; + list._size = 0; +} + + /** Remove all elements equal to @val from the list. * * This function is realtime safe - it is the caller's responsibility to |