1 /*
2  * Copyright (c) 2014 Sippy Software, Inc., http://www.sippysoft.com
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24  * SUCH DAMAGE.
25  *
26  */
27 
28 #ifndef _RTPP_QUEUE_H_
29 #define _RTPP_QUEUE_H_
30 
31 struct rtpp_queue;
32 struct rtpp_wi;
33 
34 #define RTPPQ_REMOVE_HEAD(rqp) {             \
35     if ((rqp)->tail == (rqp)->head) {        \
36         (rqp)->tail = NULL;                  \
37     }                                        \
38     (rqp)->head = (rqp)->head->next;         \
39     (rqp)->length -= 1;                      \
40 }
41 
42 #define RTPPQ_REMOVE_AFTER(rqp, wip) {       \
43     struct rtpp_wi *_twip;                   \
44     if ((wip) == NULL) {                     \
45         _twip = (rqp)->head;                 \
46         RTPPQ_REMOVE_HEAD(rqp);              \
47     } else if ((rqp)->tail == (wip)->next) { \
48         _twip = (wip)->next;                 \
49         (wip)->next = NULL;                  \
50         (rqp)->tail = (wip);                 \
51         (rqp)->length -= 1;                  \
52     } else {                                 \
53         _twip = (wip)->next;                 \
54         (wip)->next = _twip->next;           \
55         (rqp)->length -= 1;                  \
56     }                                        \
57     _twip->next = NULL;                      \
58 }
59 
60 #define RTPPQ_APPEND(rqp, wip) {             \
61     (wip)->next = NULL;                      \
62     if ((rqp)->head == NULL) {               \
63         (rqp)->head = (wip);                 \
64         (rqp)->tail = (wip);                 \
65     } else {                                 \
66         (rqp)->tail->next = (wip);           \
67         (rqp)->tail = (wip);                 \
68     }                                        \
69     (rqp)->length += 1;                      \
70 }
71 
72 struct rtpp_queue *rtpp_queue_init(int, const char *format, ...);
73 void rtpp_queue_destroy(struct rtpp_queue *queue);
74 
75 void rtpp_queue_put_item(struct rtpp_wi *wi, struct rtpp_queue *);
76 void rtpp_queue_pump(struct rtpp_queue *);
77 
78 struct rtpp_wi *rtpp_queue_get_item(struct rtpp_queue *queue, int return_on_wake);
79 int rtpp_queue_get_items(struct rtpp_queue *, struct rtpp_wi **, int, int);
80 int rtpp_queue_get_length(struct rtpp_queue *);
81 
82 DEFINE_METHOD(rtpp_wi, rtpp_queue_match_fn, int, void *);
83 
84 int rtpp_queue_count_matching(struct rtpp_queue *, rtpp_queue_match_fn_t, void *);
85 struct rtpp_wi *rtpp_queue_get_first_matching(struct rtpp_queue *, rtpp_queue_match_fn_t, void *);
86 
87 #endif
88