+ conditions should work
[public/netxms.git] / src / libnetxms / queue.cpp
CommitLineData
b01a54ba
VK
1/*
2** Project X - Network Management System
3** Copyright (C) 2003 Victor Kirhenshtein
4**
5** This program is free software; you can redistribute it and/or modify
6** it under the terms of the GNU General Public License as published by
7** the Free Software Foundation; either version 2 of the License, or
8** (at your option) any later version.
9**
10** This program is distributed in the hope that it will be useful,
11** but WITHOUT ANY WARRANTY; without even the implied warranty of
12** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13** GNU General Public License for more details.
14**
15** You should have received a copy of the GNU General Public License
16** along with this program; if not, write to the Free Software
17** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18**
19** $module: queue.cpp
20**
21**/
22
23#include "libnetxms.h"
24
25
26//
27// Queue constructor
28//
29
30Queue::Queue(DWORD dwInitialSize, DWORD dwBufferIncrement)
31{
32 m_hQueueAccess = MutexCreate();
d16cf8a5 33 m_hConditionNotEmpty = ConditionCreate(FALSE);
b01a54ba
VK
34 m_dwNumElements = 0;
35 m_dwFirst = 0;
36 m_dwLast = 0;
37 m_dwBufferSize = dwInitialSize;
38 m_dwBufferIncrement = dwBufferIncrement;
39 m_pElements = (void **)MemAlloc(sizeof(void *) * m_dwBufferSize);
40}
41
42
43//
44// Destructor
45//
46
47Queue::~Queue()
48{
49 MutexDestroy(m_hQueueAccess);
50 ConditionDestroy(m_hConditionNotEmpty);
51 MemFree(m_pElements);
52}
53
54
55//
56// Put new element into queue
57//
58
59void Queue::Put(void *pElement)
60{
61 Lock();
62 if (m_dwNumElements == m_dwBufferSize)
63 {
64 // Extend buffer
65 m_dwBufferSize += m_dwBufferIncrement;
66 m_pElements = (void **)MemReAlloc(m_pElements, sizeof(void *) * m_dwBufferSize);
67
68 // Move free space
69 memmove(&m_pElements[m_dwFirst + m_dwBufferIncrement], &m_pElements[m_dwFirst],
70 sizeof(void *) * (m_dwBufferSize - m_dwFirst - m_dwBufferIncrement));
71 m_dwFirst += m_dwBufferIncrement;
72 }
73 m_pElements[m_dwLast++] = pElement;
74 if (m_dwLast == m_dwBufferSize)
75 m_dwLast = 0;
76 m_dwNumElements++;
77 ConditionSet(m_hConditionNotEmpty);
78 Unlock();
79}
80
81
82//
83// Get object from queue. Return NULL if queue is empty
84//
85
86void *Queue::Get(void)
87{
88 void *pElement = NULL;
89
90 Lock();
91 if (m_dwNumElements != 0)
92 {
93 pElement = m_pElements[m_dwFirst++];
94 if (m_dwFirst == m_dwBufferSize)
95 m_dwFirst = 0;
96 m_dwNumElements--;
97 }
98 Unlock();
99 return pElement;
100}
101
102
103//
104// Get object from queue or block if queue if empty
105//
106
107void *Queue::GetOrBlock(void)
108{
109 void *pElement;
110
111 pElement = Get();
112 if (pElement != NULL)
113 return pElement;
114 do
115 {
116 ConditionWait(m_hConditionNotEmpty, INFINITE);
117 pElement = Get();
118 } while(pElement == NULL);
119 return pElement;
120}