1 /**************************************************************************
3 * Copyright 2013-2014 RAD Game Tools and Valve Software
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:
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
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
24 **************************************************************************/
38 #define MTQ_MEMERROR -1
39 #define MTQ_SYSERROR -2
41 #define DEFAULT_Q_SIZE 5 // Default size of nElementCount
43 // Internal Structure for holding an element in the queue
52 // Multi-thread safe queue system. Used to move data across threads asyncronously (though with some
53 // locking as neccessary).
60 ~MtQueue(); // Consumer needs to ensure this is called safely
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
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
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);
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.
84 MTQ_CODE Enqueue(unsigned int cb, char *pb, unsigned int timeoutMilSec, unsigned int nRetries);
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.
97 MTQ_CODE Dequeue(unsigned int *pcb, char **ppb, unsigned int timeoutMilSec, unsigned int nRetries);
99 MTQ_CODE Purge(); // Empties the remaining elements in the Queue
103 unsigned int m_iHead;
104 unsigned int m_iTail;
105 unsigned int m_cElements;
107 pthread_mutex_t m_mutex;
113 } // namespace queues