]> git.cworth.org Git - vogl/blob - src/common/mtqueue.h
Initial vogl checkin
[vogl] / src / common / mtqueue.h
1 /**************************************************************************
2  *
3  * Copyright 2013-2014 RAD Game Tools and Valve Software
4  * All Rights Reserved.
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to deal
8  * in the Software without restriction, including without limitation the rights
9  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10  * copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22  * THE SOFTWARE.
23  *
24  **************************************************************************/
25
26 #pragma once
27
28 #include <pthread.h>
29
30 namespace queues
31 {
32
33     typedef int MTQ_CODE;
34
35 #define MTQ_NONE 0
36 #define MTQ_FULL 1
37 #define MTQ_EMPTY 2
38 #define MTQ_MEMERROR -1
39 #define MTQ_SYSERROR -2
40
41 #define DEFAULT_Q_SIZE 5 // Default size of nElementCount
42
43     //  Internal Structure for holding an element in the queue
44     typedef struct _qElem
45     {
46         unsigned int cb;
47         char *pb;
48     } QELEM;
49
50     //
51     //  MtQueue
52     //          Multi-thread safe queue system.  Used to move data across threads asyncronously (though with some
53     //          locking as neccessary).
54     //
55     class MtQueue
56     {
57
58     public:
59         MtQueue();
60         ~MtQueue(); // Consumer needs to ensure this is called safely
61
62         //  Initializes this queue
63         //        nElementCount specifies the maximum number of elements that may be enqueued at any one
64         //        time.  Attempting to Enqueue more when the queue is full may result in an MTQ_FULL error
65         //        returned.
66         //      Note:  This is pulled out separately from the constructor as in C++ has no good way of
67         //                 failing its constructor in any way other than the allocation of the object returning
68         //                 NULL.  In this instance we can fail to malloc, or create the mutex surrounding state
69         //                 data.
70         //                 Also, this method may only be called once, and must be called before any other methods
71         //                 get called (except its destructor).
72         MTQ_CODE Initialize(unsigned int nElementCount);
73
74         //
75         //  Enqueues a buffer onto the queue
76         //    cb - size of the data pointed to by...
77         //        pb - the pointer to the data to be enqueued...  Data is copied if necessary using malloc().
78         //        timeoutMilSec - Amount of time, for each retry, that the data is attempted to enqueue.  This only
79         //                                        really matters if the queue is full.
80         //        nRetries - the number of times it will attempt to enqueue the data.  The data will only ever be enqueued
81         //                               once, but if the queue is full, we'll retry enqueing until we succeed or the queue remains
82         //                               full the whole time.
83         //
84         MTQ_CODE Enqueue(unsigned int cb, char *pb, unsigned int timeoutMilSec, unsigned int nRetries);
85
86         //
87         //  Dequeues data from the queue
88         //        pcb - contains the size of the data pointed to by...
89         //        ppb - the pointer to a pointer pointing to the actual data.  The caller here is responsible for
90         //                      cleaning up this memory by using free().
91         //        timeoutMilSec - Amount of time, for each retry, that the data is attempted to dequeue.  This only
92         //                                        really matters if the queue is empty.
93         //        nRetries - the number of times it will attempt to dequeue the data.  The data will only ever be dequeued
94         //                               once, but if the queue is empty, we'll retry dequeing until we succeed or the queue remains
95         //                               empty the whole time.
96         //
97         MTQ_CODE Dequeue(unsigned int *pcb, char **ppb, unsigned int timeoutMilSec, unsigned int nRetries);
98
99         MTQ_CODE Purge(); // Empties the remaining elements in the Queue
100
101     private:
102         QELEM *m_pbDataList;
103         unsigned int m_iHead;
104         unsigned int m_iTail;
105         unsigned int m_cElements;
106
107         pthread_mutex_t m_mutex;
108
109         bool IsFull();
110         bool IsEmpty();
111     };
112
113 } // namespace queues