An Overlay-based
Virtual Network Substrate
SpoVNet

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

Last change on this file since 5641 was 5641, checked in by Christoph Mayer, 14 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.