source: trash/old-modules/transport/protlib/queuemanager.cpp@ 5641

Last change on this file since 5641 was 5641, checked in by Christoph Mayer, 15 years ago
File size: 5.9 KB
Line 
1/// ----------------------------------------*- mode: C++; -*--
2/// @file queuemanager.cpp
3/// queuemanager which records queues and message source IDs
4/// ----------------------------------------------------------
5/// $Id: queuemanager.cpp 2774 2007-08-08 12:32:08Z bless $
6/// $HeadURL: https://svn.ipv6.tm.uka.de/nsis/protlib/trunk/src/queuemanager.cpp $
7// ===========================================================
8//
9// Copyright (C) 2005-2007, all rights reserved by
10// - Institute of Telematics, Universitaet Karlsruhe (TH)
11//
12// More information and contact:
13// https://projekte.tm.uka.de/trac/NSIS
14//
15// This program is free software; you can redistribute it and/or modify
16// it under the terms of the GNU General Public License as published by
17// the Free Software Foundation; version 2 of the License
18//
19// This program is distributed in the hope that it will be useful,
20// but WITHOUT ANY WARRANTY; without even the implied warranty of
21// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22// GNU General Public License for more details.
23//
24// You should have received a copy of the GNU General Public License along
25// with this program; if not, write to the Free Software Foundation, Inc.,
26// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
27//
28// ===========================================================
29/** @ingroup queuemanager
30 *
31 */
32#include <stdexcept>
33
34#include "queuemanager.h"
35#include "logfile.h"
36
37namespace protlib {
38
39/** @addtogroup queuemanager Queue Manager
40 * \ingroup fastqueue
41 * @{
42 */
43
44using namespace log;
45
46/***** class QueueManagerError *****/
47
48QueueManagerError::QueueManagerError(error_t e) : err(e) {}
49
50const char* QueueManagerError::getstr() const { return errstr[err]; }
51
52const char* const QueueManagerError::errstr[] = {
53 "Unable to create QueueManager.",
54 "Cannot register FastQueue. No memory or registered queue more than once."
55}; // end errstr
56
57/***** class QueueManager *****/
58
59/** Return QueueManager singleton. */
60QueueManager* QueueManager::instance() {
61 if (!inst) {
62 // try to create singleton
63 inst = new(nothrow) QueueManager();
64 if (!inst) {
65 Log(INFO_LOG,LOG_NORMAL, "QueueManager" ,"Cannot created QueueManager singleton.");
66 throw QueueManagerError(QueueManagerError::ERROR_NO_QUEUE_MANAGER);
67 } else {
68 Log(DEBUG_LOG,LOG_NORMAL, "QueueManager", "Just created QueueManager singleton.");
69 } // end if not inst
70 } // end if not inst
71 return inst;
72} // end QueueManager
73
74/**
75 * Delete the QueueManager singleton object.
76 *
77 * After a call to clear references to that object become invalid and must
78 * be updated by a call to instance().
79 */
80void QueueManager::clear() {
81
82 if (inst) {
83 QueueManager *tmp = inst;
84 inst = 0;
85 DLog("QueueManager", "Destroying QueueManager singleton ...");
86 delete tmp;
87 }
88
89 DLog("QueueManager", "The QueueManager singleton has been destroyed");
90}
91
92
93/**
94 * Register a queue.
95 *
96 * This registers a FastQueue for the given message source ID with the
97 * QueueManager.
98 *
99 * The registered queue (and all its entries) is deleted as soon as the
100 * QueueManager is deleted. Because of this, a queue may only be registered
101 * once.
102 *
103 * @param fq pointer to an already allocated fastqueue
104 * @param s message source ID
105 */
106void QueueManager::register_queue(FastQueue* fq, message::qaddr_t s) {
107 pthread_mutex_lock(&mutex); // install_cleanup_mutex_lock(&mutex);
108 // expand array if necessary
109 if (((uint32)s)>=queue_arr.capacity()) {
110 Log(DEBUG_LOG,LOG_NORMAL, "QueueManager", "expanding queue array from " << s << " to " << s+5);
111 // get more memory
112 queue_arr.reserve(s+5);
113 while (queue_arr.size()<queue_arr.capacity()) queue_arr.push_back(NULL);
114 } // end get more memory
115
116 if (queue_arr[s])
117 {
118 // queue already exists
119 Log(ERROR_LOG,LOG_CRIT, "QueueManager", "A queue for " << s << " is already registered");
120 throw QueueManagerError(QueueManagerError::ERROR_REGISTER);
121 } // end if queue exists
122 else
123 {
124 // register queue
125 if (fq)
126 {
127 queue_arr[s] = fq;
128 }
129 else
130 {
131 Log(ERROR_LOG,LOG_CRIT, "QueueManager", "Cannot register queue for " << s);
132 throw QueueManagerError(QueueManagerError::ERROR_REGISTER);
133 }
134 } // end else no queue exists
135 pthread_mutex_unlock(&mutex); // uninstall_cleanup(1);
136} // end register_queue
137
138
139void
140QueueManager::unregister_queue(message::qaddr_t s)
141{
142 pthread_mutex_lock(&mutex); // install_cleanup_mutex_lock(&mutex);
143 try {
144 queue_arr.at(s) = 0;
145 }
146 catch ( std::out_of_range ) {
147 /*
148 * Nothing to do, queue has probably already been unregistered,
149 * probably by calling QueueManager::clear().
150 */
151 }
152 pthread_mutex_unlock(&mutex); // uninstall_cleanup(1);
153}
154
155FastQueue* QueueManager::get_queue(message::qaddr_t s) const {
156 FastQueue* fq = NULL;
157 pthread_mutex_lock(&mutex); // install_cleanup_mutex_lock(&mutex);
158 if (((uint32)s)<queue_arr.size()) {
159 fq = queue_arr[s];
160 } else {
161 fq = NULL;
162 } // end if
163 pthread_mutex_unlock(&mutex); // uninstall_cleanup(1);
164 return fq;
165} // end get
166
167QueueManager* QueueManager::inst = NULL;
168
169/**
170 * Constructor.
171 */
172QueueManager::QueueManager() : queue_arr(QueueManager::INITIAL_ARRAY_SIZE) {
173 pthread_mutexattr_t mutex_attr;
174
175 pthread_mutexattr_init(&mutex_attr);
176
177#ifdef _DEBUG
178 pthread_mutexattr_settype(&mutex_attr, PTHREAD_MUTEX_ERRORCHECK);
179#else
180 pthread_mutexattr_settype(&mutex_attr, PTHREAD_MUTEX_NORMAL);
181#endif
182
183 pthread_mutex_init(&mutex, &mutex_attr);
184
185 pthread_mutexattr_destroy(&mutex_attr); // doesn't affect mutex
186}
187
188
189/**
190 * Destructor.
191 *
192 * Delete this object and all FastQueue objects that are still registered.
193 */
194QueueManager::~QueueManager() {
195
196 pthread_mutex_lock(&mutex);
197
198 // count queues which are still registered
199 for ( qm_array_it_t i = queue_arr.begin(); i != queue_arr.end(); i++)
200 if ( *i != 0 )
201 WLog("QueueManager",
202 "~QueueManager(): queue " << (*i)->get_name()
203 << " has not been unregistered");
204
205 pthread_mutex_unlock(&mutex);
206
207 pthread_mutex_destroy(&mutex);
208}
209
210//@}
211
212} // end namespace protlib
Note: See TracBrowser for help on using the repository browser.