diff --git a/BitVector.cpp b/BitVector.cpp index ff445d3..f24b17e 100644 --- a/BitVector.cpp +++ b/BitVector.cpp @@ -1,5 +1,6 @@ /* * Copyright 2008, 2009, 2014 Free Software Foundation, Inc. +* Copyright 2014 Range Networks, Inc. * * * This software is distributed under the terms of the GNU Affero Public License. @@ -348,6 +349,7 @@ float SoftVector::getSNR() const } + ostream& operator<<(ostream& os, const SoftVector& sv) { for (size_t i=0; i //@{ /**@name Casts of Vector constructors. */ - BitVector(VectorDataType wData, char* wStart, char* wEnd) : VectorBase(wData, wStart, wEnd) {} + BitVector(VectorDataType wData, char* wStart, char* wEnd) : VectorBase(wData, wStart, wEnd) {} // The one and only copy-constructor. BitVector(const BitVector&other) : VectorBase() { diff --git a/BitVectorTest.cpp b/BitVectorTest.cpp index 63ab10b..e2bf3cf 100644 --- a/BitVectorTest.cpp +++ b/BitVectorTest.cpp @@ -1,5 +1,6 @@ /* * Copyright 2008 Free Software Foundation, Inc. +* Copyright 2014 Range Networks, Inc. * * * This software is distributed under the terms of the GNU Affero Public License. diff --git a/Configuration.cpp b/Configuration.cpp index 88afbb9..b567d81 100644 --- a/Configuration.cpp +++ b/Configuration.cpp @@ -3,7 +3,6 @@ * Copyright 2010 Kestrel Signal Processing, Inc. * Copyright 2011, 2012, 2014 Range Networks, Inc. * -* * This software is distributed under the terms of the GNU Affero Public License. * See the COPYING file in the main directory for details. * diff --git a/Configuration.h b/Configuration.h index 778168b..5f6004d 100644 --- a/Configuration.h +++ b/Configuration.h @@ -371,33 +371,34 @@ class ConfigurationKey { BOOLEAN, CHOICE_OPT, CHOICE, - CIDR_OPT, + CIDR_OPT, // (pat) IP Route, eg: "xxx.xxx.xxx.xxx/yy" CIDR, FILEPATH_OPT, FILEPATH, HOSTANDPORT_OPT, - HOSTANDPORT, + HOSTANDPORT, // (pat) hostname is allowed. IPADDRESS_OPT, - IPADDRESS, + IPADDRESS, // (pat) IP Address but hostnames not allowed. IPANDPORT, MIPADDRESS_OPT, - MIPADDRESS, + MIPADDRESS, // (pat) List of IP addresses + optional ports, used only for the Neighbors config option. PORT_OPT, - PORT, + PORT, // (pat) An IP port. REGEX_OPT, REGEX, STRING_OPT, STRING, VALRANGE // (pat) string format is: ':' [ '(' ')' ] // step is not currently enforced. + // To allow floating point add a decimal point to the range, eg: "0.0:10.0" }; enum Scope { - GLOBALLYUNIQUE = 1, - GLOBALLYSAME = 2, - NEIGHBORSUNIQUE = 4, - NEIGHBORSSAME = 8, + GLOBALLYUNIQUE = 1, // (pat) value must be unique on all nodes. + GLOBALLYSAME = 2, // (pat) value must be the same on all nodes. + NEIGHBORSUNIQUE = 4, // (pat) value must be unique on all neighbors + NEIGHBORSSAME = 8, // (pat) value must be the same on all neighbors NODESPECIFIC = 16 }; diff --git a/ConfigurationTest.cpp b/ConfigurationTest.cpp index 3d8014b..1cfb5a9 100644 --- a/ConfigurationTest.cpp +++ b/ConfigurationTest.cpp @@ -1,6 +1,7 @@ /* * Copyright 2009, 2010 Free Software Foundation, Inc. * Copyright 2010 Kestrel Signal Processing, Inc. +* Copyright 2014 Range Networks, Inc. * * * This software is distributed under the terms of the GNU Affero Public License. diff --git a/Defines.h b/Defines.h index 5fb431d..f882c52 100644 --- a/Defines.h +++ b/Defines.h @@ -1,3 +1,27 @@ +/* +* Copyright 2014 Range Networks, Inc. +* +* This software is distributed under the terms of the GNU Affero Public License. +* See the COPYING file in the main directory for details. +* +* This use of this software may be subject to additional restrictions. +* See the LEGAL file in the main directory for details. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + +*/ + // Pat added this file. // We need an include file that is included before any other include files. // Might I suggest that Range Networks specific global #defines be prefixed with RN_ diff --git a/Exit.h b/Exit.h index a9f6de9..2457ad3 100644 --- a/Exit.h +++ b/Exit.h @@ -4,7 +4,7 @@ * * This software is distributed under multiple licenses; * see the COPYING file in the main directory for licensing -* information for this specific distribuion. +* information for this specific distribution. * * This use of this software may be subject to additional restrictions. * See the LEGAL file in the main directory for details. diff --git a/F16.h b/F16.h index aa292f0..374c91a 100644 --- a/F16.h +++ b/F16.h @@ -1,5 +1,6 @@ /* * Copyright 2009 Free Software Foundation, Inc. +* Copyright 2014 Range Networks, Inc. * * This software is distributed under the terms of the GNU Affero Public License. * See the COPYING file in the main directory for details. diff --git a/F16Test.cpp b/F16Test.cpp index 7f3c84d..757280d 100644 --- a/F16Test.cpp +++ b/F16Test.cpp @@ -1,5 +1,6 @@ /* * Copyright 2009 Free Software Foundation, Inc. +* Copyright 2014 Range Networks, Inc. * * * This software is distributed under the terms of the GNU Affero Public License. diff --git a/Interthread.h b/Interthread.h index 35294a2..e56b360 100644 --- a/Interthread.h +++ b/Interthread.h @@ -1,5 +1,6 @@ /* * Copyright 2008, 2011 Free Software Foundation, Inc. +* Copyright 2014 Range Networks, Inc. * * This software is distributed under the terms of the GNU Affero Public License. * See the COPYING file in the main directory for details. @@ -43,122 +44,6 @@ //@{ -/** Pointer FIFO for interthread operations. */ -// (pat) The elements in the queue are type T*, and -// the Fifo class implements the underlying queue. -// The default is class PointerFIFO, which does not place any restrictions on the type of T, -// and is implemented by allocating auxilliary structures for the queue, -// or SingleLinkedList, which implements the queue using an internal pointer in type T, -// which must implement the functional interface of class SingleLinkListNode, -// namely: functions T*next() and void setNext(T*). -#if UNUSED -//template class InterthreadQueue { -// -// protected: -// -// Fifo mQ; -// mutable Mutex mLock; -// mutable Signal mWriteSignal; -// -// public: -// -// /** Delete contents. */ -// void clear() -// { -// ScopedLock lock(mLock); -// while (mQ.size()>0) delete (T*)mQ.get(); -// } -// -// /** Empty the queue, but don't delete. */ -// void flushNoDelete() -// { -// ScopedLock lock(mLock); -// while (mQ.size()>0) mQ.get(); -// } -// -// -// ~InterthreadQueue() -// { clear(); } -// -// -// size_t size() const -// { -// ScopedLock lock(mLock); -// return mQ.size(); -// } -// -// size_t totalSize() const // pat added -// { -// ScopedLock lock(mLock); -// return mQ.totalSize(); -// } -// -// /** -// Blocking read. -// @return Pointer to object (will not be NULL). -// */ -// T* read() -// { -// ScopedLock lock(mLock); -// T* retVal = (T*)mQ.get(); -// while (retVal==NULL) { -// mWriteSignal.wait(mLock); -// retVal = (T*)mQ.get(); -// } -// return retVal; -// } -// -// /** Non-blocking peek at the first element; returns NULL if empty. */ -// T* front() -// { -// ScopedLock lock(mLock); -// return (T*) mQ.front(); -// } -// -// /** -// Blocking read with a timeout. -// @param timeout The read timeout in ms. -// @return Pointer to object or NULL on timeout. -// */ -// T* read(unsigned timeout) -// { -// if (timeout==0) return readNoBlock(); -// Timeval waitTime(timeout); -// ScopedLock lock(mLock); -// while ((mQ.size()==0) && (!waitTime.passed())) -// mWriteSignal.wait(mLock,waitTime.remaining()); -// T* retVal = (T*)mQ.get(); -// return retVal; -// } -// -// /** -// Non-blocking read. -// @return Pointer to object or NULL if FIFO is empty. -// */ -// T* readNoBlock() -// { -// ScopedLock lock(mLock); -// return (T*)mQ.get(); -// } -// -// /** Non-blocking write. */ -// void write(T* val) -// { -// ScopedLock lock(mLock); -// mQ.put(val); -// mWriteSignal.signal(); -// } -// -// /** Non-block write to the front of the queue. */ -// void write_front(T* val) // pat added -// { -// ScopedLock lock(mLock); -// mQ.push_front(val); -// mWriteSignal.signal(); -// } -//}; -#endif - // A list designed for pointers so we can use get methods that return NULL on error. template class PtrList : public std::list { @@ -365,7 +250,7 @@ template > class InterthreadQueue { T* front() { ScopedLock lock(*mLockPointer); - return (T*) mQ.front(); + return (T*) (mQ.size() ? mQ.front() : NULL); } /** @@ -380,7 +265,7 @@ template > class InterthreadQueue { ScopedLock lock(*mLockPointer); while (mQ.size()==0) { long remaining = waitTime.remaining(); - // (pat) How high to we expect the precision here to be? I dont think they are used a precision timers, + // (pat) How high do we expect the precision here to be? I dont think they used precision timers, // so dont try to wait if the remainder is just a few msecs. if (remaining < 2) { return NULL; } mWriteSignalPointer->wait(*mLockPointer,remaining); @@ -496,7 +381,7 @@ template class InterthreadQueueWithWait { // mWriteSignal.wait(mLock,waitTime.remaining()); while (mQ.size()==0) { long remaining = waitTime.remaining(); - // (pat) How high to we expect the precision here to be? I dont think they are used a precision timers, + // (pat) How high do we expect the precision here to be? I dont think they are used as precision timers, // so dont try to wait if the remainder is just a few msecs. if (remaining < 2) { return NULL; } mWriteSignal.wait(mLock,remaining); @@ -521,9 +406,10 @@ template class InterthreadQueueWithWait { /** Non-blocking write. */ void write(T* val) { - // (pat) 8-14: Taking out the threading problem fix temporarily for David to use in the field. - ScopedLock lock(mLock); - mQ.put(val); + { + ScopedLock lock(mLock); + mQ.put(val); + } mWriteSignal.signal(); } @@ -541,51 +427,44 @@ template class InterthreadQueueWithWait { }; - - - -/** Thread-safe map of pointers to class D, keyed by class K. */ -template class InterthreadMap +// (pat) Same as an InterthreadMap but the mapped type is "D" instead of "D*"; +// the only difference is that we cannot automatically delete the content on destruction (no clear method). +template class InterthreadMap1 { public: - typedef std::map Map; // (pat) It would be more generally useful if this were D instead of D* + typedef std::map Map; protected: Map mMap; mutable Mutex mLock; - //mutable Mutex mModificationLock; // (pat) Lock prevents deletion from the map while an iterator is active. Signal mWriteSignal; public: + // User can over-ride this method if they want to delete type D elements. + virtual void vdelete(D) {} - void clear() - { - // Delete everything in the map. - //ScopedLock lock1(mModificationLock); // Lock this first! + ~InterthreadMap1() { ScopedLock lock(mLock); typename Map::iterator iter = mMap.begin(); while (iter != mMap.end()) { - delete iter->second; + vdelete(iter->second); ++iter; } mMap.clear(); } - ~InterthreadMap() { clear(); } - /** Non-blocking write. WARNING: This deletes any pre-existing element! @param key The index to write to. @param wData Pointer to data, not to be deleted until removed from the map. */ - void write(const K &key, D * wData) + void write(const K &key, D wData) { - //ScopedLock lock1(mModificationLock); // Lock this first! ScopedLock lock(mLock); typename Map::iterator iter = mMap.find(key); if (iter!=mMap.end()) { - delete iter->second; + vdelete(iter->second); iter->second = wData; } else { mMap[key] = wData; @@ -598,14 +477,14 @@ public: @param key Key to read from. @return Pointer at key or NULL if key not found, to be deleted by caller. */ - D* getNoBlock(const K& key, bool bRemove = true) + bool getNoBlock(const K& key, D &result, bool bRemove = true) { ScopedLock lock(mLock); typename Map::iterator iter = mMap.find(key); - if (iter==mMap.end()) return NULL; - D* retVal = iter->second; + if (iter==mMap.end()) return false; + result = iter->second; if (bRemove) { mMap.erase(iter); } - return retVal; + return true; } /** @@ -614,30 +493,20 @@ public: @param timeout The blocking timeout in ms. @return Pointer at key or NULL on timeout, to be deleted by caller. */ - D* get(const K &key, unsigned timeout, bool bRemove = true) + bool get(const K &key, D &result, unsigned timeout, bool bRemove = true) { - if (timeout==0) return getNoBlock(key,bRemove); + if (timeout==0) return getNoBlock(key,result,bRemove); ScopedLock lock(mLock); Timeval waitTime(timeout); - // (pat 8-2013) This commented out code suffered from a deadlock problem. - //typename Map::iterator iter = mMap.find(key); - //while ((iter==mMap.end()) && (!waitTime.passed())) { - // mWriteSignal.wait(mLock,waitTime.remaining()); - // iter = mMap.find(key); - //} - //if (iter==mMap.end()) return NULL; - //D* retVal = iter->second; - //mMap.erase(iter); - //return retVal; while (1) { typename Map::iterator iter = mMap.find(key); if (iter!=mMap.end()) { - D* retVal = iter->second; + result = iter->second; if (bRemove) { mMap.erase(iter); } - return retVal; + return true; } long remaining = waitTime.remaining(); - if (remaining < 2) { return NULL; } + if (remaining < 2) { return false; } mWriteSignal.wait(mLock,remaining); } } @@ -646,8 +515,9 @@ public: Blocking read with and element removal. @param key The key to read from. @return Pointer at key, to be deleted by caller. + This always returns true. */ - D* get(const K &key, bool bRemove = true) + bool get(const K &key, D &result, bool bRemove = true) { ScopedLock lock(mLock); typename Map::iterator iter = mMap.find(key); @@ -655,9 +525,9 @@ public: mWriteSignal.wait(mLock); iter = mMap.find(key); } - D* retVal = iter->second; + result = iter->second; if (bRemove) { mMap.erase(iter); } - return retVal; + return true; } @@ -669,11 +539,13 @@ public: */ bool remove(const K &key ) { - //ScopedLock lock(mModificationLock); - D* val = getNoBlock(key); - if (!val) return false; - delete val; - return true; + D val; + if (getNoBlock(key,val,true)) { + vdelete(val); + return true; + } else { + return false; + } } @@ -682,15 +554,11 @@ public: @param key Key to read from. @return Pointer at key or NULL if key not found. */ - D* readNoBlock(const K& key) const + D readNoBlock(const K& key) const { - return Unconst(this)->getNoBlock(key,false); - // (pat 8-2013) Lets use common code. - //D* retVal=NULL; - //ScopedLock lock(mLock); - //typename Map::const_iterator iter = mMap.find(key); - //if (iter!=mMap.end()) retVal = iter->second; - //return retVal; + D result = NULL; + Unconst(this)->getNoBlock(key,result,false); + return result; } /** @@ -699,21 +567,11 @@ public: @param timeout The blocking timeout in ms. @return Pointer at key or NULL on timeout. */ - D* read(const K &key, unsigned timeout) const + D read(const K &key, unsigned timeout) const { - return Unconst(this)->get(key,timeout,false); - // (pat 8-2013) This commented out code suffered from a deadlock problem. - //if (timeout==0) return readNoBlock(key); - //ScopedLock lock(mLock); - //Timeval waitTime(timeout); - //typename Map::const_iterator iter = mMap.find(key); - //while ((iter==mMap.end()) && (!waitTime.passed())) { - // mWriteSignal.wait(mLock,waitTime.remaining()); - // iter = mMap.find(key); - //} - //if (iter==mMap.end()) return NULL; - //D* retVal = iter->second; - //return retVal; + D result = NULL; + Unconst(this)->get(key,result,timeout,false); + return result; } /** @@ -721,32 +579,18 @@ public: @param key The key to read from. @return Pointer at key. */ - D* read(const K &key) const + D read(const K &key) const { - return Unconst(this)->get(key,false); - // (pat 8-2013) Lets use common code. - //ScopedLock lock(mLock); - //typename Map::const_iterator iter = mMap.find(key); - //while (iter==mMap.end()) { - // mWriteSignal.wait(mLock); - // iter = mMap.find(key); - //} - //D* retVal = iter->second; - //return retVal; + D result; + Unconst(this)->get(key,result,false); + return result; } // pat added. - unsigned size() const { return mMap.size(); } + unsigned size() const { ScopedLock(mLock); return mMap.size(); } - //Mutex &getModificationLock() { return mModificationLock; } - //void iterLock() { mModificationLock.lock(); } - //void iterUnlock() { mModificationLock.unlock(); } - -#if USE_SCOPED_ITERATORS - typedef ScopedIteratorTemplate,std::pair > ScopedIterator; -#endif // WARNING: These iterators are not intrinsically thread safe. - // Caller must use ScopiedIterator or the modification lock or enclose the entire iteration in some higher level lock. + // Caller must use ScopedIterator or the modification lock or enclose the entire iteration in some higher level lock. Mutex &qGetLock() { return mLock; } typedef typename Map::iterator iterator; typename Map::iterator begin() { return mMap.begin(); } @@ -755,11 +599,22 @@ public: +// (pat) The original InterthreadMap works only for pointers; now it is derived from the more general version above. +/** Thread-safe map of pointers to class D, keyed by class K. */ +template class InterthreadMap : public InterthreadMap1 +{ + void vdelete(D* foo) { delete foo; } +}; + + + + /** This class is used to provide pointer-based comparison in priority_queues. */ +// The priority_queue sorts the largest element to the 'top' of the priority_queue, which is the back of the underlying vector. template class PointerCompare { public: @@ -776,7 +631,8 @@ template class PointerCompare { Priority queue for interthread operations. Passes pointers to objects. */ -template , class Cmp = PointerCompare > class InterthreadPriorityQueue { +template , class Cmp = PointerCompare > class InterthreadPriorityQueue +{ protected: @@ -784,6 +640,14 @@ template , class Cmp = PointerCompare > cl mutable Mutex mLock; mutable Signal mWriteSignal; + // Assumes caller holds the lock. + T*ipqGet() { + if (!mQ.size()) { return NULL; } + T*result = mQ.top(); + mQ.pop(); + return result; + } + public: @@ -815,31 +679,45 @@ template , class Cmp = PointerCompare > cl T* readNoBlock() { ScopedLock lock(mLock); - T* retVal = NULL; - if (mQ.size()!=0) { - retVal = mQ.top(); - mQ.pop(); - } - return retVal; + return ipqGet(); } /** Blocking read. */ T* read() { ScopedLock lock(mLock); - T* retVal; while (mQ.size()==0) mWriteSignal.wait(mLock); - retVal = mQ.top(); - mQ.pop(); - return retVal; + return ipqGet(); + } + + T* read(unsigned timeout) + { + if (timeout==0) return readNoBlock(); + Timeval waitTime(timeout); + ScopedLock lock(mLock); + while (mQ.size()==0) { + long remaining = waitTime.remaining(); + // (pat) How high do we expect the precision here to be? I dont think they used precision timers, + // so dont try to wait if the remainder is just a few msecs. + if (remaining < 2) { return NULL; } + mWriteSignal.wait(mLock,remaining); + } + return ipqGet(); + } + + // pat added 4-2014. Return but do not pop the top element, if any, or NULL. + T* peek() + { + ScopedLock lock(mLock); + return mQ.size() ? mQ.top() : NULL; } /** Non-blocking write. */ void write(T* val) { - // (pat) 8-14: Taking out the threading problem fix temporarily for David to use in the field. - ScopedLock lock(mLock); - mQ.push(val); + { ScopedLock lock(mLock); + mQ.push(val); + } mWriteSignal.signal(); } diff --git a/InterthreadTest.cpp b/InterthreadTest.cpp index 552c1ee..6079593 100644 --- a/InterthreadTest.cpp +++ b/InterthreadTest.cpp @@ -1,5 +1,6 @@ /* * Copyright 2008 Free Software Foundation, Inc. +* Copyright 2014 Range Networks, Inc. * * * This software is distributed under the terms of the GNU Affero Public License. diff --git a/LinkedLists.cpp b/LinkedLists.cpp index 35a8541..94e2533 100644 --- a/LinkedLists.cpp +++ b/LinkedLists.cpp @@ -1,5 +1,6 @@ /* * Copyright 2008 Free Software Foundation, Inc. +* Copyright 2014 Range Networks, Inc. * * * This software is distributed under the terms of the GNU Affero Public License. diff --git a/LinkedLists.h b/LinkedLists.h index 95fdc27..b97d37e 100644 --- a/LinkedLists.h +++ b/LinkedLists.h @@ -1,7 +1,8 @@ /* * Copyright 2008 Free Software Foundation, Inc. +* Copyright 2014 Range Networks, Inc. * -* This software is distributed under multiple licenses; see the COPYING file in the main directory for licensing information for this specific distribuion. +* This software is distributed under multiple licenses; see the COPYING file in the main directory for licensing information for this specific distribution. * * This software is distributed under the terms of the GNU Affero Public License. * See the COPYING file in the main directory for details. diff --git a/LogTest.cpp b/LogTest.cpp index 20959a0..81fb9af 100644 --- a/LogTest.cpp +++ b/LogTest.cpp @@ -1,6 +1,7 @@ /* * Copyright 2009 Free Software Foundation, Inc. * Copyright 2010 Kestrel Signal Processing, Inc. +* Copyright 2014 Range Networks, Inc. * * * This software is distributed under the terms of the GNU Affero Public License. diff --git a/Logger.cpp b/Logger.cpp index 4a70b74..8d8c340 100644 --- a/Logger.cpp +++ b/Logger.cpp @@ -262,7 +262,6 @@ ostringstream& Log::get() } - // Allow applications to also pass in a filename. Filename should come from the database void gLogInitWithFile(const char* name, const char* level, int facility, char * LogFilePath) { @@ -301,9 +300,9 @@ void gLogInit(const char* name, const char* level, int facility) gPid = getpid(); // Pat added, tired of the syslog facility. - // Both the transceiver and OpenBTS use this same facility, but only OpenBTS/OpenNodeB may use this log file: + // Both the transceiver and OpenBTS use this same Logger class, but only RMSC/OpenBTS/OpenNodeB may use this log file: string str = gConfig.getStr("Log.File"); - if (gLogToFile==0 && str.length() && 0==strncmp(gCmdName,"Open",4)) { + if (gLogToFile==0 && str.length() && (0==strncmp(gCmdName,"Open",4) || 0==strncmp(gCmdName,"RMSC",4))) { const char *fn = str.c_str(); if (fn && *fn && strlen(fn)>3) { // strlen because a garbage char is getting in sometimes. gLogToFile = fopen(fn,"w"); // New log file each time we start. @@ -365,6 +364,7 @@ void LogGroup::LogGroupInit() for (unsigned g = 0; g < _NumberOfLogGroups; g++) { mDebugLevel[g] = 0; + mWatchLevel[g] = 0; } #if 0 @@ -377,26 +377,39 @@ void LogGroup::LogGroupInit() #endif } -static const char *LogGroupPrefix = "Log.Group."; +static const char*getNonEmptyStrIfDefined(string param) +{ + if (! gConfig.defines(param)) { return NULL; } + string result = gConfig.getStr(param); + // (pat) The "unconfig" command does not remove the value, it just gives it an empty value, so check for that. + return result.size() ? result.c_str() : NULL; +} // Set all the Log.Group debug levels based on database settings void LogGroup::setAll() { LOG(DEBUG); - string prefix = string(LogGroupPrefix); + string groupprefix = string("Log.Group."); + string watchprefix = string("Log.Watch."); for (unsigned g = 0; g < _NumberOfLogGroups; g++) { + { + string param = groupprefix + mGroupNames[g]; int level = 0; - string param = prefix + mGroupNames[g]; - if (gConfig.defines(param)) { - string levelName = gConfig.getStr(param); - // (pat) The "unconfig" command does not remove the value, it just gives it an empty value, so check for that. - if (levelName.size()) { - //LOG(DEBUG) << "Setting "<=LOG_##wLevel) #define IS_LOG_LEVEL(wLevel) (gCheckGroupLogLevel(LOG_GROUP,LOG_##wLevel) || gGetLoggingLevel(__FILE__)>=LOG_##wLevel) +#define IS_WATCH_LEVEL(wLevel) gCheckGroupWatchLevel(LOG_GROUP,LOG_##wLevel) #else +#define IS_WATCH_LEVEL(wLevel) (gGetLoggingLevel(__FILE__)>=LOG_##wLevel) #define IS_LOG_LEVEL(wLevel) (gGetLoggingLevel(__FILE__)>=LOG_##wLevel) #endif @@ -89,10 +91,11 @@ extern pid_t gPid; #define LOGVAR2(name,val) " " << name << "=" << (val) #define LOGVAR(var) (" " #var "=") << var #define LOGVARM(var) " " << &#var[1] << "=" << var // Strip the first char ("m") off the var name when printing. -#define LOGVARP(var) (" " #var "=(") << var <<")" // Put value in parens; used for classes. +#define LOGVARP2(name,val) (" " name "=(") << val <<")" // Put value in parens; used for classes. +#define LOGVARP(var) LOGVARP2(#var,var) // Put value in parens; used for classes. // (pat) 3-2014: Use (unsigned long) for LOGHEX so it can be used for pointers with 64-bit compiler. What a choke. -#define LOGHEX(var) (" " #var "=0x") << hex << ((unsigned long)var) << dec -#define LOGHEX2(name,val) " " << name << "=0x" << hex << ((unsigned long)(val)) << dec +#define LOGHEX(var) (" " #var "=0x") << std::hex << ((unsigned long long)var) << std::dec +#define LOGHEX2(name,val) " " << name << "=0x" << std::hex << ((unsigned long)(val)) << std::dec // These are kind of cheesy, but you can use for bitvector #define LOGBV2(name,val) " " << name << "=(" << val<<" size:"<= (int) level; } +static __inline__ bool gCheckGroupWatchLevel(LogGroup::Group group, unsigned level) { + assert(group < LogGroup::_NumberOfLogGroups); + //_LOG(DEBUG) << LOGVAR(group)<= (int) level; +} diff --git a/Makefile.am b/Makefile.am index 811f19d..b5b0f6c 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,6 +1,6 @@ # # Copyright 2008, 2009 Free Software Foundation, Inc. -# Copyright 2011, 2012 Range Networks, Inc. +# Copyright 2011, 2012, 2014 Range Networks, Inc. # # This software is distributed under the terms of the GNU Public License. # See the COPYING file in the main directory for details. @@ -22,7 +22,7 @@ include $(top_srcdir)/Makefile.common AM_CPPFLAGS = $(STD_DEFINES_AND_INCLUDES) -AM_CXXFLAGS = -Wall -O3 -g -ldl -lpthread +AM_CXXFLAGS = -Wall -O3 -g -ldl -lpthread -lsqlite3 EXTRA_DIST = \ example.config \ @@ -47,6 +47,8 @@ libcommon_la_SOURCES = \ Utils.cpp noinst_PROGRAMS = \ + UtilsTest \ + ThreadTest \ BitVectorTest \ InterthreadTest \ SelfDetectTest \ @@ -83,6 +85,9 @@ noinst_HEADERS = \ Logger.h \ sqlite3util.h +ThreadTest_SOURCES = ThreadTest.cpp +ThreadTest_LDADD = libcommon.la $(SQLITE_LA) + URLEncodeTest_SOURCES = URLEncodeTest.cpp URLEncodeTest_LDADD = libcommon.la @@ -123,6 +128,9 @@ LogTest_LDADD = libcommon.la $(SQLITE_LA) F16Test_SOURCES = F16Test.cpp +UtilsTest_SOURCES = UtilsTest.cpp +UtilsTest_LDADD = libcommon.la + MOSTLYCLEANFILES += testSource testDestination diff --git a/MemoryLeak.h b/MemoryLeak.h index 1f7bcd6..c7ae4f9 100644 --- a/MemoryLeak.h +++ b/MemoryLeak.h @@ -1,10 +1,10 @@ /* -* Copyright 2011 Range Networks, Inc. +* Copyright 2011, 2014 Range Networks, Inc. * All Rights Reserved. * * This software is distributed under multiple licenses; * see the COPYING file in the main directory for licensing -* information for this specific distribuion. +* information for this specific distribution. * * This use of this software may be subject to additional restrictions. * See the LEGAL file in the main directory for details. diff --git a/README b/README new file mode 100644 index 0000000..7d59dc1 --- /dev/null +++ b/README @@ -0,0 +1,16 @@ +This directory contains common-use classes, most of which are not specific to GSM. + +``` +Vector A vector class (NOT std::vector<>) that supports aliased subvectors. Not resizable. +BitVector Bit-indexable vectors based on Vector. +Interthread A set of C++ wrappers for pthread facilities. +Sockets A set of C++ wrappers for Unix sockets. +Timeval A C++ wraper for struct timeval. +LinkLists Classes for simple linked lists of pointers. +Logger A logging interface based on syslogd. +Configuration A key-value configuration table. +Regexp A C++ wrapper on stdlib regular expressions. +``` + +Do "make tests" to build a series of unit tests for these classes. + diff --git a/README.common b/README.common deleted file mode 100644 index 9aecc16..0000000 --- a/README.common +++ /dev/null @@ -1,15 +0,0 @@ -This directory contains common-use classes, most of which are not specific to GSM. - -Vector A vector class (NOT std::vector<>) that supports - aliased subvectors. Not resizable. -BitVector Bit-indexable vectors based on Vector. -Interthread A set of C++ wrappers for pthread facilities. -Sockets A set of C++ wrappers for Unix sockets. -Timeval A C++ wraper for struct timeval. -LinkLists Classes for simple linked lists of pointers. -Logger A logging interface based on syslogd. -Configuration A key-value configuration table. -Regexp A C++ wrapper on stdlib regular expressions. - -Do "make tests" to build a series of unit tests for these classes. - diff --git a/Regexp.h b/Regexp.h index 3ff1e97..a190950 100644 --- a/Regexp.h +++ b/Regexp.h @@ -1,5 +1,6 @@ /* * Copyright 2008 Free Software Foundation, Inc. +* Copyright 2014 Range Networks, Inc. * * This software is distributed under the terms of the GNU Affero Public License. * See the COPYING file in the main directory for details. diff --git a/RegexpTest.cpp b/RegexpTest.cpp index 748be49..84b2fc3 100644 --- a/RegexpTest.cpp +++ b/RegexpTest.cpp @@ -1,5 +1,6 @@ /* * Copyright 2008 Free Software Foundation, Inc. +* Copyright 2014 Range Networks, Inc. * * * This software is distributed under the terms of the GNU Affero Public License. diff --git a/Reporting.cpp b/Reporting.cpp index 6ad95e3..b77c4e0 100644 --- a/Reporting.cpp +++ b/Reporting.cpp @@ -1,6 +1,6 @@ /**@file Module for performance-reporting mechanisms. */ /* -* Copyright 2012, 2013 Range Networks, Inc. +* Copyright 2012, 2013, 2014 Range Networks, Inc. * * This software is distributed under the terms of the GNU Affero Public License. * See the COPYING file in the main directory for details. diff --git a/Reporting.h b/Reporting.h index f5341cd..c6bbc08 100644 --- a/Reporting.h +++ b/Reporting.h @@ -1,6 +1,6 @@ /**@file Module for performance-reporting mechanisms. */ /* -* Copyright 2012, 2013 Range Networks, Inc. +* Copyright 2012, 2013, 2014 Range Networks, Inc. * * This software is distributed under the terms of the GNU Affero Public License. * See the COPYING file in the main directory for details. @@ -98,6 +98,7 @@ class ReportingTable { /** Periodically triggers ReportingTable::commit(). */ void* reportingBatchCommitter(void*); +extern ReportingTable gReports; #endif diff --git a/ReportingTest.cpp b/ReportingTest.cpp index a0d874b..2f262bc 100644 --- a/ReportingTest.cpp +++ b/ReportingTest.cpp @@ -1,5 +1,5 @@ /* -* Copyright 2012 Range Networks, Inc. +* Copyright 2012, 2014 Range Networks, Inc. * * This software is distributed under the terms of the GNU Affero Public License. * See the COPYING file in the main directory for details. diff --git a/ScalarTypes.h b/ScalarTypes.h index 21fa66d..a31ec69 100644 --- a/ScalarTypes.h +++ b/ScalarTypes.h @@ -1,10 +1,10 @@ /* -* Copyright 2011 Range Networks, Inc. +* Copyright 2011, 2014 Range Networks, Inc. * All Rights Reserved. * * This software is distributed under multiple licenses; * see the COPYING file in the main directory for licensing -* information for this specific distribuion. +* information for this specific distribution. * * This use of this software may be subject to additional restrictions. * See the LEGAL file in the main directory for details. diff --git a/SelfDetect.cpp b/SelfDetect.cpp index 54a6276..dd99d25 100644 --- a/SelfDetect.cpp +++ b/SelfDetect.cpp @@ -1,6 +1,6 @@ /**@file Module for preventing two instances of a program from running. */ /* -* Copyright 2013 Range Networks, Inc. +* Copyright 2013, 2014 Range Networks, Inc. * * This software is distributed under the terms of the GNU Affero Public License. * See the COPYING file in the main directory for details. @@ -96,6 +96,7 @@ void SelfDetect::RegisterProgram(const char *argv0) // openbts: NOTICE 3031243584 05:03:50.4 OpenBTS.cpp:165:startTransceiver: starting transceiver ./transceiver w/ 1 ARFCNs and Args: // openbts: NOTICE 3073816320 05:03:50.4 SelfDetect.cpp:98:Exit: *** Terminating ./OpenBTS // openbts: NOTICE 3073816320 05:03:50.4 SelfDetect.cpp:105:Exit: *** Removing pid file /var/run/OpenBTS.pid + case SIGCONT: case SIGCHLD: break; default: diff --git a/SelfDetect.h b/SelfDetect.h index ce9fb8c..ccf47fa 100644 --- a/SelfDetect.h +++ b/SelfDetect.h @@ -1,10 +1,10 @@ /* -* Copyright 2013 Range Networks, Inc. +* Copyright 2013, 2014 Range Networks, Inc. * All Rights Reserved. * * This software is distributed under multiple licenses; * see the COPYING file in the main directory for licensing -* information for this specific distribuion. +* information for this specific distribution. * * This use of this software may be subject to additional restrictions. * See the LEGAL file in the main directory for details. diff --git a/SelfDetectTest.cpp b/SelfDetectTest.cpp index aa66b23..03af9f1 100644 --- a/SelfDetectTest.cpp +++ b/SelfDetectTest.cpp @@ -1,5 +1,5 @@ /* -* Copyright 2013 Range Networks, Inc. +* Copyright 2013, 2014 Range Networks, Inc. * * This software is distributed under the terms of the GNU Affero Public License. * See the COPYING file in the main directory for details. diff --git a/Sockets.cpp b/Sockets.cpp index 47676ff..8464616 100644 --- a/Sockets.cpp +++ b/Sockets.cpp @@ -1,5 +1,6 @@ /* * Copyright 2008, 2010, 2014 Free Software Foundation, Inc. +* Copyright 2014 Range Networks, Inc. * * * This software is distributed under the terms of the GNU Affero Public License. diff --git a/Sockets.h b/Sockets.h index f607f7c..213fcb7 100644 --- a/Sockets.h +++ b/Sockets.h @@ -1,5 +1,6 @@ /* * Copyright 2008, 2010 Free Software Foundation, Inc. +* Copyright 2014 Range Networks, Inc. * * This software is distributed under the terms of the GNU Affero Public License. * See the COPYING file in the main directory for details. diff --git a/SocketsTest.cpp b/SocketsTest.cpp index e8e8082..ef2fddf 100644 --- a/SocketsTest.cpp +++ b/SocketsTest.cpp @@ -1,5 +1,6 @@ /* * Copyright 2008 Free Software Foundation, Inc. +* Copyright 2014 Range Networks, Inc. * * * This software is distributed under the terms of the GNU Affero Public License. diff --git a/ThreadTest.cpp b/ThreadTest.cpp new file mode 100644 index 0000000..dfe7897 --- /dev/null +++ b/ThreadTest.cpp @@ -0,0 +1,140 @@ +/* +* Copyright 2014 Range Networks, Inc. +* +* This software is distributed under the terms of the GNU Affero Public License. +* See the COPYING file in the main directory for details. +* +* This use of this software may be subject to additional restrictions. +* See the LEGAL file in the main directory for details. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + +*/ + +#include +#include +#include +#include +#include "Threads.h" +#include "Utils.h" +using namespace Utils; + +// We must have a gConfig now to include BitVector. +#include "Configuration.h" +ConfigurationTable gConfig; + +// pat 6-2014: Check how many threads we can create. + +#define NUM_THREADS 100000 + +// Overwrite Thread::start() so we can see what is going on. + +class ThreadTest { + + protected: + + pthread_t mThread; + pthread_attr_t mAttrib; + // FIXME -- Can this be reduced now? + size_t mStackSize; + + + public: + + /** Create a thread in a non-running state. */ + ThreadTest(size_t wStackSize = (65536*4)):mThread((pthread_t)0) { + pthread_attr_init(&mAttrib); // (pat) moved this here. + mStackSize=wStackSize; + } + + /** + Destroy the Thread. + It should be stopped and joined. + */ + // (pat) If the Thread is destroyed without being started, then mAttrib is undefined. Oops. + ~ThreadTest() { pthread_attr_destroy(&mAttrib); } + + + /** Start the thread on a task. */ + void start( void*(*task)(void*), void *arg) { + assert(mThread==((pthread_t)0)); + int res; + res = pthread_attr_setstacksize(&mAttrib, mStackSize); + if (res) { fprintf(stderr,"pthread_setstacksize(%u) failed: error=%d %s\n",mStackSize,res,strerror(res)); } + assert(!res); + //res = pthread_create(&mThread, &mAttrib, &thread_main, p); + res = pthread_create(&mThread, &mAttrib, task, arg); + if (res) { LOG(ALERT) << "pthread_create failed, error:" <start( (void*(*)(void*)) serviceLoop,&i); + if (i && i % 1000 == 0) { + printf("%d\n",i); fflush(stdout); + printf("Created %d (%d total) threads in %.2g seconds mem=%lldM\n",1000,i,timef()-chunktime,totalmem/1000000); + chunktime = timef(); + } + } + + double elapsed = timef() - start; + printf("Created %d threads in %.2g seconds\n",NUM_THREADS,elapsed); +} diff --git a/Threads.cpp b/Threads.cpp index 191d518..1247494 100644 --- a/Threads.cpp +++ b/Threads.cpp @@ -1,5 +1,6 @@ /* * Copyright 2008, 2014 Free Software Foundation, Inc. +* Copyright 2014 Range Networks, Inc. * * * This software is distributed under the terms of the GNU Affero Public License. @@ -256,9 +257,17 @@ void Thread::start(void *(*task)(void*), void *arg) p->task = task; p->arg = arg; res = pthread_create(&mThread, &mAttrib, &thread_main, p); + // (pat) Note: the error is returned and is not placed in errno. + if (res) { LOG(ALERT) << "pthread_create failed, error:" <. + +*/ #include #include diff --git a/URLEncode.h b/URLEncode.h index 558ced9..ff5fc8c 100644 --- a/URLEncode.h +++ b/URLEncode.h @@ -1,5 +1,6 @@ /* * Copyright 2011 Free Software Foundation, Inc. +* Copyright 2014 Range Networks, Inc. * * * This software is distributed under the terms of the GNU Affero Public License. diff --git a/URLEncodeTest.cpp b/URLEncodeTest.cpp index fa20744..0e71d3d 100644 --- a/URLEncodeTest.cpp +++ b/URLEncodeTest.cpp @@ -1,3 +1,26 @@ +/* +* Copyright 2014 Range Networks, Inc. +* +* This software is distributed under the terms of the GNU Affero Public License. +* See the COPYING file in the main directory for details. +* +* This use of this software may be subject to additional restrictions. +* See the LEGAL file in the main directory for details. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + +*/ #include "URLEncode.h" #include diff --git a/UnixSignal.h b/UnixSignal.h index cb50c17..2c3f29e 100644 --- a/UnixSignal.h +++ b/UnixSignal.h @@ -4,7 +4,7 @@ * * This software is distributed under multiple licenses; * see the COPYING file in the main directory for licensing -* information for this specific distribuion. +* information for this specific distribution. * * This use of this software may be subject to additional restrictions. * See the LEGAL file in the main directory for details. diff --git a/Utils.cpp b/Utils.cpp index 0a85d19..92bcf06 100644 --- a/Utils.cpp +++ b/Utils.cpp @@ -4,7 +4,7 @@ * * This software is distributed under multiple licenses; * see the COPYING file in the main directory for licensing -* information for this specific distribuion. +* information for this specific distribution. * * This use of this software may be subject to additional restrictions. * See the LEGAL file in the main directory for details. @@ -41,8 +41,10 @@ int RefCntBase::decRefCnt() } // Must not keep locked during the delete, since the Mutex itself will be deleted. // The typeid(this).name() doesnt add anything because it is just the name of the class here, not the derived class. LOG(DEBUG) <<" "<<(void*)this <<" " <= 0); mRefCnt++; @@ -555,4 +558,19 @@ string uintToString(uint32_t x) os << hex << x; return os.str(); } + + +// Return the first n lines of a string. +string firstlines(string msgstr, int n) { // n must be >=1 + size_t pos = msgstr.find('\n'); + if (pos < msgstr.size()) pos++; + //printf("firstlines pos=%d\n",(int)pos); + while (--n > 0 && pos < msgstr.size()) { + pos = msgstr.find('\n',pos); + //printf("firstlines n=%d pos=%d\n",n,(int)pos); + if (pos < msgstr.size()) pos++; + } + //printf("firstlines return n=%d pos=%d\n",n,(int)pos); + return msgstr.substr(0,pos); +} }; diff --git a/Utils.h b/Utils.h index 7f63596..67c2752 100644 --- a/Utils.h +++ b/Utils.h @@ -4,7 +4,7 @@ * * This software is distributed under multiple licenses; * see the COPYING file in the main directory for licensing -* information for this specific distribuion. +* information for this specific distribution. * * This use of this software may be subject to additional restrictions. * See the LEGAL file in the main directory for details. @@ -194,9 +194,11 @@ extern void stringToUint(string strRAND, uint64_t *hRAND, uint64_t *lRAND); extern string uintToString(uint64_t h, uint64_t l); extern string uintToString(uint32_t x); +//template class RefCntPointer; // The class is created with a RefCnt of 0. The caller must assign the constructed result to a pointer // of type RefCntPointer. When the last RefCntPointer is freed, this struct is too. class RefCntBase { + template friend class RefCntPointer; Mutex mRefMutex; mutable short mRefCnt; // signed, not unsigned! int setRefCnt(int val) { return mRefCnt = val; } @@ -206,14 +208,20 @@ class RefCntBase { RefCntBase(RefCntBase &) { assert(0); } RefCntBase(const RefCntBase &) { assert(0); } RefCntBase operator=(RefCntBase &) {assert(0); mRefCnt = 0; return *this; } + int decRefCnt(); // Only RefCntPointer is permitted to use incRefCnt and decRefCnt. + void incRefCnt(); public: virtual ~RefCntBase(); RefCntBase() : mRefCnt(0) {} int getRefCnt() const { return mRefCnt; } - int decRefCnt(); - void incRefCnt(); }; +// This is basically the same as a C++11 shared_ptr, but we cannot use C++ 11 yet. +// The basic idea is that once you put an object into a RefCntPointer, then destruction of that +// object is controlled by and assured by RefCntPointer using reference counts; when the last +// RefCntPointer referring to the object is destroyed, the object is too. +// You can use RefCntPointer similarly to an object* for most data-access purposes. +// The auto-destruction should be optional - there should be a version that just maintains reference counts for you. // Semantics: // SomeDescendentOfRefCntBase foo; // RefCntPointer ptrToFoo; @@ -244,7 +252,8 @@ class RefCntPointer { // The operator=(Type*) is called if the argument is NULL, so we dont need int. //Type* operator=(int value) { assert(value == 0); rcDec(); rcPointer = 0; return rcPointer; } // We increment before decrement if possible so that a = a; does not crash. - RefCntPointer& operator=(RefCntPointer &other) { other.rcInc(); rcDec(); rcPointer = other.rcPointer; return *this; } + RefCntPointer& operator=(RefCntPointer other) { other.rcInc(); rcDec(); rcPointer = other.rcPointer; return *this; } + // The old is the previous value of this pointer. We do not decrement the refcnt in the other that we are taking charge of. RefCntPointer& operator=(Type* other) { Type *old = rcPointer; rcPointer = other; rcInc(); if (old) {old->decRefCnt();} return *this; } bool operator==(const RefCntPointer &other) const { return rcPointer == other.rcPointer; } bool operator==(const Type* other) const { return rcPointer == other; } @@ -265,6 +274,8 @@ class RefCntPointer { bool isNULL() const { return self() == NULL; } }; +extern string firstlines(string msgstr, int n=2); + }; // namespace using namespace Utils; diff --git a/UtilsTest.cpp b/UtilsTest.cpp new file mode 100644 index 0000000..2667944 --- /dev/null +++ b/UtilsTest.cpp @@ -0,0 +1,71 @@ +#include +#include +#include "Configuration.h" +#include "Utils.h" +ConfigurationTable gConfig; // Needed for logger. +using namespace std; + + +struct foo : public RefCntBase { + string id; + foo(string wid) : id(wid) { printf("create foo %s %p\n",id.c_str(),this); } + ~foo() { printf("delete foo %s %p\n",id.c_str(),this); } +}; + +typedef RefCntPointer fooref; + +RefCntPointer refize(foo*f) +{ + fooref ref(f); + return ref; +} + +void test1() // Basic test. +{ + foo *b = new foo("b"); + fooref bref(b); + bref.free(); // Should free b. + +} + +void test2() // assignment +{ + foo *c = new foo("c"); + fooref cref = refize(c); + + foo *d = new foo("d"); + fooref dref = d; + fooref dref2 = d; + + dref = c; + printf("here\n"); + // d and c deleted when test2 returns. +} + +void test3() // assignment +{ + foo *c = new foo("c"); + fooref cref = refize(c); + + foo *d = new foo("d"); + fooref dref = d; + + dref = c; + printf("here\n"); + // d and c deleted when test2 returns. +} + +void refcntpointertest() +{ + test1(); + test2(); + test3(); +} + + + +int main(int argc, char **argv) +{ + printf("Utils Test starting.\n"); + refcntpointertest(); +} diff --git a/Variables.cpp b/Variables.cpp index 5c6624d..0073dbd 100644 --- a/Variables.cpp +++ b/Variables.cpp @@ -4,7 +4,7 @@ * * This software is distributed under multiple licenses; * see the COPYING file in the main directory for licensing -* information for this specific distribuion. +* information for this specific distribution. * * This use of this software may be subject to additional restrictions. * See the LEGAL file in the main directory for details. diff --git a/Vector.h b/Vector.h index b4422d3..91b850b 100644 --- a/Vector.h +++ b/Vector.h @@ -1,6 +1,7 @@ /**@file Simplified Vector template with aliases. */ /* * Copyright 2008 Free Software Foundation, Inc. +* Copyright 2014 Range Networks, Inc. * * This software is distributed under the terms of the GNU Affero Public License. * See the COPYING file in the main directory for details. diff --git a/VectorTest.cpp b/VectorTest.cpp index 4065968..9100f46 100644 --- a/VectorTest.cpp +++ b/VectorTest.cpp @@ -1,5 +1,6 @@ /* * Copyright 2008 Free Software Foundation, Inc. +* Copyright 2014 Range Networks, Inc. * * * This software is distributed under the terms of the GNU Affero Public License. diff --git a/sqlite3util.cpp b/sqlite3util.cpp index d6d8ace..f40b129 100644 --- a/sqlite3util.cpp +++ b/sqlite3util.cpp @@ -1,10 +1,29 @@ /* * Copyright 2010 Kestrel Signal Processing, Inc. -* All rights reserved. +* Copyright 2014 Range Networks, Inc. +* +* This software is distributed under the terms of the GNU Affero Public License. +* See the COPYING file in the main directory for details. +* +* This use of this software may be subject to additional restrictions. +* See the LEGAL file in the main directory for details. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + */ -#include "sqlite3.h" #include "sqlite3util.h" #include "Logger.h" @@ -342,17 +361,21 @@ bool sqlite3_single_lookup(sqlite3* DB, const char* tableName, bool sqlite_set_attr(sqlite3*db,const char *attr_name,const char*attr_value) { if (! sqlite3_command(db,"CREATE TABLE IF NOT EXISTS ATTR_TABLE (ATTR_NAME TEXT PRIMARY KEY, ATTR_VALUE TEXT)")) { - const char *fn = sqlite3_db_filename(db,"main"); + // (mike) 2014-06: to free ourselves of the in-tree sqlite3 code, the system library must be used. + // However, sqlite3_db_filename is not available in Ubuntu 12.04. Removing dependence for now. + //const char *fn = sqlite3_db_filename(db,"main"); // (pat) You must not call LOG() from this file because it causes infinite recursion through gGetLoggingLevel and ConfigurationTable::lookup - _LOG(WARNING) << "Could not create ATTR_TABLE in database file " <<(fn?fn:""); + _LOG(WARNING) << "Could not create ATTR_TABLE in database file ";// <<(fn?fn:""); return false; } char query[100]; snprintf(query,100,"REPLACE INTO ATTR_TABLE (ATTR_NAME,ATTR_VALUE) VALUES('%s','%s')",attr_name,attr_value); if (! sqlite3_command(db,query)) { - const char *fn = sqlite3_db_filename(db,"main"); + // (mike) 2014-06: to free ourselves of the in-tree sqlite3 code, the system library must be used. + // However, sqlite3_db_filename is not available in Ubuntu 12.04. Removing dependence for now. + //const char *fn = sqlite3_db_filename(db,"main"); // (pat) You must not call LOG() from this file because it causes infinite recursion through gGetLoggingLevel and ConfigurationTable::lookup - _LOG(WARNING) << "Could not set attribute: "<. + +*/ + #ifndef SQLITE3UTIL_H #define SQLITE3UTIL_H