← Back to team overview

nrtb-core team mailing list archive

[Merge] lp:~fpstovall/nrtb/bk2thefuture into lp:nrtb

 

Rick Stovall has proposed merging lp:~fpstovall/nrtb/bk2thefuture into lp:nrtb.

Requested reviews:
  NRTB Core (nrtb-core): code merge

For more details, see:
https://code.launchpad.net/~fpstovall/nrtb/bk2thefuture/+merge/179547

This branch moves our development focus back to C++ (C++11). In preparing for this, the following has been accomplished:

   * The D code has been moved to the "obsolete" directory.
   * The needed C++ common libs have been restored from the obsolete directory.
   * Threading now uses the C++11 model; the old thread class has been removed.
   * The work_queue template has been replaced by cleaner thread safe queues.
   * The tcp_server_socket factory has been redesigned to use a producer/consumer model.
   * There is a new logger class which is simple and fast.
   * All the common code has been reviewed, formatted neatly, and updated to C++11 standards.

The upshot of all this is that we are closer to a working alpha phase release now than at any time in the last couple of years. I intend to allow this to rest until Sunday, at which time I will promoted it to main branch if there are no objections.
-- 
https://code.launchpad.net/~fpstovall/nrtb/bk2thefuture/+merge/179547
Your team NRTB Core is requested to review the proposed merge of lp:~fpstovall/nrtb/bk2thefuture into lp:nrtb.
=== renamed directory 'obsolete/Cpp' => 'cpp'
=== modified file 'cpp/common/Makefile'
--- obsolete/Cpp/common/Makefile	2011-12-14 19:24:03 +0000
+++ cpp/common/Makefile	2013-08-09 21:47:12 +0000
@@ -16,7 +16,7 @@
 #
 #***********************************************
 
-lib: ./lib/nrtb_common.a ./lib/nrtb_communication.a
+lib: ./lib/nrtb_common.a 
 
 ./lib/nrtb_common.a:
 	@echo "============= building common libs ==============="
@@ -24,9 +24,6 @@
 	@ar -r ./lib/nrtb_common.a ./obj/*.o
 	@echo "============= common libs complete ==============="
 
-./lib/nrtb_communication.a:
-	@cd comm_handlers; make lib
-
 modules:
 	@echo "============= building common modules ==============="
 	@make doit
@@ -36,14 +33,13 @@
 	@echo "============= cleaning common libs ==============="
 	@make action=clean doit
 	@rm -fv ./obj/* ./lib/* ./include/*
-	@cd comm_handlers; make clean
 	@echo "========== common lib cleanup complete ==========="
 
 doit:
 	@cd common_rl; make ${action}
 	@cd point; make ${action}
 	@cd timer; make ${action}
-	@cd threads; make ${action}
+	@cd abs_queue; make ${action}
 	@cd circular_queue; make ${action}
 	@cd linear_queue; make ${action}
 	@cd sockets; make ${action}
@@ -51,6 +47,9 @@
 	@cd singleton; make ${action}
 	@cd logger; make ${action}
 	@cd confreader; make ${action}
-	@cd GPB; make ${action}
-	@cd transceiver; make ${action}
+
+# --- the following are obsolete and may be removed later.
+#	@cd threads; make ${action}
+#	@cd GPB; make ${action}
+#	@cd transceiver; make ${action}
 	

=== added directory 'cpp/common/abs_queue'
=== added file 'cpp/common/abs_queue/Makefile'
--- cpp/common/abs_queue/Makefile	1970-01-01 00:00:00 +0000
+++ cpp/common/abs_queue/Makefile	2013-08-09 21:47:12 +0000
@@ -0,0 +1,33 @@
+#***********************************************
+#This file is part of the NRTB project (https://launchpad.net/nrtb).
+#
+#    NRTB is free software: you can redistribute it and/or modify
+#    it under the terms of the GNU General Public License as published by
+#    the Free Software Foundation, either version 3 of the License, or
+#    (at your option) any later version.
+#
+#    NRTB 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 General Public License for more details.
+#
+#    You should have received a copy of the GNU General Public License
+#    along with NRTB.  If not, see <http://www.gnu.org/licenses/>.
+#
+#***********************************************
+
+switches=-std=gnu++11 -D _GLIBCXX_USE_SCHED_YIELD -D _GLIBCXX_USE_NANOSLEEP
+
+lib:	abs_queue_test
+	@./abs_queue_test
+	@cp -v abs_queue.h ../include
+	@echo build complete
+
+abs_queue_test:	abs_queue.h abs_queue_test.cpp
+	@rm -f abs_queue_test
+	g++ -c abs_queue_test.cpp -I../include ${switches}
+	g++ -o abs_queue_test abs_queue_test.o -lpthread ${switches}
+
+clean:
+	@rm -rvf *.o abs_queue_test ../include/abs_queue.h *.log ../obj/abs_queue.o
+	@echo all objects and executables have been erased.

=== added file 'cpp/common/abs_queue/abs_queue.h'
--- cpp/common/abs_queue/abs_queue.h	1970-01-01 00:00:00 +0000
+++ cpp/common/abs_queue/abs_queue.h	2013-08-09 21:47:12 +0000
@@ -0,0 +1,187 @@
+/***********************************************
+ This file is part of the NRTB project (https://*launchpad.net/nrtb).
+
+ NRTB is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ NRTB 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with NRTB.  If not, see <http://www.gnu.org/licenses/>.
+
+ **********************************************/
+
+#ifndef nrtb_abs_queue_h
+#define nrtb_abs_queue_h
+
+#include <common.h>
+#include <atomic>
+#include <mutex>
+#include <condition_variable>
+
+namespace nrtb
+{
+
+/********************************************************
+ * The abs_queue template is designed for use with
+ * the classic producer/consumer thread management model.
+ * The producer uses abs_queue::push() to put items
+ * in the queue as they become available, and the consumer
+ * thread calls abs_queue::park() when it is ready
+ * for the next item to work.
+ * 
+ * This queue will expand as needed. Constrast this with
+ * the circular_queue, which is of a fixed size and will 
+ * drop older data when full
+ *
+ * Common uses would be for buffering outgoing or incomming
+ * messages from a communications channel, providing a feed
+ * queue for parallel threads to make full use of multi-core
+ * processors, or any case where one or more threads are
+ * passing data to another set of threads.
+********************************************************/
+template <class T, class queue_t>
+class abs_queue
+{
+public:
+  class queue_not_ready: public nrtb::base_exception {};
+    
+    /// Total number of items placed in queue.
+    std::atomic<int> in_count {0};
+    /// Total number of items read from queue.
+    std::atomic<int> out_count {0};
+
+    /*********************************************
+      * creates the queue with the specified
+      * number of elements. 
+    *********************************************/
+    abs_queue();
+
+    /*********************************************
+      * releases all items in the queue
+    *********************************************/
+    ~abs_queue();
+
+    /*********************************************
+      * Puts an item in the queue.
+    *********************************************/
+    void push(T item);
+
+    /*********************************************
+      * Pops the next item off the queue, blocking
+      * if needed until an item becomes available.
+    *********************************************/
+    T pop();
+
+    /*********************************************
+     * puts the queue in shutdown mode.
+    *********************************************/
+    void shutdown();
+
+    // returns the number of items in the queue
+    int size();
+    // resizes the buffer, may cause data loss
+    void resize(int newsize);
+    // clears the buffer, data will be discarded.
+    void clear();
+
+protected:
+
+    queue_t buffer;
+    std::mutex mylock;
+    std::condition_variable signal;
+    bool ready {true};
+};
+
+template <class T, class queue_t>
+abs_queue<T,queue_t>::abs_queue()
+{
+};
+
+template <class T, class queue_t>
+abs_queue<T,queue_t>::~abs_queue()
+{
+  shutdown();
+};
+
+template <class T, class queue_t>
+void abs_queue<T,queue_t>::push(T item)
+{
+  if (ready)
+  {
+    in_count++;
+    {
+      std::unique_lock<std::mutex> lock(mylock);
+      buffer.push(item);
+    }
+    signal.notify_one();
+  }
+  else 
+  {
+    queue_not_ready e;
+    throw e;
+  }
+};
+
+template <class T, class queue_t>
+T abs_queue<T,queue_t>::pop()
+{
+  std::unique_lock<std::mutex> lock(mylock);
+  while (buffer.empty() && ready)
+    signal.wait(lock);
+  if (ready)
+  {
+    T returnme = buffer.front();
+    buffer.pop();
+    out_count++;
+    return returnme;
+  }
+  else
+  {
+    queue_not_ready e;
+    throw e;
+  };
+};
+
+template <class T, class queue_t>
+void abs_queue<T,queue_t>::shutdown()
+{
+  try
+  {
+    std::unique_lock<std::mutex> lock(mylock);
+    ready = false;
+    while (buffer.size()) { buffer.pop(); }
+    signal.notify_all();
+  }
+  catch (...) {}  
+}
+
+template <class T, class queue_t>
+int abs_queue<T,queue_t>::size()
+{
+  std::unique_lock<std::mutex> lock(mylock);
+  return buffer.size();
+};
+
+template <class T, class queue_t>
+void abs_queue<T,queue_t>::resize(int newsize)
+{
+  std::unique_lock<std::mutex> lock(mylock);
+  buffer.set_capacity(newsize);
+};
+
+template <class T, class queue_t>
+void abs_queue<T,queue_t>::clear()
+{
+  std::unique_lock<std::mutex> lock(mylock);
+  while (buffer.size()) buffer.pop();
+};
+
+} // namespace nrtb
+
+#endif //nrtb_abs_queue_h//

=== added file 'cpp/common/abs_queue/abs_queue_test.cpp'
--- cpp/common/abs_queue/abs_queue_test.cpp	1970-01-01 00:00:00 +0000
+++ cpp/common/abs_queue/abs_queue_test.cpp	2013-08-09 21:47:12 +0000
@@ -0,0 +1,120 @@
+/***********************************************
+ This file is part of the NRTB project (https://*launchpad.net/nrtb).
+ 
+ NRTB is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+ 
+ NRTB 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 General Public License for more details.
+ 
+ You should have received a copy of the GNU General Public License
+ along with NRTB.  If not, see <http://www.gnu.org/licenses/>.
+ 
+ **********************************************/
+
+#include <unistd.h> // included for usleep()
+#include <string>
+#include <iostream>
+#include "abs_queue.h"
+#include <memory>
+#include <atomic>
+#include <future>
+#include <queue>
+
+using namespace nrtb;
+using namespace std;
+
+typedef abs_queue<int,std::queue<int>> test_queue;
+typedef shared_ptr<test_queue> queue_p;
+
+int consumer_task(string name, queue_p input)
+{
+  bool ready {true};
+  int count {0};
+  try
+  {
+    while (ready)
+    {
+      int num = input->pop();
+      count++;
+      usleep(1);	  
+    }
+  }
+  catch (...) 
+  { 
+    // exit if we get any exception.
+    ready = false; 
+  };
+  return count;
+};
+
+int main()
+{
+  cout << "***** abs_queue unit test ******" << endl;
+  /************************************************
+   * Load queue and then cook it down...
+   ***********************************************/
+  // make and load a queue
+  queue_p q1(new test_queue());
+  for (int i=0; i<100; i++)
+  {
+    q1->push(i);
+  };
+  // the queue should be loaded with 0-99
+  // attach a thread and process it.
+  auto t1 = async(launch::async,consumer_task,"task 1",q1);
+  while (q1->size()) usleep(100);
+  cout << "cp 1 " 
+    << q1->in_count << ":"
+    << q1->out_count << endl;
+  /************************************************
+   * now that the preload is exhasted, shove items
+   * in one at a time to make sure each is picked
+   * up correctly.
+   ***********************************************/
+  for (int i=200; i<225; i++)
+  {
+    q1->push(i);
+    usleep(100);
+  };
+  cout << "cp 2 " 
+    << q1->in_count << ":"
+    << q1->out_count << endl;
+  /************************************************
+   * Last check; attach a second thread to the queue
+   * and make sure both are servicing it.
+   ***********************************************/
+  auto t2 = async(launch::async,consumer_task,"task 2",q1);
+  for (int i=300; i<325; i++)
+  {
+    q1->push(i);
+  };
+  while (q1->size()) usleep(100);
+  // shut it all down
+  q1->shutdown();
+  // important numbers
+  int t1_count = t1.get();
+  int t2_count = t2.get();
+  int q1_in = q1->in_count;
+  int q1_out = q1->out_count;
+  // release the queues.
+  q1.reset();
+  // do some reporting.
+  cout << "cp 3 " 
+    << q1_in << ":" << q1_out
+    << " t1=" << t1_count
+    << " t2=" << t2_count
+    << endl;
+  bool passed = (q1_in == q1_out) 
+    and (q1_out == (t1_count + t2_count));
+  cout << "***** abs_queue TEST "
+    << (passed ? "PASSED" : "FAILED")
+    << " ******" << endl;
+  // inverted logic needed because 0 is good for 
+  // return codes.
+  return !passed; 
+};
\ No newline at end of file

=== modified file 'cpp/common/circular_queue/Makefile'
--- obsolete/Cpp/common/circular_queue/Makefile	2012-04-06 12:10:36 +0000
+++ cpp/common/circular_queue/Makefile	2013-08-09 21:47:12 +0000
@@ -16,6 +16,8 @@
 #
 #***********************************************
 
+switches=-std=gnu++11 -D _GLIBCXX_USE_SCHED_YIELD -D _GLIBCXX_USE_NANOSLEEP
+
 lib:	circular_queue_test
 	@./circular_queue_test
 	@cp -v circular_queue.h ../include
@@ -23,8 +25,8 @@
 
 circular_queue_test:	circular_queue.h circular_queue_test.cpp
 	@rm -f circular_queue_test
-	g++ -c circular_queue_test.cpp -I../include -std=gnu++0x
-	g++ -o circular_queue_test circular_queue_test.o ../obj/common.o ../obj/base_thread.o -lpthread  -std=gnu++0x
+	g++ -c circular_queue_test.cpp -I../include ${switches}
+	g++ -o circular_queue_test circular_queue_test.o -lpthread ${switches}
 
 clean:
 	@rm -rvf *.o circular_queue_test ../include/circular_queue.h *.log ../obj/circular_queue.o

=== modified file 'cpp/common/circular_queue/circular_queue.h'
--- obsolete/Cpp/common/circular_queue/circular_queue.h	2011-10-06 20:09:07 +0000
+++ cpp/common/circular_queue/circular_queue.h	2013-08-09 21:47:12 +0000
@@ -20,18 +20,31 @@
 #define nrtb_circular_queue_h
 
 #include <iostream>
-#include <base_thread.h>
 #include <boost/circular_buffer.hpp>
+#include <atomic>
+#include <mutex>
+#include <condition_variable>
+#include <common.h>
+#include <abs_queue.h>
 
 namespace nrtb
 {
+  
+// specialize boost::circular_buffer to act like a queue.
+template <class T> 
+class base_cq : public boost::circular_buffer<T>
+{
+public:
+  void push(T elem) { this->push_back(elem); };
+  void pop() { this->pop_front(); };
+};
 
 /********************************************************
  * The circular_queue template is designed for use with
  * the classic producer/consumer thread management model.
  * The producer uses circular_queue::push() to put items
  * in the queue as they become available, and the consumer
- * thread calls circular_queue::park() when it is ready
+ * thread calls circular_queue::pop() when it is ready
  * for the next item to work.
  *
  * Common uses would be for buffering outgoing or incomming
@@ -41,132 +54,14 @@
  * passing data to another set of threads.
 ********************************************************/
 template <class T>
-class circular_queue
-{
-public:
-    class queue_not_ready: public base_exception {};
-
-    /*********************************************
-      * creates the queue with the specified
-      * number of elements. All memory is allocated
-      * at construction to minimize delays at runtime.
-    *********************************************/
-    circular_queue(int size);
-
-    /*********************************************
-      * releases all items in the queue
-    *********************************************/
-    virtual ~circular_queue();
-
-    /*********************************************
-      * Puts an item in the queue.
-    *********************************************/
-    void push(T item);
-
-    /*********************************************
-      * Pops the next item off the queue, blocking
-      * if needed until an item becomes available.
-    *********************************************/
-    T pop();
-
-    /*********************************************
-     * puts the queue in shutdown mode.
-    *********************************************/
-    void shutdown();
-
-    // returns the number of items in the queue
-    int size();
-    // resizes the buffer, may cause data loss
-    void resize(int newsize);
-    // clears the buffer, data will be discarded.
-    void clear();
-
-protected:
-
-    boost::circular_buffer<T> buffer;
-    cond_variable buffer_lock;
-    bool ready;
-};
-
-template <class T>
-circular_queue<T>::circular_queue(int size)
-{
-    buffer.set_capacity(size);
-    ready = true;
-};
-
-// TODO: needed ... a queue stop method.
-
-template <class T>
-circular_queue<T>::~circular_queue()
-{
-};
-
-template <class T>
-void circular_queue<T>::push(T item)
-{
-  if (ready)
-  {
-	scope_lock lock(buffer_lock);
-    buffer.push_back(item);
-    buffer_lock.signal();
-  }
-  else 
-  {
-	queue_not_ready e;
-	  throw e;
-  }
-};
-
-template <class T>
-T circular_queue<T>::pop()
-{
-    scope_lock lock(buffer_lock);
-    while (buffer.empty() && ready)
-        buffer_lock.wait();
-    if (!ready)
-    {
-        queue_not_ready e;
-        throw e;
-    };
-	T returnme = buffer.front();
-	buffer.pop_front();
-	return returnme;
-};
-
-template <class T>
-void circular_queue<T>::shutdown()
-{
-  try
-  {
-	scope_lock lock(buffer_lock);
-	ready = false;
-	buffer_lock.broadcast_signal();
-	buffer.clear();
-  }
-  catch (...) {}  
-}
-
-
-template <class T>
-int circular_queue<T>::size()
-{
-    scope_lock lock(buffer_lock);
-    return buffer.size();
-};
-
-template <class T>
-void circular_queue<T>::resize(int newsize)
-{
-    scope_lock lock(buffer_lock);
-    buffer.set_capacity(newsize);
-};
-
-template <class T>
-void circular_queue<T>::clear()
-{
-    scope_lock lock(buffer_lock);
-    buffer.clear();
+class circular_queue : public abs_queue<T, base_cq<T>> 
+{
+public:  
+  // convienence constructor because a 0 size circular_queue is useless.
+  circular_queue(int size=10) : abs_queue<T, base_cq<T>>() 
+  {
+    this->resize(size);
+  };
 };
 
 } // namespace nrtb

=== modified file 'cpp/common/circular_queue/circular_queue_test.cpp'
--- obsolete/Cpp/common/circular_queue/circular_queue_test.cpp	2011-10-06 20:09:07 +0000
+++ cpp/common/circular_queue/circular_queue_test.cpp	2013-08-09 21:47:12 +0000
@@ -18,78 +18,41 @@
  
 #include <string>
 #include <iostream>
+#include <unistd.h>
 #include "circular_queue.h"
-#include <boost/shared_ptr.hpp>
+#include <memory>
+#include <future>
 
 using namespace nrtb;
 using namespace std;
 
 typedef circular_queue<int> test_queue;
-typedef boost::shared_ptr<test_queue> queue_p;
+typedef std::shared_ptr<test_queue> queue_p;
 
-class consumer_task: public thread
+int consumer_task(string name, queue_p input)
 {
-public:
-
-  consumer_task(string n, queue_p buffer)
-  {
-	name = n;
-	input = buffer;
-	count = 0;
-  };
-  
-  ~consumer_task()
-  {
-	cout << ">> in " << name << "::~consumer_task()" << endl;
-	try
-	{
-	  this->thread::~thread();
-	  input.reset();
-	}
-	catch (...)  {};
-	cout << "<< leaving " << name << "::~consumer_task()" << endl;
-  };
-  
-  int get_count() { return count; };
-  
-  void run()
-  {
-	try
-	{
-	  while (true)
-	  {
-		int num = input->pop();
-		{
-		  static mutex console;
-		  scope_lock lock(console);
-		  cout << name << " picked up " << num
-			<< endl;
-		};
-		count++;
-		lastnum = num;
-		yield();	  
-	  }
-	}
-	catch (...) {};
-  };
-
-protected:
-  // link to the feed queue
-  queue_p input;
-  // a name to report 
-  string name;
-  // number of items processed
-  int count;
-  // last number caught
-  int lastnum;
+  bool ready {true};
+  int count {0};
+  try
+  {
+    while (ready)
+    {
+      int num = input->pop();
+      count++;
+      usleep(1);	  
+    }
+  }
+  catch (...) 
+  {
+    // exit on any exception
+    ready = false;
+  };
+  return count;
 };
 
-typedef boost::shared_ptr<consumer_task> task_p;
-
-
 int main()
 {
-  int er_count = 0;
+  cout << "***** circular_queue unit test *****" << endl;
   /************************************************
    * Load queue and then cook it down...
    ***********************************************/
@@ -101,10 +64,11 @@
   };
   // the queue should be loaded with 50-99
   // attach a thread and process it.
-  task_p p1(new consumer_task("task 1",q1));
-  p1->start();
+  auto t1 = async(launch::async,consumer_task,"task 1",q1);
   while (q1->size()) usleep(100);
-  cout << "cp 1 " << p1->get_count() << endl;
+  cout << "cp 1 " 
+    << q1->in_count << ":"
+    << q1->out_count << endl;
   /************************************************
    * now that the preload is exhasted, shove items
    * in one at a time to make sure each is picked
@@ -112,40 +76,42 @@
    ***********************************************/
   for (int i=200; i<225; i++)
   {
-	q1->push(i);
-	usleep(100);
+    q1->push(i);
+    usleep(100);
   };
-  cout << "cp 2 " << p1->get_count() << endl;
+  cout << "cp 2 " 
+    << q1->in_count << ":"
+    << q1->out_count << endl;
   /************************************************
    * Last check; attach a second thread to the queue
    * and make sure both are servicing it.
    ***********************************************/
-  task_p p2(new consumer_task("task 2",q1));
-  p2->start();
+  auto t2 = async(launch::async,consumer_task,"task 2",q1);
   for (int i=300; i<325; i++)
   {
-	q1->push(i);
+    q1->push(i);
   };
   while (q1->size()) usleep(100);
   // shut it all down
   q1->shutdown();
-  p1->join();
-  p2->join();
   // important numbers
-  int tot_items = p1->get_count() + p2->get_count();
-  int p1_items = p1->get_count() - 75;
-  int p2_items = p2->get_count();
+  int q1_in = q1->in_count;
+  int q1_out = q1->out_count;
+  int t1_items = t1.get();
+  int t2_items = t2.get();
   // release she threads and queues.
-  p1.reset();
-  p2.reset();
   q1.reset();
   // do some reporting.
   cout << "cp 3 " 
-	<<  tot_items
-	<< " [75 + (" << p1_items
-	<< " + " << p2_items 
-	<< ")]" << endl;
-	bool passed = (tot_items == 100);
+    << q1_in << ":" << q1_out
+    << " t1=" << t1_items
+    << " t2=" << t2_items 
+    << endl;
+  bool passed = (q1_in - 50 == q1_out)
+    and (q1_out == (t1_items + t2_items));
+  cout << "***** circular_queue TEST "
+    << (passed ? "PASSED" : "FAILED")
+    << " ******" << endl;
   // inverted logic needed because 0 is good for 
   // return codes.
   return !passed; 

=== modified file 'cpp/common/common_rl/Makefile'
--- obsolete/Cpp/common/common_rl/Makefile	2012-04-06 12:16:10 +0000
+++ cpp/common/common_rl/Makefile	2013-08-09 21:47:12 +0000
@@ -16,6 +16,9 @@
 #
 #***********************************************
 
+switches=-std=gnu++11 -D _GLIBCXX_USE_SCHED_YIELD -D _GLIBCXX_USE_NANOSLEEP
+
+
 lib:	common_rl_test
 	@./common_rl_test
 	@cp -v common.h ../include
@@ -24,12 +27,12 @@
 
 common.o:	common.h common.cpp Makefile
 	@rm -f common.o
-	g++ -c -O3 common.cpp  -std=gnu++0x
+	g++ -c -O3 common.cpp ${switches}
 	
 common_rl_test:	common.o common_rl_test.cpp
 	@rm -f common_rl_test
-	g++ -c common_rl_test.cpp -std=gnu++0x
-	g++ -o common_rl_test common_rl_test.o common.o -std=gnu++0x
+	g++ -c common_rl_test.cpp  ${switches}
+	g++ -o common_rl_test common_rl_test.o common.o ${switches}
 
 clean:
 	@rm -rvf *.o  ../include/common.h ../obj/common.o common_rl_test

=== modified file 'cpp/common/common_rl/common.cpp'
--- obsolete/Cpp/common/common_rl/common.cpp	2010-12-25 22:44:22 +0000
+++ cpp/common/common_rl/common.cpp	2013-08-09 21:47:12 +0000
@@ -19,7 +19,6 @@
 #include <stdlib.h>
 #include <iostream>
 #include <math.h>
-#include <time.h>
 #include "common.h"
 
 using namespace std;
@@ -27,247 +26,224 @@
 namespace nrtb
 {
 
-base_exception::base_exception()
-{
-	ctime = time(NULL);
-};
-
-base_exception::base_exception(const string & text)
-{
-	ctime = time(NULL);
-	_text = text;
-};
-
-void base_exception::store(const string & s)
-{
-	_text = s;
-};
-
-string base_exception::comment()
-{
-	return _text;
-};
-
-unsigned long int base_exception::creation_time()
-{
-	return ctime;
-};
-
 const string __ricks_handy_upper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
 const string __ricks_handy_lower = "abcdefghijklmnopqrstuvwxyz";
 
-string changecase(const string &s,const string &upper, const string &lower)
+string changecase(const string &s,const string &upper, 
+		  const string &lower)
 {
-	try
-	{
-		string returnme = "";
-		for (int i = 0; i < s.size(); i++)
-		{
-			unsigned long int loc = lower.find(s[i]);
-			if (loc == string::npos)
-			{
-				returnme += s[i];
-			}
-			else
-			{
-				returnme += upper[loc];
-			};
-		};
-		return returnme;
-	}
-	catch (...)
-	{
-		throw translate_exception();
-	};
+  try
+  {
+    string returnme = "";
+    for (int i = 0; i < s.size(); i++)
+    {
+      unsigned long int loc = lower.find(s[i]);
+      if (loc == string::npos)
+      {
+	returnme += s[i];
+      }
+      else
+      {
+	returnme += upper[loc];
+      };
+    };
+    return returnme;
+  }
+  catch (...)
+  {
+    throw translate_exception();
+  };
 };
 
 string upcase(const string &s)
 {
-	return changecase(s,__ricks_handy_upper,__ricks_handy_lower);
+  return changecase(s,__ricks_handy_upper,__ricks_handy_lower);
 };
 
 string downcase(const string &s)
 {
-	return changecase(s,__ricks_handy_lower,__ricks_handy_upper);
+  return changecase(s,__ricks_handy_lower,__ricks_handy_upper);
 };
 
 
 const string __ricks_handy_hexits = "0123456789ABCDEF";
 
-string gsub(const string & target, const string & findme, const string & putme)
+string gsub(const string & target, const string & findme,
+	    const string & putme)
 {
-	// error checking
-	if (findme.empty() || target.empty())
-	{
-		throw gsub_exception();
-	};
-	string returnme = "";
-	unsigned long int okay_through = 0;
-	unsigned long int step = findme.length();
-	unsigned long int where = target.find(findme,okay_through);
-	while (where != string::npos)
-	{
-		returnme += target.substr(okay_through,where-okay_through) + putme;
-		okay_through = where + step;
-		where = target.find(findme,okay_through);
-	};
-	returnme += target.substr(okay_through);
-	return returnme;
+  // error checking
+  if (findme.empty() || target.empty())
+  {
+    throw gsub_exception();
+  };
+  string returnme = "";
+  unsigned long int okay_through = 0;
+  unsigned long int step = findme.length();
+  unsigned long int where = target.find(findme,okay_through);
+  while (where != string::npos)
+  {
+    returnme += target.substr(okay_through,where-okay_through) + putme;
+    okay_through = where + step;
+    where = target.find(findme,okay_through);
+  };
+  returnme += target.substr(okay_through);
+  return returnme;
 };
 
 strlist split(const string & source, const char token)
 {
-	strlist returnme;
-	returnme.clear();
-	if (source.size() > 0)
-	{
-		unsigned long int loc;
-		unsigned long int processed = 0;
-		try
-		{
-			loc = source.find(token,processed);
-			while (loc != string::npos)
-			{
-				returnme.push_back(source.substr(processed,loc-processed));
-				processed = loc + 1;
-				loc = source.find(token,processed);
-			}
-			returnme.push_back(source.substr(processed));
-		}
-		catch (...)
-		{
-			throw split_exception();
-		};
-	};
-	return returnme;
+  strlist returnme;
+  returnme.clear();
+  if (source.size() > 0)
+  {
+    unsigned long int loc;
+    unsigned long int processed = 0;
+    try
+    {
+      loc = source.find(token,processed);
+      while (loc != string::npos)
+      {
+	returnme.push_back(source.substr(processed,loc-processed));
+	processed = loc + 1;
+	loc = source.find(token,processed);
+      }
+      returnme.push_back(source.substr(processed));
+    }
+    catch (...)
+    {
+      throw split_exception();
+    };
+  };
+  return returnme;
 }; 
 
 string trim(std::string s)
 {
-	const string ws = "\t\n ";
-	unsigned long int where = s.find_first_not_of(ws);
-	if (where != string::npos)
-	{
-		s.erase(0,where);
-	};
-	where = s.find_last_not_of(ws);
-	if (where != string::npos)
-	{
-		s.erase(where+1);
-	};
-	return s;
+  const string ws = "\t\n ";
+  unsigned long int where = s.find_first_not_of(ws);
+  if (where != string::npos)
+  {
+    s.erase(0,where);
+  };
+  where = s.find_last_not_of(ws);
+  if (where != string::npos)
+  {
+    s.erase(where+1);
+  };
+  return s;
 };
 
 string mconvert(const string &s)
 {
-	/* This function is designed to escape strings destined for 
-	 * use in SQL queries and the like.  Specifically, the following 
-	 * is done to the string passed in:
-	 *   1. "\" is replaced with "\\"
-	 *   2. "'" is replaced with "\'"
-	 *   3. """ (double quote) is replaced with "\""
-	 *   4. 0x00 is replaced with "\"+0x00.
-	*/
-	string returnme = "";
-   if (s.length() > 0)
-   {
-		returnme = gsub(s,"\\","\\\\");
-      returnme = gsub(returnme,"'", "\\'");
-      returnme = gsub(returnme,"\"","\\\"");
-      // special handling is required to make strings including
-      // 0x00; this is the kludge I found to work at 2200 tonight.
-      string findme = " "; findme[0] = 0;
-      returnme = gsub(returnme,findme,"\\0");
-   };
-   return returnme;
+  /* This function is designed to escape strings destined for 
+    * use in SQL queries and the like.  Specifically, the following 
+    * is done to the string passed in:
+    *   1. "\" is replaced with "\\"
+    *   2. "'" is replaced with "\'"
+    *   3. """ (double quote) is replaced with "\""
+    *   4. 0x00 is replaced with "\"+0x00.
+  */
+  string returnme = "";
+  if (s.length() > 0)
+  {
+    returnme = gsub(s,"\\","\\\\");
+    returnme = gsub(returnme,"'", "\\'");
+    returnme = gsub(returnme,"\"","\\\"");
+    // special handling is required to make strings including
+    // 0x00; this is the kludge I found to work at 2200 tonight.
+    string findme = " "; findme[0] = 0;
+    returnme = gsub(returnme,findme,"\\0");
+  };
+  return returnme;
 };
 
 string dateflip(string date, const string & sep) 
 {
-	string out;
-	try
-	{
-	   strlist temp = split(date,'-');
-	   out = temp[1]+ sep + temp[2] + sep + temp[0];
-	}
-	catch (...)
-	{
-		throw dateflip_exception();
-	};
-	return out;
+  string out;
+  try
+  {
+    strlist temp = split(date,'-');
+    out = temp[1]+ sep + temp[2] + sep + temp[0];
+  }
+  catch (...)
+  {
+    throw dateflip_exception();
+  };
+  return out;
 }; // string dateflip
    
 string http_hextochar(string s)
 {
-	try
-	{
-	   s = upcase(s);
-	   unsigned char v = (16 * __ricks_handy_hexits.find(s[0])) 
-	   	+ __ricks_handy_hexits.find(s[1]);
-	   return s = v;
-	}
-	catch (...)
-	{
-		throw hextrans_exception();
-	};
+  try
+  {
+    s = upcase(s);
+    unsigned char v = (16 * __ricks_handy_hexits.find(s[0])) 
+	+ __ricks_handy_hexits.find(s[1]);
+    return s = v;
+  }
+  catch (...)
+  {
+    throw hextrans_exception();
+  };
 }; // string hextochar
 
 string http_chartohex(const string &s)
 {
-   string out;
-   try
-   {
-	   for (long int i=0; i < s.length() ; i++ ) {
-	      unsigned char v = s[i];
-	      div_t hexval = div(v,16);
-	      out += __ricks_handy_hexits[hexval.quot];
-	      out += __ricks_handy_hexits[hexval.rem];
-	   }; /* endfor */
-	}
-	catch (...)
-	{
-		throw hextrans_exception();
-	};
-   return out;
+  string out;
+  try
+  {
+    for (long int i=0; i < s.length() ; i++ ) {
+      unsigned char v = s[i];
+      div_t hexval = div(v,16);
+      out += __ricks_handy_hexits[hexval.quot];
+      out += __ricks_handy_hexits[hexval.rem];
+    }; /* endfor */
+  }
+  catch (...)
+  {
+    throw hextrans_exception();
+  };
+  return out;
 };// string chartohex()
 
 string http_enhex(const string & s)
 {
-   string out;
-   try
-   {
-	   for (long int i=0; i < s.length() ; i++ ) {
-	      unsigned char v = s[i];
-	      div_t hexval = div(v,16);
-	      out += "%";
-	      out += __ricks_handy_hexits[hexval.quot];
-	      out += __ricks_handy_hexits[hexval.rem];
-	   }; /* endfor */
-	}
-	catch (...)
-	{
-		throw hextrans_exception();
-	};
-   return out;
+  string out;
+  try
+  {
+    for (long int i=0; i < s.length() ; i++ ) 
+    {
+      unsigned char v = s[i];
+      div_t hexval = div(v,16);
+      out += "%";
+      out += __ricks_handy_hexits[hexval.quot];
+      out += __ricks_handy_hexits[hexval.rem];
+    }; /* endfor */
+  }
+  catch (...)
+  {
+	  throw hextrans_exception();
+  };
+  return out;
 }; // string enhex()
 
 string http_unhex(string s)
 {
-	try
-	{
-	   while (s.find('%') != string::npos) 
-	   {
-	      int where = s.find('%');
-	      string hexchar = s.substr(where+1,2);
-	      s.erase(where,3);
-	      s.insert(where,http_hextochar(hexchar));
-	   }; /* endwhile */
-	}
-	catch (...)
-	{
-		throw hextrans_exception();
-	};
-   return s;
+  try
+  {
+    while (s.find('%') != string::npos) 
+    {
+      int where = s.find('%');
+      string hexchar = s.substr(where+1,2);
+      s.erase(where,3);
+      s.insert(where,http_hextochar(hexchar));
+    }; /* endwhile */
+  }
+  catch (...)
+  {
+	  throw hextrans_exception();
+  };
+  return s;
 };// string unhex()
 
 

=== modified file 'cpp/common/common_rl/common.h'
--- obsolete/Cpp/common/common_rl/common.h	2010-12-25 22:44:22 +0000
+++ cpp/common/common_rl/common.h	2013-08-09 21:47:12 +0000
@@ -20,10 +20,10 @@
 #ifndef __ga_common_h
 #define __ga_common_h 1
 
-//#include <stream.h>
 #include <string>
 #include <map>
 #include <vector>
+#include <chrono>
 
 namespace nrtb
 {
@@ -39,40 +39,36 @@
  ** get the time the exception was created and any text the thrower may have
  ** provided.
  **/
- class base_exception: public std::exception
- {
- 	protected:
- 		unsigned long int ctime;
- 		std::string _text;
- 	public:
- 		/** Default constructor.
- 		 ** 
- 		 ** Creates an nrtb_exception recording it's creation time but without
- 		 ** a comment string.
- 		 **/
- 		base_exception();
- 		/** Constructs with a comment string.
- 		 ** 
- 		 ** Creates an nrtb_exception recording it's creation time and storing the 
- 		 ** provided string "text" for recall later via the comment method.
- 		 ** 
- 		 ** This version takes an ISO standard C++ string.
- 		 **/
- 		base_exception(const std::string & text);
- 		/// NOP virtual distructor for safe inheritance
- 		virtual ~base_exception() throw() {};
- 		/** Stores a comment string.
- 		 **/
- 		void store(const std::string & s);
- 		/** Returns the value stored at exception creation.
- 		 **/
- 		std::string comment();
- 		/** Returns the unix time the exception was created.
- 		 **/
- 		unsigned long int creation_time();
+class base_exception: public std::exception
+{
+protected:
+  typedef std::chrono::high_resolution_clock myclock;
+  typedef std::chrono::high_resolution_clock::time_point mark;
+  typedef std::chrono::microseconds ms;
+  mark created {myclock::now()};
+  std::string _text;
+  
+public:
+  /// NOP virtual distructor for safe inheritance
+  virtual ~base_exception() throw() {};
+  /** Stores a comment string.
+   **/
+  void store(const std::string & s) { _text = s; };
+  /** Returns the value stored at exception creation.
+   **/
+  std::string comment() { return _text; };
+  /** Returns the time the exception was created.
+   **/
+  mark creation_time() { return created; };
+  /** Returns the age of the exception 
+   **/
+  ms age_in_ms() 
+  { 
+    return std::chrono::duration_cast<ms>(myclock::now() - created); 
+  };
 };
 
-// Thrown by gsub() in cases of unexpected error.
+// Thrown by gsub() in cases of unexpectaed error.
 class gsub_exception: public nrtb::base_exception {};
 // Thrown by split() in cases of unexpected error.
 class split_exception: public nrtb::base_exception {};

=== modified file 'cpp/common/common_rl/common_rl_test.cpp'
--- obsolete/Cpp/common/common_rl/common_rl_test.cpp	2011-07-21 22:14:53 +0000
+++ cpp/common/common_rl/common_rl_test.cpp	2013-08-09 21:47:12 +0000
@@ -18,6 +18,7 @@
  
 #include "common.h"
 #include <iostream>
+#include <unistd.h>
 
 using namespace std;
 
@@ -96,6 +97,23 @@
 	  "nrtb::http_unhex()",
 	  nrtb::http_unhex("%4D%69%58%65%44%63%41%73%45") == tstr);
   
+  try
+  {
+    nrtb::base_exception e;
+    e.store("Test code");
+    usleep(100);
+    throw e;
+  }
+  catch (nrtb::base_exception & e)
+  {
+    returnme += report_test(
+      "nrtb::base_exception::comment()",
+      e.comment() == "Test code");
+    returnme += report_test(
+      "nrtb::base_exception::age_in_ms()",
+      e.age_in_ms().count() > 100 );
+  };
+  
   cout << "=== nrtb::common_rl unit test complete ===" << endl;
   return returnme;
 };
\ No newline at end of file

=== modified file 'cpp/common/confreader/Makefile'
--- obsolete/Cpp/common/confreader/Makefile	2012-04-06 12:19:37 +0000
+++ cpp/common/confreader/Makefile	2013-08-09 21:47:12 +0000
@@ -16,6 +16,8 @@
 #
 #***********************************************
 
+switches=-std=gnu++11 -D _GLIBCXX_USE_SCHED_YIELD -D _GLIBCXX_USE_NANOSLEEP
+
 lib:	conftest
 	@rm -f conf_test.log
 	@./conftest test=1 test2-2 test2=71.837486 test3="jack danials" --doit
@@ -26,12 +28,12 @@
 
 confreader.o:	confreader.h confreader.cpp Makefile 
 	@rm -f confreader.o
-	g++ -c confreader.cpp -I../include -std=gnu++0x
+	g++ -c confreader.cpp -I../include ${switches}
 
 conftest:	confreader.o conftest.cpp
 	@rm -f conftest
-	g++ -c conftest.cpp -I../include -std=gnu++0x
-	g++ -o conftest conftest.o confreader.o ../obj/common.o ../obj/log_setup.o ../obj/base_thread.o -lpthread -lPocoFoundation -lPocoUtil -std=gnu++0x
+	g++ -c conftest.cpp -I../include ${switches} 
+	g++ -o conftest conftest.o confreader.o ../obj/common.o ../obj/logger.o -lpthread ${switches}
 
 clean:
 	@rm -rvf *.o conftest ../include/confreader.h ../obj/confreader.o conf_test.log

=== modified file 'cpp/common/confreader/confreader.cpp'
--- obsolete/Cpp/common/confreader/confreader.cpp	2011-08-13 15:06:08 +0000
+++ cpp/common/confreader/confreader.cpp	2013-08-09 21:47:12 +0000
@@ -21,206 +21,198 @@
 #include "confreader.h"
 #include <fstream>
 #include <iostream>
-#include <common.h>
-#include "Poco/Logger.h"
 
 using namespace std;
 using namespace nrtb;
 
-const std::string logname = "conf_reader";
-
 namespace nrtb
 {
 
 conf_reader::conf_reader()
 {
-	Poco::Logger& logger = Poco::Logger::get(logname);
-	logger.information("conf_reader instanciated.");
+  // nop constructor
 };
 
-conf_reader::~conf_reader() {};
+conf_reader::~conf_reader() 
+{
+  // nop destructor
+};
 
 unsigned int conf_reader::read(const std::string & _filename, bool _clear)
 {
-	Poco::Logger& logger = Poco::Logger::get(logname);
-	logger.information("Reading from \"" + _filename + "\".");
-	if (_filename != "") { filename = _filename; };
-	if (filename != "")
-	{
-		try
-		{
-			ifstream cfile(filename.c_str());
-			if (!cfile) throw base_exception();
-			if (_clear) values.clear();
-			// read the file line by line, ignoring comments.
-			char inbuff[16*1024];
-			while (cfile)
-			{
-				cfile.getline(inbuff, 16*1024);
-				string in = inbuff;
-				// truncate at the start of a comment.
-				unsigned long int where = in.find("#");
-				while (where != string::npos)
-				{
-					if (in[where-1] == '\\')
-					{
-						// comment char was escaped.. ignore.
-						where = in.find("#",where+1);
-					}
-					else
-					{
-						// truncate the string at this point.
-						in.erase(where);
-						where = string::npos;
-					};
-				};
-				// see if we can parse what's left.
-				in = trim(in);
-				unsigned long int split_point = in.find_first_of("\t ");
-				if (split_point != string::npos)
-				{
-					// okay.. get the fields.
-					pair arg;
-					arg.first = gsub(trim(in.substr(0,split_point)),"\\#","#");
-					arg.second = gsub(trim(in.substr(split_point)),"\\#","#");
-					// is this an include directive?
-					if (arg.first == "*INCLUDE")
-					{
-						read(arg.second,false);
-					} 
-					else if (arg.first != "")
-					{
-						values.insert(arg);
-					};
-				};
-			};
-		}
-		catch (...)
-		{
-			logger.warning("Problems reading configuration file \""
-				+ filename + "\"; data may be incomplete.");
-		}
-	};
-	return values.size();
+  if (_filename != "") { filename = _filename; };
+  if (filename != "")
+  {
+    try
+    {
+      ifstream cfile(filename.c_str());
+      if (!cfile) throw base_exception();
+      if (_clear) values.clear();
+      // read the file line by line, ignoring comments.
+      char inbuff[16*1024];
+      while (cfile)
+      {
+	cfile.getline(inbuff, 16*1024);
+	string in = inbuff;
+	// truncate at the start of a comment.
+	unsigned long int where = in.find("#");
+	while (where != string::npos)
+	{
+	  if (in[where-1] == '\\')
+	  {
+	    // comment char was escaped.. ignore.
+	    where = in.find("#",where+1);
+	  }
+	  else
+	  {
+	    // truncate the string at this point.
+	    in.erase(where);
+	    where = string::npos;
+	  };
+	};
+	// see if we can parse what's left.
+	in = trim(in);
+	unsigned long int split_point = in.find_first_of("\t ");
+	if (split_point != string::npos)
+	{
+	  // okay.. get the fields.
+	  pair arg;
+	  arg.first = gsub(trim(in.substr(0,split_point)),"\\#","#");
+	  arg.second = gsub(trim(in.substr(split_point)),"\\#","#");
+	  // is this an include directive?
+	  if (arg.first == "*INCLUDE")
+	  {
+	    read(arg.second,false);
+	  } 
+	  else if (arg.first != "")
+	  {
+	    values.insert(arg);
+	  };
+	};
+      };
+    }
+    catch (...)
+    {
+      cerr << "WARNING:Problems reading configuration file \""
+	<< filename <<  "\"; data may be incomplete.";
+    }
+  };
+  return values.size();
 };
 
 unsigned int conf_reader::read(int argc, char * argv[], 
 	const string & _filename)
 {
-	Poco::Logger& logger = Poco::Logger::get(logname);
-	logger.information("Reading from command line.");
-	clear();
-	filename = _filename;
-	value_list_type cvars;
-	// read values from the command line first.
-	for (int i = 0; i < argc; i++)
-	{
-		string instring = argv[i];
-		if (i == 0)
-		{
-			instring = "__exec_name="+instring;
-		};
-		strlist t = split(instring,'=');
-		if (t.size() > 0)
-		{
-			// build the new insert pair;
-			pair newval;
-			newval.first = t[0];
-			// assemble the value
-			// (allows for including "=" in the argument)
-			for (unsigned int l = 1; l < t.size(); l++)
-			{
-				newval.second += t[l];
-				if (l < (t.size() -1) )
-				{
-					newval.second += "=";
-				};
-			};
-			// store this in the list
-			trim(newval.first);
-			trim(newval.second);
-			cvars.insert(newval);
-			// is this a config file name?
-			if (newval.first == "configfile")
-			{
-				filename = newval.second;
-			};
-		};
-	}; // read the command line arguments.
-	// read the file args if any.
-	read(filename,false);
-	// override the first instance of any value found in configs
-	// or insert as appropriate.
-	iterator c = cvars.begin();
-	iterator e = cvars.end();
-	while (c != e)
-	{
-		iterator here = values.find(c->first);
-		if (here != values.end())
-		{
-			here->second = c->second;
-		}
-		else
-		{
-			values.insert(*c);
-		};
-		c++;
+  clear();
+  filename = _filename;
+  value_list_type cvars;
+  // read values from the command line first.
+  for (int i = 0; i < argc; i++)
+  {
+    string instring = argv[i];
+    if (i == 0)
+    {
+      instring = "__exec_name="+instring;
+    };
+    strlist t = split(instring,'=');
+    if (t.size() > 0)
+    {
+      // build the new insert pair;
+      pair newval;
+      newval.first = t[0];
+      // assemble the value
+      // (allows for including "=" in the argument)
+      for (unsigned int l = 1; l < t.size(); l++)
+      {
+	newval.second += t[l];
+	if (l < (t.size() -1) )
+	{
+	  newval.second += "=";
 	};
-	std::stringstream message;
-	message << "Read " << values.size() << " parameters.";
-	logger.information(message.str());
-	return values.size();
+      };
+      // store this in the list
+      trim(newval.first);
+      trim(newval.second);
+      cvars.insert(newval);
+      // is this a config file name?
+      if (newval.first == "configfile")
+      {
+	filename = newval.second;
+      };
+    };
+  }; // read the command line arguments.
+  // read the file args if any.
+  read(filename,false);
+  // override the first instance of any value found in configs
+  // or insert as appropriate.
+  iterator c = cvars.begin();
+  iterator e = cvars.end();
+  while (c != e)
+  {
+    iterator here = values.find(c->first);
+    if (here != values.end())
+    {
+      here->second = c->second;
+    }
+    else
+    {
+      values.insert(*c);
+    };
+    c++;
+  };
+  cout << "Read " << values.size() << " parameters.";
+  return values.size();
 };
 
 void conf_reader::clear()
 {
-	values.clear();
+  values.clear();
 };
 
 conf_reader::iterator conf_reader::begin()
 {
-	return values.begin();
+  return values.begin();
 };
 
 conf_reader::iterator conf_reader::end()
 {
-	return values.end();
+  return values.end();
 };
 
 bool conf_reader::empty()
 {
-	return values.empty();
+  return values.empty();
 };
 
 unsigned int conf_reader::size()
 {
-	return values.size();
+  return values.size();
 };
 
 strlist conf_reader::all(const std::string & key)
 {
-	strlist returnme;
-	iterator current = values.find(key);
-	iterator e = values.end();
-	while ((current != e) && (current->first == key))
-	{
-		returnme.push_back(current->second);
-		current++;
-	};
-	return returnme;
+  strlist returnme;
+  iterator current = values.find(key);
+  iterator e = values.end();
+  while ((current != e) && (current->first == key))
+  {
+    returnme.push_back(current->second);
+    current++;
+  };
+  return returnme;
 };
 
 string conf_reader::operator [] (const std::string & key)
 {
-	iterator res = values.find(key);
-	string returnme = "";
-	if (res != values.end()) returnme = res->second;
-	return returnme;
+  iterator res = values.find(key);
+  string returnme = "";
+  if (res != values.end()) returnme = res->second;
+  return returnme;
 };
 
 bool conf_reader::exists(const std::string & key)
 {
-	return (values.find(key) != values.end());
+  return (values.find(key) != values.end());
 };
 
 } // namespace nrtb

=== modified file 'cpp/common/confreader/confreader.h'
--- obsolete/Cpp/common/confreader/confreader.h	2011-08-13 15:06:08 +0000
+++ cpp/common/confreader/confreader.h	2013-08-09 21:47:12 +0000
@@ -16,8 +16,8 @@
  
  **********************************************/
 
-#ifndef ricklib_confreader_h
-#define ricklib_confreader_h
+#ifndef nrtb_confreader_h
+#define nrtb_confreader_h
 
 #include <string.h>
 #include <map>
@@ -25,13 +25,13 @@
 #include <string>
 #include <fstream>
 #include <boost/lexical_cast.hpp>
+#include <common.h>
+#include <logger.h>
 #include <singleton.h>
 
-namespace nrtb
+namespace nrtb 
 {
 
-typedef std::vector<std::string> strlist;
-
 /** Reads command line and configuration file information.
  **
  ** For this NRTB implementation, this class is implemented as
@@ -47,241 +47,242 @@
  **/
 class conf_reader
 {
-	private:
-		typedef std::multimap<std::string,std::string> value_list_type;
-		value_list_type values;
-		std::string filename;
-	protected:
-		/** Reads and parses a configuration file.
-		 ** 
-		 ** Returns the number of values stored.
-		 ** 
-		 ** The optional parameter _clear when true clears the currently
-		 ** stored list of values. if false the new values read will be added
-		 ** to the existing list.
-		 ** 
-		 ** If the file named can not be processed completely, a warning
-		 ** message is published to cerr. 
-		 ** 
-		 ** Configuration files are defined as follows.
-		 ** 
-		 ** 1. Files are read line by line. No value can cross a newline
-		 **    (and at least in this version) or include one. The good
-		 **    news is that you are allowed up to 16k for each line.
-		 **    
-		 ** 2. values are specifed in name/value pairs, one per line, with
-		 ** 	 the name first, followed by whitespace, followed by the 
-		 ** 	 value. Values may include whitespace. All leading and trailing
-		 ** 	 whitespace is removed from both the name and the value.
-		 ** 	 
-		 ** 3. Comments start with a \# symbol; all text following a \# is
-		 **    ignored. If you need to use \# in a name or value, escape
-		 **    it with a backslash instead.
-		 **    
-		 ** 4. Duplicate names are allowed.
-		 ** 
-		 ** 5. Names without values will be stored with "" as the value.
-		 ** 
-		 ** 6. A configuration file may include another configuration file
-		 **    automatically by the use of the "*INCLUDE" reserved name.
-		 **    When this name is found, it's value is used as the name of
-		 **    the new file to be read.
-		 **/
-		unsigned int read(const std::string & _filename = "", bool _clear=true);
-	public:
-		/// conf_reader iterator, points to a conf_reader::pair
-		typedef value_list_type::iterator iterator;
-		/// conf_reader::pair is a std::pair<string,string>
-		typedef std::pair<std::string,std::string> pair;
-		/** No argument constructor; actually calls read() without a filename.
-		**/
-		conf_reader();
-		/** NOP virtual destructor to allow safe inheritance.
-		 **/
-		virtual ~conf_reader();
-		/** Reads and parses the command line and the provided file.
-		 ** 
-		 ** Returns the number of values stored. argc and argv are, of 
-		 ** course the same names you used as arguments to main(). Therefore
-		 ** you can easily read all command line and configuration file 
-		 ** values like this:
-		 ** 
-		 ** int main(int argc, char* argv[])
-		 **
-		 ** {
-		 **
-		 ** 	conf_reader config;
-		 **
-		 ** 	config.read(argc,argv,"my_conf_file");
-		 **
-		 ** 	...
-		 **
-		 ** }
-		 ** 
-		 ** See read(filename,_clear) for a discription of how configuration
-		 ** files are structured and parsed. This method unconditionally
-		 ** clears the existing value list before starting. For command line
-		 ** arguments the following rules are true.
-		 ** 
-		 ** 1. The executable name (argv[0]) is stored as a value with the 
-		 **    name "__exec_name".
-		 **   
-		 ** 2. Command line arguments of the form "name=value" are parsed
-		 **    stored as named values.
-		 ** 
-		 ** 3. All other command line arguments are stored as names with 
-		 **    value = "".
-		 **    
-		 ** 4. A command line argument of form "configfile=filename" will
-		 **    override the filename supplied as an argument to this method.
-		 **    
-		 ** 5. In the case of duplicate command line arguments, the last one 
-		 **    specified wins.
-		 **    
-		 ** 6. In the case of names in the configuration file duplicating 
-		 **    names from the command line, the values from the command line
-		 **    dominate. If there were multiple values for a given name 
-		 **    specified in the file, only the first one (the one returned by
-		 **    the "[]" operator or get<>() method) is overridden.
-		 **/
-		unsigned int read(int argc, char* argv[], 
-			const std::string & _filename);
-		/// clears the name/value list.
-		void clear();
-		/// returns an iterator to the first item in the list.
-		iterator begin();
-		/// returns an iterator one past the end of the list.
-		iterator end();
-		/// True if there are no values, false otherwise.
-		bool empty();
-		/// Returns the number of values stored.
-		unsigned int size();
-		/** Returns the string value matching the supplied name.
-		 ** 
-		 ** NOTE: the use of get<T>(key) or get<T>(key,default) is preferred.
-		 ** This method is public to allow for specialized handling in the
-		 ** rare cases where it may be required.
-		 ** 
-		 ** If there are no matching names, "" is returned. Be aware that
-		 ** "" is a valid value, so you can not use this to verify that
-		 ** a given name was defined. Use exists() for that.
-		 **/
-		std::string operator [] (const std::string & key);
-		/** Returns all values associated with the supplied name.
-		 ** 
-		 ** NOTE: the use of getall<T>(key) is preferred. This method is 
-		 ** public to allow specialized handling in rare case where it
-		 ** may be required.
-		 ** 
-		 ** If there are no values defined  the strlist will be empty.
-		 **/
-		strlist all(const std::string & key);
-		/// True if the name exists, false otherwise.
-		bool exists(const std::string & key);
-		/** Use this to get all matching values.
-		 ** 
-		 ** Usage:
-		 ** 
-		 ** vector<type> mylist = conf_reader_object.getall<type>(key);
-		 ** 
-		 ** type can be any standard type (string, int, double, etc.) or any
-		 ** type for which the ">>" stream operator is defined. All values
-		 ** with matching names that can map to the requested type will be
-		 ** returned. Any that do not map will not be returned.
-		 **/
-		template < class T >
-			typename std::vector<T> getall(const std::string & key);
-		/** Use this to get the matching value.
-		 ** 
-		 ** Useage:
-		 ** 
-		 ** type myvar = get<type>(key);
-		 ** 
-		 ** type can be any standard type (string, int, double, etc.) or any
-		 ** type for which the ">>" stream operator is defined. The return
-		 ** value is initialized to all zeros if no matching name is found or
-		 ** if the first value with that name does not map to the requested 
-		 ** type. For the numeric types that results in zero being returned,
-		 ** but be aware that more complex object may be in non-sensible
-		 ** states if they were not found or could not map. Use exists() to 
-		 ** verify the existance of a given name if needed.
-		 **/
-		template < class T >
-			T get(const std::string & key);
-		/** Returns the value for the requested key, or the supplied default.
-		 ** 
-		 ** Works exactly like get<>() with the exception that if the key
-		 ** is not found in the list, the user supplied default value is
-		 ** returned instead of 0 or an empty string. If the value exists but
-		 ** can not map to the requested type, 0 or an empty string is 
-		 ** returned for the standard types.
-		 **/
-		template <class T>
-			T get(const std::string & key, const T & def);
+private:
+  typedef std::multimap<std::string,std::string> value_list_type;
+  value_list_type values;
+public:
+  /// conf_reader iterator, points to a conf_reader::pair
+  typedef value_list_type::iterator iterator;
+  /// conf_reader::pair is a std::pair<string,string>
+  typedef std::pair<std::string,std::string> pair;
+  /** No argument constructor; actually calls read() without a filename.
+  **/
+  conf_reader();
+  /** NOP virtual destructor to allow safe inheritance.
+  **/
+  virtual ~conf_reader();
+  /** Reads and parses the command line and the provided file.
+  ** 
+  ** Returns the number of values stored. argc and argv are, of 
+  ** course the same names you used as arguments to main(). Therefore
+  ** you can easily read all command line and configuration file 
+  ** values like this:
+  ** 
+  ** int main(int argc, char* argv[])
+  **
+  ** {
+  **
+  ** 	conf_reader config;
+  **
+  ** 	config.read(argc,argv,"my_conf_file");
+  **
+  ** 	...
+  **
+  ** }
+  ** 
+  ** See read(filename,_clear) for a discription of how configuration
+  ** files are structured and parsed. This method unconditionally
+  ** clears the existing value list before starting. For command line
+  ** arguments the following rules are true.
+  ** 
+  ** 1. The executable name (argv[0]) is stored as a value with the 
+  **    name "__exec_name".
+  **   
+  ** 2. Command line arguments of the form "name=value" are parsed
+  **    stored as named values.
+  ** 
+  ** 3. All other command line arguments are stored as names with 
+  **    value = "".
+  **    
+  ** 4. A command line argument of form "configfile=filename" will
+  **    override the filename supplied as an argument to this method.
+  **    
+  ** 5. In the case of duplicate command line arguments, the last one 
+  **    specified wins.
+  **    
+  ** 6. In the case of names in the configuration file duplicating 
+  **    names from the command line, the values from the command line
+  **    dominate. If there were multiple values for a given name 
+  **    specified in the file, only the first one (the one returned by
+  **    the "[]" operator or get<>() method) is overridden.
+  **/
+  unsigned int read(int argc, char* argv[], 
+	  const std::string & _filename);
+  /// clears the name/value list.
+  void clear();
+  /// returns an iterator to the first item in the list.
+  iterator begin();
+  /// returns an iterator one past the end of the list.
+  iterator end();
+  /// True if there are no values, false otherwise.
+  bool empty();
+  /// Returns the number of values stored.
+  unsigned int size();
+  /** Returns the string value matching the supplied name.
+  ** 
+  ** NOTE: the use of get<T>(key) or get<T>(key,default) is preferred.
+  ** This method is public to allow for specialized handling in the
+  ** rare cases where it may be required.
+  ** 
+  ** If there are no matching names, "" is returned. Be aware that
+  ** "" is a valid value, so you can not use this to verify that
+  ** a given name was defined. Use exists() for that.
+  **/
+  std::string operator [] (const std::string & key);
+  /** Returns all values associated with the supplied name.
+  ** 
+  ** NOTE: the use of getall<T>(key) is preferred. This method is 
+  ** public to allow specialized handling in rare case where it
+  ** may be required.
+  ** 
+  ** If there are no values defined  the strlist will be empty.
+  **/
+  strlist all(const std::string & key);
+  /// True if the name exists, false otherwise.
+  bool exists(const std::string & key);
+  /** Use this to get all matching values.
+  ** 
+  ** Usage:
+  ** 
+  ** vector<type> mylist = conf_reader_object.getall<type>(key);
+  ** 
+  ** type can be any standard type (string, int, double, etc.) or any
+  ** type for which the ">>" stream operator is defined. All values
+  ** with matching names that can map to the requested type will be
+  ** returned. Any that do not map will not be returned.
+  **/
+  template < class T >
+    typename std::vector<T> getall(const std::string & key);
+  /** Use this to get the matching value.
+  ** 
+  ** Useage:
+  ** 
+  ** type myvar = get<type>(key);
+  ** 
+  ** type can be any standard type (string, int, double, etc.) or any
+  ** type for which the ">>" stream operator is defined. The return
+  ** value is initialized to all zeros if no matching name is found or
+  ** if the first value with that name does not map to the requested 
+  ** type. For the numeric types that results in zero being returned,
+  ** but be aware that more complex object may be in non-sensible
+  ** states if they were not found or could not map. Use exists() to 
+  ** verify the existance of a given name if needed.
+  **/
+  template < class T >
+    T get(const std::string & key);
+  /** Returns the value for the requested key, or the supplied default.
+  ** 
+  ** Works exactly like get<>() with the exception that if the key
+  ** is not found in the list, the user supplied default value is
+  ** returned instead of 0 or an empty string. If the value exists but
+  ** can not map to the requested type, 0 or an empty string is 
+  ** returned for the standard types.
+  **/
+  template <class T>
+    T get(const std::string & key, const T & def);
+private:
+  std::string filename;
+protected:
+  /** Reads and parses a configuration file.
+  ** 
+  ** Returns the number of values stored.
+  ** 
+  ** The optional parameter _clear when true clears the currently
+  ** stored list of values. if false the new values read will be added
+  ** to the existing list.
+  ** 
+  ** If the file named can not be processed completely, a warning
+  ** message is published to cerr. 
+  ** 
+  ** Configuration files are defined as follows.
+  ** 
+  ** 1. Files are read line by line. No value can cross a newline
+  **    (and at least in this version) or include one. The good
+  **    news is that you are allowed up to 16k for each line.
+  **    
+  ** 2. values are specifed in name/value pairs, one per line, with
+  ** 	 the name first, followed by whitespace, followed by the 
+  ** 	 value. Values may include whitespace. All leading and trailing
+  ** 	 whitespace is removed from both the name and the value.
+  ** 	 
+  ** 3. Comments start with a \# symbol; all text following a \# is
+  **    ignored. If you need to use \# in a name or value, escape
+  **    it with a backslash instead.
+  **    
+  ** 4. Duplicate names are allowed.
+  ** 
+  ** 5. Names without values will be stored with "" as the value.
+  ** 
+  ** 6. A configuration file may include another configuration file
+  **    automatically by the use of the "*INCLUDE" reserved name.
+  **    When this name is found, it's value is used as the name of
+  **    the new file to be read.
+  **/
+  unsigned int read(const std::string & _filename = "", bool _clear=true);
 };
 
 typedef singleton<conf_reader> global_conf_reader;
 
 template < class T >
-	typename std::vector<T> conf_reader::getall(const std::string & key)
-{
-	strlist tvals = all(key);
-	std::vector<T> returnme;
-	if (typeid(T) == typeid(std::string))
-	{
-		// T is a std::string.. we can do this quickly.
-		strlist * wl = (strlist *) &returnme;
-		*wl = tvals;
-	}
-	else
-	{
-		// T is non-string.. will require more playing around.
-		unsigned int limit = tvals.size();
-		for (unsigned int i = 0; i < limit; i++)
-		{
-			try
-			{
-				returnme.push_back(boost::lexical_cast<T>(tvals[i]));	
-			}
-			catch (...) {};
-		};
-	};
-	return returnme;
-};
-
-template < class T >
-	T conf_reader::get(const std::string & key)
-{
-	conf_reader & me = *this;
-	std::string tval = me[key];
-	T returnme;
-	// initialize the return value to nulls
-	// Needed for the numeric types, but bad for strings.
-	if (typeid(T) != typeid(std::string))
-	{
-		// null out the working area (death for strings!)
-		memset(&returnme,0,sizeof(T));
-	};
-	// This does appear to work for all the standard types.
-	if (tval != "")
-	{
-		try
-		{
-			returnme = boost::lexical_cast<T>(tval);
-		}
-		catch (...) {};
-	};
-	return returnme;
-};
-
-template < class T >
-	T conf_reader::get(const std::string & key, const T & def)
-{
-	if (exists(key)) { return get<T>(key); }
-	else { return def; };
+  typename std::vector<T> conf_reader::getall(const std::string & key)
+{
+  strlist tvals = all(key);
+  std::vector<T> returnme;
+  if (typeid(T) == typeid(std::string))
+  {
+    // T is a std::string.. we can do this quickly.
+    strlist * wl = (strlist *) &returnme;
+    *wl = tvals;
+  }
+  else
+  {
+    // T is non-string.. will require more playing around.
+    unsigned int limit = tvals.size();
+    for (unsigned int i = 0; i < limit; i++)
+    {
+      try
+      {
+	returnme.push_back(boost::lexical_cast<T>(tvals[i]));	
+      }
+      catch (...) {};
+    };
+  };
+  return returnme;
+};
+
+template < class T >
+  T conf_reader::get(const std::string & key)
+{
+  conf_reader & me = *this;
+  std::string tval = me[key];
+  T returnme;
+  // initialize the return value to nulls
+  // Needed for the numeric types, but bad for strings.
+  if (typeid(T) != typeid(std::string))
+  {
+    // null out the working area (death for strings!)
+    memset(&returnme,0,sizeof(T));
+  };
+  // This does appear to work for all the standard types.
+  if (tval != "")
+  {
+    try
+    {
+      returnme = boost::lexical_cast<T>(tval);
+    }
+    catch (...) {};
+  };
+  return returnme;
+};
+
+template < class T >
+  T conf_reader::get(const std::string & key, const T & def)
+{
+  if (exists(key)) { return get<T>(key); }
+  else { return def; };
 };
 
 }; // namespace nrtb
 
-#endif // ricklib_confreader_h
+#endif // nrtb_confreader_h
 

=== modified file 'cpp/common/confreader/conftest.cpp'
--- obsolete/Cpp/common/confreader/conftest.cpp	2011-08-13 15:06:08 +0000
+++ cpp/common/confreader/conftest.cpp	2013-08-09 21:47:12 +0000
@@ -19,54 +19,56 @@
 /* confreader test program */
 
 #include "confreader.h"
-#include <log_setup.h>
 #include <iostream>
-#include "Poco/Logger.h"
-#include "Poco/SimpleFileChannel.h"
-//#include "Poco/AutoPtr.h"
 
 using namespace nrtb;
 using namespace std;
 
+log_queue lq;
+log_file_writer writer(lq, "conf_test.log");
+
 int main(int argc, char* argv[])
 {
   bool set_if_failed = false;
-  setup_global_logging("conf_test.log");
-  Poco::Logger & log = Poco::Logger::get("conftest");
-  log.information("=-=-=-=-=-= conftest Init =-=-=-=-=-=-=");
-  global_conf_reader & config = global_conf_reader::get_instance();
+  log_recorder log("config_test",lq);  
+  log.info("=-=-=-=-=-= conftest Init =-=-=-=-=-=-=");
+  conf_reader &  config = global_conf_reader::get_reference();
+
   try
   {
-	log.information("Starting read");
-	config.read(argc,argv,"test.config");
+    log.info("Starting read");
+    config.read(argc,argv,"test.config");
   }
   catch (...)
   {
-	set_if_failed = true;
-	cerr << "Failed reading the configuration." << endl;
+    set_if_failed = true;
+    cerr << "Failed reading the configuration." << endl;
+    log.severe("Failed reading the configuration.");
   };
   if (config.size() != 12)
   {
-	set_if_failed = true;
-	cerr << "Did not find 12 parameters." << endl;
+    set_if_failed = true;
+    cerr << "Did not find 12 parameters." << endl;
+    log.severe("Did not find 12 parameters.");
   };
   // iterator test
   try
   {
-	conf_reader::iterator c = config.begin();
-	conf_reader::iterator e = config.end();
-	while (c != e)
-	{
-		cout << "\t\"" <<  c->first << "\"=\"" << c->second 
-			<< "\"" <<  endl;
-		c++;
-	};
+    conf_reader::iterator c = config.begin();
+    conf_reader::iterator e = config.end();
+    while (c != e)
+    {
+      cout << "\t\"" <<  c->first << "\"=\"" << c->second 
+	  << "\"" <<  endl;
+      c++;
+    };
   }
   catch (...)
   {
-	set_if_failed = true;
-	cerr << "Iterator test failed." << endl;
-  };
+    set_if_failed = true;
+    cerr << "Iterator test failed." << endl;
+    log.severe("Iterator test failed.");
+};
   // template test.
   int test = config.get<int>("test",-1);
   int test2 = config.get<int>("test2",-1);
@@ -74,56 +76,60 @@
   double test4 = config.get<double>("test",-1);
   double test5 = config.get<double>("test2",-1);
   cout << "(int) test = " << test 
-	<< "\n(int) test2 = " << test2 
-	<< "\n(string) test3 = \"" << test3 << "\""
-	<< "\n(double) test = " << test4
-	<< "\n(double) test2 = " << test5 
-	<< endl;
+    << "\n(int) test2 = " << test2 
+    << "\n(string) test3 = \"" << test3 << "\""
+    << "\n(double) test = " << test4
+    << "\n(double) test2 = " << test5 
+    << endl;
   if ( 
-	(test != 1) or (test2 != 0)
-	or (test3 != "jack danials")
-	or (test4 != 1.0) or (test5 != 71.837486)
+    (test != 1) or (test2 != 0)
+    or (test3 != "jack danials")
+    or (test4 != 1.0) or (test5 != 71.837486)
   )
   {
-	set_if_failed = true;
-	cerr << "** Template test failed." << endl;
+    set_if_failed = true;
+    cerr << "** Template test failed." << endl;
+    log.severe("** Template test failed.");
   };
   // exists test.
   cout << "?var \"--doit\" exists? " 
-	  << (config.exists("--doit") ? "Yes" : "No")
-	  << endl;
+    << (config.exists("--doit") ? "Yes" : "No")
+    << endl;
   if (!config.exists("--doit"))
   {
-	set_if_failed = true;
-	cerr << "exists() test failed." << endl;
+    set_if_failed = true;
+    cerr << "exists() test failed." << endl;
+    log.severe("exists() test failed.");
   };
   vector<int> intlist = config.getall<int>("test");
   cout << "valid int \"test\" values:" << endl;
   for (unsigned int i=0; i < intlist.size(); i++)
   {
-	  cout << "\t" << i << ": " << intlist[i] << endl;
+    cout << "\t" << i << ": " << intlist[i] << endl;
   };
   if (intlist.size() != 2)
   {
-	set_if_failed = true;
-	cerr << "getall<int>() did not find 2 parameters." << endl;
+    set_if_failed = true;
+    cerr << "getall<int>() did not find 2 parameters." << endl;
+    log.severe("getall<int>() did not find 2 parameters.");
   };
   strlist strings = config.getall<string>("test");
   cout << "valid string \"test\" values:" << endl;
   for (unsigned int i=0; i < strings.size(); i++)
   {
-	  cout << "\t" << i << ": " << strings[i] << endl;
+    cout << "\t" << i << ": " << strings[i] << endl;
   };
   if (strings.size() != 3)
   {
-	set_if_failed = true;
-	cerr << "getall<string>() did not find 3 parameters." << endl;
+    set_if_failed = true;
+    cerr << "getall<string>() did not find 3 parameters." << endl;
+    log.severe("getall<string>() did not find 3 parameters.");
   };
   if (set_if_failed) 
   {
-	cerr << "** ntrb::conf_reader UNIT TEST FAILED. **" << endl;
-	log.fatal("UNIT TEST FAILED");
+    cerr << "** ntrb::conf_reader UNIT TEST FAILED. **" << endl;
+    log.critical("UNIT TEST FAILED");
   };
-  log.information("Run Complete");
+  log.info("Run Complete");
   return set_if_failed;
 };

=== modified file 'cpp/common/linear_queue/Makefile'
--- obsolete/Cpp/common/linear_queue/Makefile	2012-04-06 17:18:50 +0000
+++ cpp/common/linear_queue/Makefile	2013-08-09 21:47:12 +0000
@@ -16,6 +16,8 @@
 #
 #***********************************************
 
+switches=-std=gnu++11 -D _GLIBCXX_USE_SCHED_YIELD -D _GLIBCXX_USE_NANOSLEEP
+
 lib:	linear_queue_test
 	@./linear_queue_test
 	@cp -v linear_queue.h ../include
@@ -23,8 +25,8 @@
 
 linear_queue_test:	linear_queue.h linear_queue_test.cpp
 	@rm -f linear_queue_test
-	g++ -c linear_queue_test.cpp -I../include -std=gnu++0x
-	g++ -o linear_queue_test linear_queue_test.o ../obj/common.o ../obj/base_thread.o -lpthread -std=gnu++0x
+	g++ -c linear_queue_test.cpp -I../include ${switches}
+	g++ -o linear_queue_test linear_queue_test.o -lpthread ${switches}
 
 clean:
 	@rm -rvf *.o linear_queue_test ../include/linear_queue.h *.log ../obj/linear_queue.o

=== modified file 'cpp/common/linear_queue/linear_queue.h'
--- obsolete/Cpp/common/linear_queue/linear_queue.h	2011-10-07 00:01:15 +0000
+++ cpp/common/linear_queue/linear_queue.h	2013-08-09 21:47:12 +0000
@@ -19,9 +19,11 @@
 #ifndef nrtb_linear_queue_h
 #define nrtb_linear_queue_h
 
-#include <iostream>
-#include <base_thread.h>
-#include <list>
+#include <atomic>
+#include <mutex>
+#include <condition_variable>
+#include <queue>
+#include <abs_queue.h>
 
 namespace nrtb
 {
@@ -45,120 +47,7 @@
  * passing data to another set of threads.
 ********************************************************/
 template <class T>
-class linear_queue
-{
-public:
-    class queue_not_ready: public base_exception {};
-
-    /*********************************************
-      * creates the queue with the specified
-      * number of elements. 
-    *********************************************/
-    linear_queue();
-
-    /*********************************************
-      * releases all items in the queue
-    *********************************************/
-    virtual ~linear_queue();
-
-    /*********************************************
-      * Puts an item in the queue.
-    *********************************************/
-    void push(T item);
-
-    /*********************************************
-      * Pops the next item off the queue, blocking
-      * if needed until an item becomes available.
-    *********************************************/
-    T pop();
-
-    /*********************************************
-     * puts the queue in shutdown mode.
-    *********************************************/
-    void shutdown();
-
-    // returns the number of items in the queue
-    int size();
-    // clears the buffer, data will be discarded.
-    void clear();
-
-protected:
-
-    std::list<T> buffer;
-    cond_variable buffer_lock;
-    bool ready;
-};
-
-template <class T>
-linear_queue<T>::linear_queue()
-{
-    ready = true;
-};
-
-template <class T>
-linear_queue<T>::~linear_queue()
-{
-};
-
-template <class T>
-void linear_queue<T>::push(T item)
-{
-  if (ready)
-  {
-	scope_lock lock(buffer_lock);
-    buffer.push_back(item);
-    buffer_lock.signal();
-  }
-  else 
-  {
-	queue_not_ready e;
-	  throw e;
-  }
-};
-
-template <class T>
-T linear_queue<T>::pop()
-{
-    scope_lock lock(buffer_lock);
-    while (buffer.empty() && ready)
-        buffer_lock.wait();
-    if (!ready)
-    {
-        queue_not_ready e;
-        throw e;
-    };
-	T returnme = buffer.front();
-	buffer.pop_front();
-	return returnme;
-};
-
-template <class T>
-void linear_queue<T>::shutdown()
-{
-  try
-  {
-	scope_lock lock(buffer_lock);
-	ready = false;
-	buffer_lock.broadcast_signal();
-	buffer.clear();
-  }
-  catch (...) {}  
-}
-
-
-template <class T>
-int linear_queue<T>::size()
-{
-    scope_lock lock(buffer_lock);
-    return buffer.size();
-};
-
-template <class T>
-void linear_queue<T>::clear()
-{
-    scope_lock lock(buffer_lock);
-    buffer.clear();
-};
+class linear_queue : public abs_queue<T,std::queue<T>> {};
 
 } // namespace nrtb
 

=== modified file 'cpp/common/linear_queue/linear_queue_test.cpp'
--- obsolete/Cpp/common/linear_queue/linear_queue_test.cpp	2011-10-07 00:01:15 +0000
+++ cpp/common/linear_queue/linear_queue_test.cpp	2013-08-09 21:47:12 +0000
@@ -15,81 +15,45 @@
  along with NRTB.  If not, see <http://www.gnu.org/licenses/>.
  
  **********************************************/
- 
+
+#include <unistd.h> // included for usleep()
 #include <string>
 #include <iostream>
 #include "linear_queue.h"
-#include <boost/shared_ptr.hpp>
+#include <memory>
+#include <atomic>
+#include <future>
 
 using namespace nrtb;
 using namespace std;
 
 typedef linear_queue<int> test_queue;
-typedef boost::shared_ptr<test_queue> queue_p;
+typedef shared_ptr<test_queue> queue_p;
 
-class consumer_task: public thread
+int consumer_task(string name, queue_p input)
 {
-public:
-
-  consumer_task(string n, queue_p buffer)
-  {
-	name = n;
-	input = buffer;
-	count = 0;
-  };
-  
-  ~consumer_task()
-  {
-	cout << ">> in " << name << "::~consumer_task()" << endl;
-	try
-	{
-	  this->thread::~thread();
-	  input.reset();
-	}
-	catch (...)  {};
-	cout << "<< leaving " << name << "::~consumer_task()" << endl;
-  };
-  
-  int get_count() { return count; };
-  
-  void run()
-  {
-	try
-	{
-	  while (true)
-	  {
-		int num = input->pop();
-		{
-		  static mutex console;
-		  scope_lock lock(console);
-		  cout << name << " picked up " << num
-			<< endl;
-		};
-		count++;
-		lastnum = num;
-		yield();	  
-	  }
-	}
-	catch (...) {};
-  };
-
-protected:
-  // link to the feed queue
-  queue_p input;
-  // a name to report 
-  string name;
-  // number of items processed
-  int count;
-  // last number caught
-  int lastnum;
+  bool ready {true};
+  int count {0};
+  try
+  {
+    while (ready)
+    {
+      int num = input->pop();
+      count++;
+      usleep(1);	  
+    }
+  }
+  catch (...) 
+  { 
+    // exit if we get any exception.
+    ready = false; 
+  };
+  return count;
 };
 
-typedef boost::shared_ptr<consumer_task> task_p;
-
-
 int main()
 {
-  int er_count = 0;
+  cout << "***** linear_queue unit test ******" << endl;
   /************************************************
    * Load queue and then cook it down...
    ***********************************************/
@@ -97,14 +61,15 @@
   queue_p q1(new test_queue());
   for (int i=0; i<100; i++)
   {
-	q1->push(i);
+    q1->push(i);
   };
-  // the queue should be loaded with 50-99
+  // the queue should be loaded with 0-99
   // attach a thread and process it.
-  task_p p1(new consumer_task("task 1",q1));
-  p1->start();
+  auto t1 = async(launch::async,consumer_task,"task 1",q1);
   while (q1->size()) usleep(100);
-  cout << "cp 1 " << p1->get_count() << endl;
+  cout << "cp 1 " 
+    << q1->in_count << ":"
+    << q1->out_count << endl;
   /************************************************
    * now that the preload is exhasted, shove items
    * in one at a time to make sure each is picked
@@ -112,40 +77,42 @@
    ***********************************************/
   for (int i=200; i<225; i++)
   {
-	q1->push(i);
-	usleep(100);
+    q1->push(i);
+    usleep(100);
   };
-  cout << "cp 2 " << p1->get_count() << endl;
+  cout << "cp 2 " 
+    << q1->in_count << ":"
+    << q1->out_count << endl;
   /************************************************
    * Last check; attach a second thread to the queue
    * and make sure both are servicing it.
    ***********************************************/
-  task_p p2(new consumer_task("task 2",q1));
-  p2->start();
+  auto t2 = async(launch::async,consumer_task,"task 2",q1);
   for (int i=300; i<325; i++)
   {
-	q1->push(i);
+    q1->push(i);
   };
   while (q1->size()) usleep(100);
   // shut it all down
   q1->shutdown();
-  p1->join();
-  p2->join();
   // important numbers
-  int tot_items = p1->get_count() + p2->get_count();
-  int p1_items = p1->get_count() - 125;
-  int p2_items = p2->get_count();
-  // release she threads and queues.
-  p1.reset();
-  p2.reset();
+  int t1_count = t1.get();
+  int t2_count = t2.get();
+  int q1_in = q1->in_count;
+  int q1_out = q1->out_count;
+  // release the queues.
   q1.reset();
   // do some reporting.
   cout << "cp 3 " 
-	<<  tot_items
-	<< " [125 + (" << p1_items
-	<< " + " << p2_items 
-	<< ")]" << endl;
-	bool passed = (tot_items == 150);
+    << q1_in << ":" << q1_out
+    << " t1=" << t1_count
+    << " t2=" << t2_count
+    << endl;
+  bool passed = (q1_in == q1_out) 
+    and (q1_out == (t1_count + t2_count));
+  cout << "***** linear_queue TEST "
+    << (passed ? "PASSED" : "FAILED")
+    << " ******" << endl;
   // inverted logic needed because 0 is good for 
   // return codes.
   return !passed; 

=== modified file 'cpp/common/logger/Makefile'
--- obsolete/Cpp/common/logger/Makefile	2012-04-06 17:42:05 +0000
+++ cpp/common/logger/Makefile	2013-08-09 21:47:12 +0000
@@ -1,5 +1,5 @@
 #***********************************************
-#This file is part of the NRTB project (https://launchpad.net/nrtb).
+# This file is part of the NRTB project (https://launchpad.net/nrtb).
 #
 #    NRTB is free software: you can redistribute it and/or modify
 #    it under the terms of the GNU General Public License as published by
@@ -16,27 +16,25 @@
 #
 #***********************************************
 
-lib:	log_test
-	@echo "Testing..."
-	@rm -f test_output.log
-	@./log_test
-	@grep "Program run complete." test_output.log
-	@cp -fv log_setup.h ../include
-	@cp -fv log_setup.o ../obj
-
-
-log_setup.o:	log_setup.h log_setup.cpp Makefile
-	@rm -f log_setup.o
-	g++ -c log_setup.cpp -I ../include -std=gnu++0x
-
-log_test:	log_setup.o log_test.cpp Makefile
-	@rm -vf log_test
-	g++ -c log_test.cpp -I../include  -std=gnu++0x
-	g++ -o log_test log_setup.o log_test.o -lPocoFoundation -std=gnu++0x
-#	g++ -g common_test.cpp  -idirafter . -o common_test
+switches=-std=gnu++11 -D _GLIBCXX_USE_SCHED_YIELD -D _GLIBCXX_USE_NANOSLEEP
+
+lib:	logger_test
+	@./logger_test
+	@cp -v logger.h ../include/
+	@cp -v logger.o ../obj/
+	@echo build complete
+
+logger_test:	logger.o logger_test.cpp
+	@rm -f logger_test
+	g++ -c -O3 logger_test.cpp -I ../include ${switches} 
+	g++ -o logger_test logger_test.o logger.o -lpthread ${switches}
+
+
+logger.o:	logger.cpp logger.h Makefile
+	@rm -f logger.o
+	g++ -c -O3 logger.cpp -I ../include ${switches} 
 
 clean:
-	@rm -vf *.o log_test ../include/log_setup.h ../obj/log_setup.o test_output.log
-
-
+	@rm -vf *.o ../include/logger.h logger_test
+	@echo all objects and executables have been erased.
 

=== added file 'cpp/common/logger/logger.cpp'
--- cpp/common/logger/logger.cpp	1970-01-01 00:00:00 +0000
+++ cpp/common/logger/logger.cpp	2013-08-09 21:47:12 +0000
@@ -0,0 +1,141 @@
+/***********************************************
+ This file is part of the NRTB project (https://*launchpad.net/nrtb).
+ 
+ NRTB is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+ 
+ NRTB 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 General Public License for more details.
+ 
+ You should have received a copy of the GNU General Public License
+ along with NRTB.  If not, see <http://www.gnu.org/licenses/>.
+ 
+ **********************************************/
+
+// see base_socket.h for documentation
+
+#include "logger.h"
+#include <fstream>
+#include <iomanip>
+#include <sstream>
+#include <ctime>
+#include <unistd.h>
+
+namespace nrtb
+{
+  
+std::string sev2text(log_sev s)
+{
+  std::string returnme;
+  switch (s)
+  {
+    case log_sev::critical : returnme = "CRITICAL"; break;
+    case log_sev::severe : returnme = "SEVERE"; break;
+    case log_sev::warning :  returnme = "WARNING"; break;
+    case log_sev::info : returnme = "INFO"; break;
+    case log_sev::trace : returnme = "TRACE"; break;
+    default: returnme = "Undefined";
+  };
+  return returnme;
+};
+
+log_record::log_record(log_sev s, std::string c, std::string m)
+{
+  created = std::time(NULL);
+  severity = s;
+  component = c;
+  message = m;
+};
+
+void log_recorder::operator()(log_sev sev, std::string msg)
+{
+  log_record tr(sev, component, msg);
+  my_queue.push(tr);
+};
+
+void log_recorder::critical(std::string msg)
+{
+  (*this)(log_sev::critical,msg);
+};
+
+void log_recorder::severe(std::string msg)
+{
+  (*this)(log_sev::severe, msg);
+};
+
+void log_recorder::warning(std::string msg)
+{
+  (*this)(log_sev::warning, msg);
+};
+
+void log_recorder::info(std::string msg)
+{
+  (*this)(log_sev::info, msg);
+};
+
+void log_recorder::trace(std::string msg)
+{
+  (*this)(log_sev::trace, msg);
+};
+
+log_file_writer::log_file_writer(log_queue& queue, std::string filename)
+  : myqueue(queue)
+{
+  // start the writer
+  writer_process = 
+    std::thread(log_file_writer::writer_thread,
+		  std::ref(queue),filename);
+};
+
+void log_file_writer::close()
+{
+  // Hang around long enough to drain the queue.
+  while (myqueue.size())
+      usleep(100);
+  // Shutdown the queue, terminate the worker thread.
+  myqueue.shutdown();
+};
+
+log_file_writer::~log_file_writer()
+{
+  close();
+  // Wait for the worker to close down.
+  if (writer_process.joinable())
+    writer_process.join();
+};
+
+void log_file_writer::writer_thread(log_queue& q, std::string fname)
+{
+  bool done {false};
+  std::ofstream output;
+  output.open(fname);
+  while (!done)
+  {
+    try 
+    { 
+      log_record record = q.pop();
+      std::tm tm = *std::localtime(&record.created);
+      std::stringstream s;
+      s << tm.tm_year + 1900
+	<< "-" << tm.tm_mon + 1
+	<< "-" << tm.tm_mday
+	<< ":" << tm.tm_hour
+	<< ":" << tm.tm_min
+	<< ":" << tm.tm_sec
+	<< "\t" << sev2text(record.severity)
+	<< "\t" << record.component
+	<< "\t" << record.message;
+      output << s.str()
+	<< std::endl;
+    }
+    catch (...) { done = true; };
+  };
+  output.close();
+};
+
+} // namqespace nrtb
+

=== added file 'cpp/common/logger/logger.h'
--- cpp/common/logger/logger.h	1970-01-01 00:00:00 +0000
+++ cpp/common/logger/logger.h	2013-08-09 21:47:12 +0000
@@ -0,0 +1,76 @@
+/***********************************************
+ This file is part of the NRTB project (https://*launchpad.net/nrtb).
+ 
+ NRTB is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+ 
+ NRTB 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 General Public License for more details.
+ 
+ You should have received a copy of the GNU General Public License
+ along with NRTB.  If not, see <http://www.gnu.org/licenses/>.
+ 
+ **********************************************/
+ 
+#ifndef logger_header
+#define logger_header
+
+#include <string>
+#include <chrono>
+#include <thread>
+#include <ctime>
+#include <linear_queue.h>
+
+namespace nrtb
+{
+
+enum class log_sev {critical,severe,warning,info,trace};
+
+std::string sev2text(log_sev s);
+
+struct log_record
+{
+  log_record(log_sev s, std::string c, std::string m);
+  std::time_t created; 
+  log_sev severity;
+  std::string component;
+  std::string message;
+};
+
+typedef linear_queue<log_record> log_queue;
+
+class log_recorder
+{
+public:
+  log_recorder(std::string comp, log_queue & queue): 
+    component(comp), my_queue(queue) {};
+  void operator () (log_sev sev, std::string msg);
+  void critical(std::string msg);
+  void severe(std::string msg);
+  void warning(std::string msg);
+  void info(std::string msg);
+  void trace(std::string msg);
+private:
+  log_queue & my_queue;
+  std::string component;
+};
+
+class log_file_writer
+{
+public:
+  log_file_writer(log_queue & queue, std::string filename);
+  ~log_file_writer();
+  void close();
+private:
+  log_queue & myqueue;
+  std::thread writer_process;
+  static void writer_thread(log_queue & q, std::string fname);
+};
+
+} // namepace nrtb
+
+#endif // logger_header

=== added file 'cpp/common/logger/logger_test.cpp'
--- cpp/common/logger/logger_test.cpp	1970-01-01 00:00:00 +0000
+++ cpp/common/logger/logger_test.cpp	2013-08-09 21:47:12 +0000
@@ -0,0 +1,105 @@
+/***********************************************
+ This file is part of the NRTB project (https://*launchpad.net/nrtb).
+ 
+ NRTB is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+ 
+ NRTB 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 General Public License for more details.
+ 
+ You should have received a copy of the GNU General Public License
+ along with NRTB.  If not, see <http://www.gnu.org/licenses/>.
+ 
+ **********************************************/
+
+#include "logger.h"
+#include <sstream>
+#include <iostream>
+#include <boost/concept_check.hpp>
+
+using namespace nrtb;
+using namespace std;
+
+int ecount {0};
+
+string stext_test(string a, log_sev b)
+{
+  stringstream s;
+  s << a  << " " << (a == sev2text(b) ? "passed" : "failed");
+  if (a != sev2text(b)) ecount++;
+  return s.str();
+};
+
+int main()
+{
+  cout << "=========== logger unit test ============="
+    << endl;
+
+  log_queue test_logger;
+  log_recorder log("Unit_Test",test_logger);
+  log_file_writer writer(test_logger,"test_log.log");
+  
+  log.trace("Starting");
+  for(auto i= 0; i<10; i++)
+  {
+    stringstream s;
+    s << "Log entry " << i;
+    log(log_sev::info,s.str());
+  };
+  
+  log.trace("sev2test() testing");
+  log.info(stext_test("CRITICAL",log_sev::critical));
+  log.info(stext_test("SEVERE",log_sev::severe));
+  log.info(stext_test("WARNING",log_sev::warning));
+  log.info(stext_test("INFO",log_sev::info));
+  log.info(stext_test("TRACE",log_sev::trace));
+  
+  log.trace("Shutting down");
+  writer.close();
+  
+  bool good = (test_logger.in_count == test_logger.out_count);
+  good = good and (ecount == 0);
+  
+  // test status billboard
+  cout << test_logger.in_count
+    << " : " << test_logger.out_count
+    << " : " << ecount
+    << endl;
+  if (!good)
+    cout << "Errors reported.. check log file." << endl;
+  cout << "=========== tcp_socket and server test complete ============="
+    << endl;
+  
+  return !good; // return code has reversed values.
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

=== modified file 'cpp/common/point/Makefile'
--- obsolete/Cpp/common/point/Makefile	2012-04-06 17:42:40 +0000
+++ cpp/common/point/Makefile	2013-08-09 21:47:12 +0000
@@ -16,17 +16,16 @@
 #
 #***********************************************
 
+switches=-std=gnu++11 -D _GLIBCXX_USE_SCHED_YIELD -D _GLIBCXX_USE_NANOSLEEP
+
 lib:	common_test Makefile
 	@echo "(2,3.5,7)" | ./common_test 
 	@cp -v triad.h ../include
 	@echo nrtb::triad build complete
 
-../include/common.h:
-	@cd ../common_rl; make lib
-
-common_test:	common_test.cpp triad.h Makefile ../include/common.h
+common_test:	common_test.cpp triad.h Makefile
 	@rm -vf common_test
-	g++ -O3 common_test.cpp -I ../include ../obj/common.o -o common_test -std=gnu++0x
+	g++ -O3 common_test.cpp -I ../include ../obj/common.o -o common_test ${switches}
 
 clean:
 	@rm -vf *.o common_test ../include/triad.h

=== modified file 'cpp/common/point/common_test.cpp'
--- obsolete/Cpp/common/point/common_test.cpp	2011-07-27 02:27:23 +0000
+++ cpp/common/point/common_test.cpp	2013-08-09 21:47:12 +0000
@@ -32,8 +32,8 @@
   cout << "\t" << prompt << " = " << val << endl;
   if (val != right)
   {
-	ec++;
-	cerr << "\t\tTest Failed: Answer should be " << val << endl;
+    ec++;
+    cerr << "\t\tTest Failed: Answer should be " << val << endl;
   }
   return ec;
 };
@@ -43,75 +43,75 @@
   cout << "\t" << prompt << " = " << val << endl;
   if (val != right)
   {
-	ec++;
-	cerr << "\t\tTest Failed: Answer should be " << val << endl;
+    ec++;
+    cerr << "\t\tTest Failed: Answer should be " << val << endl;
   }
   return ec;
 };
 
 int main()
 {
-	ld_triad a(1,2,3);
-	ld_triad b(3,2,1);
-	int returnme = 0;
+  ld_triad a(1,2,3);
+  ld_triad b(3,2,1);
+  int returnme = 0;
 
-	cout << setprecision(10);
-	cout << "=== nrtb::triad Unit Test ===" << endl;
-	cout << "\ta = " << a << "; b = " << b << endl;
-	// basic operations tests
-	returnme = test_triad("a + b",a + b,ld_triad(4,4,4),returnme);
-	returnme = test_triad("a - b",a - b,ld_triad(-2,0,2),returnme);
-	returnme = test_triad("a * b",a * b,ld_triad(3,4,3),returnme);
-	returnme = test_triad("a / b",a / b,ld_triad(1.0d/(long double) 3.0,1,3),returnme);
-	returnme = test_triad("a += b; a",a += b,ld_triad(4,4,4),returnme);
-	returnme = test_triad("a -= b; a",a -= b,ld_triad(1,2,3),returnme);
-	returnme = test_triad("a *= b; a",a *= b,ld_triad(3,4,3),returnme);
-	returnme = test_triad("a /= b; a",a /= b,ld_triad(1,2,3),returnme);
-	// power test
-	returnme = test_triad("a.pow(b)",a.pow(b),ld_triad(1,4,3),returnme);
-	// range test
-	ld_triad t = b - a;
-	t *= t;
-	long double r = sqrt(t.x + t.y + t.z);
-	returnme = test_ld("a.range(b)",a.range(b),r,returnme);
-	// magnatude test
-	returnme = test_ld("a.magnatude()",a.magnatude(),a.range(0),returnme);
-	// boolean tests
-	returnme = test_ld("a == a",a == a,1,returnme);
-	returnme = test_ld("a == b",a == b,0,returnme);
-	returnme = test_ld("a != b",a != b,1,returnme);
-	returnme = test_ld("a != a",a != a,0,returnme);
-	// point/scalar operations
-	returnme = test_triad("a + 2",a + 2,ld_triad(3,4,5),returnme);
-	returnme = test_triad("a - 2",a - 2,ld_triad(-1,0,1),returnme);
-	returnme = test_triad("a * 2",a * 2,ld_triad(2,4,6),returnme);
-	returnme = test_triad("a / 2",a / 2,ld_triad(0.5,1,1.5),returnme);
-	returnme = test_triad("a += 2",a += 2,ld_triad(3,4,5),returnme);
-	returnme = test_triad("a -= 2",a -= 2,ld_triad(1,2,3),returnme);
-	returnme = test_triad("a *= 2",a *= 2,ld_triad(2,4,6),returnme);
-	returnme = test_triad("a /= 2",a /= 2,ld_triad(1,2,3),returnme);
-	returnme = test_triad("a.pow(2)",a.pow(2),ld_triad(1,4,9),returnme);
-	// normalization test
-	cout << "\ta.normalize() = " << a.normalize() << endl;
-	returnme = test_ld("a.normalize().magnatude()",a.normalize().magnatude(),1.0,returnme);
-	// dot and vector product tests.
-	returnme = test_ld("a.dot_product(b)",a.dot_product(b),10,returnme);
-	returnme = test_triad("a.vector_product(b)",a.vector_product(b),
-		ld_triad(-4,8,-4),returnme);
-	// string i/o tests, assumes "2,3.5,7) is input.
-	cout << "\tInput a new value for b \"(2,3.5,7)\": " << flush;
-	cin >> b; cout << endl;
-	returnme = test_triad("b",b,ld_triad(2,3.5,7),returnme);
-	returnme = test_triad("b.from_str(b.to_str(10))",
-					b.from_str(b.to_str(10)),ld_triad(2,3.5,7),returnme);
-	// report errors, if any
-	if (returnme)
-	{
-	  cerr << "There were " << returnme 
-		<< " error(s) found." << endl;
-	}
-	cout << "=== nrtb::triad Unit Test Complete ===" << endl;
-	// return the error count as the exit code
-	return returnme;
+  cout << setprecision(10);
+  cout << "=== nrtb::triad Unit Test ===" << endl;
+  cout << "\ta = " << a << "; b = " << b << endl;
+  // basic operations tests
+  returnme = test_triad("a + b",a + b,ld_triad(4,4,4),returnme);
+  returnme = test_triad("a - b",a - b,ld_triad(-2,0,2),returnme);
+  returnme = test_triad("a * b",a * b,ld_triad(3,4,3),returnme);
+  returnme = test_triad("a / b",a / b,ld_triad(1.0d/(long double) 3.0,1,3),returnme);
+  returnme = test_triad("a += b; a",a += b,ld_triad(4,4,4),returnme);
+  returnme = test_triad("a -= b; a",a -= b,ld_triad(1,2,3),returnme);
+  returnme = test_triad("a *= b; a",a *= b,ld_triad(3,4,3),returnme);
+  returnme = test_triad("a /= b; a",a /= b,ld_triad(1,2,3),returnme);
+  // power test
+  returnme = test_triad("a.pow(b)",a.pow(b),ld_triad(1,4,3),returnme);
+  // range test
+  ld_triad t = b - a;
+  t *= t;
+  long double r = sqrt(t.x + t.y + t.z);
+  returnme = test_ld("a.range(b)",a.range(b),r,returnme);
+  // magnatude test
+  returnme = test_ld("a.magnatude()",a.magnatude(),a.range(0),returnme);
+  // boolean tests
+  returnme = test_ld("a == a",a == a,1,returnme);
+  returnme = test_ld("a == b",a == b,0,returnme);
+  returnme = test_ld("a != b",a != b,1,returnme);
+  returnme = test_ld("a != a",a != a,0,returnme);
+  // point/scalar operations
+  returnme = test_triad("a + 2",a + 2,ld_triad(3,4,5),returnme);
+  returnme = test_triad("a - 2",a - 2,ld_triad(-1,0,1),returnme);
+  returnme = test_triad("a * 2",a * 2,ld_triad(2,4,6),returnme);
+  returnme = test_triad("a / 2",a / 2,ld_triad(0.5,1,1.5),returnme);
+  returnme = test_triad("a += 2",a += 2,ld_triad(3,4,5),returnme);
+  returnme = test_triad("a -= 2",a -= 2,ld_triad(1,2,3),returnme);
+  returnme = test_triad("a *= 2",a *= 2,ld_triad(2,4,6),returnme);
+  returnme = test_triad("a /= 2",a /= 2,ld_triad(1,2,3),returnme);
+  returnme = test_triad("a.pow(2)",a.pow(2),ld_triad(1,4,9),returnme);
+  // normalization test
+  cout << "\ta.normalize() = " << a.normalize() << endl;
+  returnme = test_ld("a.normalize().magnatude()",a.normalize().magnatude(),1.0,returnme);
+  // dot and vector product tests.
+  returnme = test_ld("a.dot_product(b)",a.dot_product(b),10,returnme);
+  returnme = test_triad("a.vector_product(b)",a.vector_product(b),
+	  ld_triad(-4,8,-4),returnme);
+  // string i/o tests, assumes "2,3.5,7) is input.
+  cout << "\tInput a new value for b \"(2,3.5,7)\": " << flush;
+  cin >> b; cout << endl;
+  returnme = test_triad("b",b,ld_triad(2,3.5,7),returnme);
+  returnme = test_triad("b.from_str(b.to_str(10))",
+				  b.from_str(b.to_str(10)),ld_triad(2,3.5,7),returnme);
+  // report errors, if any
+  if (returnme)
+  {
+    cerr << "There were " << returnme 
+      << " error(s) found." << endl;
+  }
+  cout << "=== nrtb::triad Unit Test Complete ===" << endl;
+  // return the error count as the exit code
+  return returnme;
 	
 };

=== modified file 'cpp/common/point/triad.h'
--- obsolete/Cpp/common/point/triad.h	2011-07-27 02:27:23 +0000
+++ cpp/common/point/triad.h	2013-08-09 21:47:12 +0000
@@ -43,265 +43,265 @@
 template <class T> 
 struct triad
 {
-	/// X coordinate
-	T x;
-	/// Y coordinate
-	T y;
-	/// Z coordinate
-	T z;
+  /// X coordinate
+  T x;
+  /// Y coordinate
+  T y;
+  /// Z coordinate
+  T z;
 
-	/** Constructor. 
-	 ** 
-	 ** An easy way to create a point at the origin would be 
-	 ** "triad<T> a;".
-	 **/
-	triad(T _x=0, T _y=0, T _z=0);
-	triad<T> operator + (const triad<T> & a);
-	triad<T> operator - (const triad<T> & a);
-	triad<T> operator * (const triad<T> & a);
-	triad<T> operator / (const triad<T> & a);
-	triad<T> operator += (const triad<T> & a);
-	triad<T> operator -= (const triad<T> & a);
-	triad<T> operator *= (const triad<T> & a);
-	triad<T> operator /= (const triad<T> & a);
-	/// returns (pow(x,a.x),pow(y,a.y),pow(z,a.z)).
-	triad<T> pow(const triad<T> & a);
-	triad<T> operator + (const T & a);
-	triad<T> operator - (const T & a);
-	triad<T> operator * (const T & a);
-	triad<T> operator / (const T & a);
-	triad<T> operator += (const T & a);
-	triad<T> operator -= (const T & a);
-	triad<T> operator *= (const T & a);
-	triad<T> operator /= (const T & a);
-	/// returns (pow(x,a),pow(y,a),pow(z,a)).
-	triad<T> pow(const T & a);
-	/** Returns a normalized version of the triad.
-	 ** 
-	 ** Normalization in this case refers to an operation resulting in a
-	 ** traid where the magnatude of the vector is 1.0 while maintaining the
-	 ** same angular component. For example, given triad<float> a = (1,2,3),
-	 ** a.normalize() = (0.267,0.534,0.802). Of course, the original triad
-	 ** is not modified.
-	 ** 
-	 ** Normalized triads are very useful when calcuating force or
-	 ** accelleration vectors, for example.
-	 **/
-	triad<T> normalize();
-	/// Returns the distance between *this and the supplied argument.
-	T range(const triad<T> & a);
-	/// Returns the magnatude of the vector.
-	T magnatude();
-	/// Returns the dot (scalar) product of two triads
-	T dot_product(const triad<T> & a);
-	/// Returns the vector product of two triads
-	triad<T> vector_product(const triad<T> & a);
-	bool operator == (const triad<T> & a);
-	bool operator != (const triad<T> & a);
-	/// Loads from a std::string.
-	triad<T> from_str(const std::string & a);
-	/// Returns a std::string representation.
-	std::string to_str(int precision=6);
+  /** Constructor. 
+    ** 
+    ** An easy way to create a point at the origin would be 
+    ** "triad<T> a;".
+    **/
+  triad(T _x=0, T _y=0, T _z=0);
+  triad<T> operator + (const triad<T> & a);
+  triad<T> operator - (const triad<T> & a);
+  triad<T> operator * (const triad<T> & a);
+  triad<T> operator / (const triad<T> & a);
+  triad<T> operator += (const triad<T> & a);
+  triad<T> operator -= (const triad<T> & a);
+  triad<T> operator *= (const triad<T> & a);
+  triad<T> operator /= (const triad<T> & a);
+  /// returns (pow(x,a.x),pow(y,a.y),pow(z,a.z)).
+  triad<T> pow(const triad<T> & a);
+  triad<T> operator + (const T & a);
+  triad<T> operator - (const T & a);
+  triad<T> operator * (const T & a);
+  triad<T> operator / (const T & a);
+  triad<T> operator += (const T & a);
+  triad<T> operator -= (const T & a);
+  triad<T> operator *= (const T & a);
+  triad<T> operator /= (const T & a);
+  /// returns (pow(x,a),pow(y,a),pow(z,a)).
+  triad<T> pow(const T & a);
+  /** Returns a normalized version of the triad.
+    ** 
+    ** Normalization in this case refers to an operation resulting in a
+    ** traid where the magnatude of the vector is 1.0 while maintaining the
+    ** same angular component. For example, given triad<float> a = (1,2,3),
+    ** a.normalize() = (0.267,0.534,0.802). Of course, the original triad
+    ** is not modified.
+    ** 
+    ** Normalized triads are very useful when calcuating force or
+    ** accelleration vectors, for example.
+    **/
+  triad<T> normalize();
+  /// Returns the distance between *this and the supplied argument.
+  T range(const triad<T> & a);
+  /// Returns the magnatude of the vector.
+  T magnatude();
+  /// Returns the dot (scalar) product of two triads
+  T dot_product(const triad<T> & a);
+  /// Returns the vector product of two triads
+  triad<T> vector_product(const triad<T> & a);
+  bool operator == (const triad<T> & a);
+  bool operator != (const triad<T> & a);
+  /// Loads from a std::string.
+  triad<T> from_str(const std::string & a);
+  /// Returns a std::string representation.
+  std::string to_str(int precision=6);
 };
 
 template <class T>
 triad<T>::triad(T _x, T _y, T _z)
 {
-	x = _x;
-	y = _y;
-	z = _z;
+  x = _x;
+  y = _y;
+  z = _z;
 };
 
 template <class T>
 triad<T> triad<T>::operator + (const triad<T> & a)
 {
-	triad<T> returnme;
-	returnme.x = x + a.x;
-	returnme.y = y + a.y;
-	returnme.z = z + a.z;
-	return returnme;
+  triad<T> returnme;
+  returnme.x = x + a.x;
+  returnme.y = y + a.y;
+  returnme.z = z + a.z;
+  return returnme;
 };
 
 template <class T>
 triad<T> triad<T>::operator - (const triad<T> & a)
 {
-	triad<T> returnme;
-	returnme.x = x - a.x;
-	returnme.y = y - a.y;
-	returnme.z = z - a.z;
-	return returnme;
+  triad<T> returnme;
+  returnme.x = x - a.x;
+  returnme.y = y - a.y;
+  returnme.z = z - a.z;
+  return returnme;
 };
 
 template <class T>
 triad<T> triad<T>::operator * (const triad<T> & a)
 {
-	triad<T> returnme;
-	returnme.x = x * a.x;
-	returnme.y = y * a.y;
-	returnme.z = z * a.z;
-	return returnme;
+  triad<T> returnme;
+  returnme.x = x * a.x;
+  returnme.y = y * a.y;
+  returnme.z = z * a.z;
+  return returnme;
 };
 
 template <class T>
 triad<T> triad<T>::operator / (const triad<T> & a)
 {
-	triad<T> returnme;
-	returnme.x = x / a.x;
-	returnme.y = y / a.y;
-	returnme.z = z / a.z;
-	return returnme;
+  triad<T> returnme;
+  returnme.x = x / a.x;
+  returnme.y = y / a.y;
+  returnme.z = z / a.z;
+  return returnme;
 };
 
 template <class T>
 triad<T> triad<T>::operator += (const triad<T> & a)
 {
-	x += a.x;
-	y += a.y;
-	z += a.z;
-	return *this;
+  x += a.x;
+  y += a.y;
+  z += a.z;
+  return *this;
 };
 
 template <class T>
 triad<T> triad<T>::operator -= (const triad<T> & a)
 {
-	x -= a.x;
-	y -= a.y;
-	z -= a.z;
-	return *this;
+  x -= a.x;
+  y -= a.y;
+  z -= a.z;
+  return *this;
 };
 
 template <class T>
 triad<T> triad<T>::operator *= (const triad<T> & a)
 {
-	x *= a.x;
-	y *= a.y;
-	z *= a.z;
-	return *this;
+  x *= a.x;
+  y *= a.y;
+  z *= a.z;
+  return *this;
 };
 
 template <class T>
 triad<T> triad<T>::operator /= (const triad<T> & a)
 {
-	x /= a.x;
-	y /= a.y;
-	z /= a.z;
-	return *this;
+  x /= a.x;
+  y /= a.y;
+  z /= a.z;
+  return *this;
 };
 
 template <class T>
 triad<T> triad<T>::pow(const triad<T> & a)
 {
-	triad<T> returnme;
-	returnme.x = ::pow(x,a.x);
-	returnme.y = ::pow(y,a.y);
-	returnme.z = ::pow(z,a.z);
-	return returnme;
+  triad<T> returnme;
+  returnme.x = ::pow(x,a.x);
+  returnme.y = ::pow(y,a.y);
+  returnme.z = ::pow(z,a.z);
+  return returnme;
 };
 
 template <class T>
 triad<T> triad<T>::normalize()
 {
-	return (*this / this->magnatude());
+  return (*this / this->magnatude());
 };
 
 template <class T>
 triad<T> triad<T>::operator + (const T & a)
 {
-	triad<T> returnme;
-	returnme.x = x + a;
-	returnme.y = y + a;
-	returnme.z = z + a;
-	return returnme;
+  triad<T> returnme;
+  returnme.x = x + a;
+  returnme.y = y + a;
+  returnme.z = z + a;
+  return returnme;
 };
 
 template <class T>
 triad<T> triad<T>::operator - (const T & a)
 {
-	triad<T> returnme;
-	returnme.x = x - a;
-	returnme.y = y - a;
-	returnme.z = z - a;
-	return returnme;
+  triad<T> returnme;
+  returnme.x = x - a;
+  returnme.y = y - a;
+  returnme.z = z - a;
+  return returnme;
 };
 
 template <class T>
 triad<T> triad<T>::operator * (const T & a)
 {
-	triad<T> returnme;
-	returnme.x = x * a;
-	returnme.y = y * a;
-	returnme.z = z * a;
-	return returnme;
+  triad<T> returnme;
+  returnme.x = x * a;
+  returnme.y = y * a;
+  returnme.z = z * a;
+  return returnme;
 };
 
 template <class T>
 triad<T> triad<T>::operator / (const T & a)
 {
-	triad<T> returnme;
-	returnme.x = x / a;
-	returnme.y = y / a;
-	returnme.z = z / a;
-	return returnme;
+  triad<T> returnme;
+  returnme.x = x / a;
+  returnme.y = y / a;
+  returnme.z = z / a;
+  return returnme;
 };
 
 template <class T>
 triad<T> triad<T>::operator += (const T & a)
 {
-	x += a;
-	y += a;
-	z += a;
-	return *this;
+  x += a;
+  y += a;
+  z += a;
+  return *this;
 };
 
 template <class T>
 triad<T> triad<T>::operator -= (const T & a)
 {
-	x -= a;
-	y -= a;
-	z -= a;
-	return *this;
+  x -= a;
+  y -= a;
+  z -= a;
+  return *this;
 };
 
 template <class T>
 triad<T> triad<T>::operator *= (const T & a)
 {
-	x *= a;
-	y *= a;
-	z *= a;
-	return *this;
+  x *= a;
+  y *= a;
+  z *= a;
+  return *this;
 };
 
 template <class T>
 triad<T> triad<T>::operator /= (const T & a)
 {
-	x /= a;
-	y /= a;
-	z /= a;
-	return *this;
+  x /= a;
+  y /= a;
+  z /= a;
+  return *this;
 };
 
 template <class T>
 triad<T> triad<T>::pow(const T & a)
 {
-	triad<T> returnme;
-	returnme.x = ::pow(x,a);
-	returnme.y = ::pow(y,a);
-	returnme.z = ::pow(z,a);
-	return returnme;
+  triad<T> returnme;
+  returnme.x = ::pow(x,a);
+  returnme.y = ::pow(y,a);
+  returnme.z = ::pow(z,a);
+  return returnme;
 };
 
 template <class T>
 T triad<T>::range(const triad<T> & a)
 {
-	triad<T> offset = *this - a;
-	offset *= offset;
-	return sqrt(offset.x + offset.y + offset.z);
+  triad<T> offset = *this - a;
+  offset *= offset;
+  return sqrt(offset.x + offset.y + offset.z);
 };
 
 template <class T>
 T triad<T>::magnatude()
 {
-	return sqrt((x*x) + (y*y) + (z*z));
+  return sqrt((x*x) + (y*y) + (z*z));
 };
 
 template <class T>
@@ -327,39 +327,39 @@
 template <class T>
 bool triad<T>::operator == (const triad<T> & a)
 {
-	return ((x == a.x) && (y == a.y) && (z == a.z));
+  return ((x == a.x) && (y == a.y) && (z == a.z));
 };
 
 template <class T>
 bool triad<T>::operator != (const triad<T> & a)
 {
-	return (! (*this == a));
+  return (! (*this == a));
 };
 
 template <class T>
 triad<T> triad<T>::from_str(const std::string & a)
 {
-	std::istringstream t(a.c_str());
-	t >> *this;
-	return *this;
+  std::istringstream t(a.c_str());
+  t >> *this;
+  return *this;
 };
 
 template <class T>
 std::string triad<T>::to_str(int precision)
 {
-	std::stringstream a;
-	a << std::setprecision(precision) << *this;
-	std::string returnme;
-	a >> returnme;
-	return returnme;
+  std::stringstream a;
+  a << std::setprecision(precision) << *this;
+  std::string returnme;
+  a >> returnme;
+  return returnme;
 };
 
 /// Writes the triad<T> in the format "(x,y,z)" to the output stream.
 template <class T>
 std::ostream & operator << (std::ostream &f, const triad<T> & a)
 {
-	f << "(" << a.x << "," << a.y << "," << a.z << ")";
-	return f;
+  f << "(" << a.x << "," << a.y << "," << a.z << ")";
+  return f;
 };
 
 /** Reads the triad<T> from an input stream.
@@ -372,22 +372,22 @@
 template <class T>
 std::istream & operator >> (std::istream &f, triad<T> & a)
 {
-	std::string element;
-	f >> element;
-	strlist t = split(element,',');
-	if (t.size() != 3)
-	{
-		a = 0;
-	}
-	else
-	{
-		std::stringstream transmorgrafier;
-		transmorgrafier << std::setprecision(30);
-		if (t[0][0] == '(') { t[0].erase(0,1); };
-		for(int i=0; i < 3; i++) { transmorgrafier << t[i] << " "; };
-		transmorgrafier >> a.x >> a.y >> a.z;
-	};
-	return f;
+  std::string element;
+  f >> element;
+  strlist t = split(element,',');
+  if (t.size() != 3)
+  {
+    a = 0;
+  }
+  else
+  {
+    std::stringstream transmorgrafier;
+    transmorgrafier << std::setprecision(30);
+    if (t[0][0] == '(') { t[0].erase(0,1); };
+    for(int i=0; i < 3; i++) { transmorgrafier << t[i] << " "; };
+    transmorgrafier >> a.x >> a.y >> a.z;
+  };
+  return f;
 };
 
 } // namespace nrtb

=== modified file 'cpp/common/serializer/Makefile'
--- obsolete/Cpp/common/serializer/Makefile	2012-04-06 17:44:53 +0000
+++ cpp/common/serializer/Makefile	2013-08-09 21:47:12 +0000
@@ -28,8 +28,8 @@
 
 serializer_test:	serializer.o serializer_test.cpp
 	@rm -f serializer_test
-	g++ -c serializer_test.cpp -I../include -std=gnu++0x
-	g++ -o serializer_test serializer_test.o serializer.o ../obj/base_thread.o -lpthread ../obj/common.o -std=gnu++0x
+	g++ -c serializer_test.cpp -I../include -std=gnu++11
+	g++ -o serializer_test serializer_test.o serializer.o -lpthread -std=gnu++11
 
 clean:
 	@rm -rvf *.o serializer_test ../include/serializer.h ../obj/serializer.o

=== modified file 'cpp/common/serializer/serializer.cpp'
--- obsolete/Cpp/common/serializer/serializer.cpp	2011-07-30 15:32:43 +0000
+++ cpp/common/serializer/serializer.cpp	2013-08-09 21:47:12 +0000
@@ -17,7 +17,6 @@
  **********************************************/
  
 #include "serializer.h"
-#include <base_thread.h>
 
 using namespace nrtb;
 
@@ -38,6 +37,5 @@
 
 unsigned long long serializer::operator()()
 {
-  nrtb::scope_lock mylock(lock);
   return counter++;
 }

=== modified file 'cpp/common/serializer/serializer.h'
--- obsolete/Cpp/common/serializer/serializer.h	2011-09-15 01:21:11 +0000
+++ cpp/common/serializer/serializer.h	2013-08-09 21:47:12 +0000
@@ -18,7 +18,8 @@
 
 #ifndef nrtb_serializer_h
 #define nrtb_serializer_h
-#include <base_thread.h>
+
+#include <atomic>
 
 namespace nrtb 
 { 
@@ -41,8 +42,7 @@
 	// functor method, returns the next value in the sequence.
 	unsigned long long operator ()();
   private:
-	nrtb::mutex lock;
-	unsigned long long int counter;
+	std::atomic<unsigned long long> counter;
   };
 
 }

=== modified file 'cpp/common/singleton/Makefile'
--- obsolete/Cpp/common/singleton/Makefile	2012-04-06 17:46:15 +0000
+++ cpp/common/singleton/Makefile	2013-08-09 21:47:12 +0000
@@ -16,6 +16,7 @@
 #
 #***********************************************
 
+switches=-std=gnu++11 -D _GLIBCXX_USE_SCHED_YIELD -D _GLIBCXX_USE_NANOSLEEP
 
 lib:	singleton_test
 	@./singleton_test
@@ -24,8 +25,8 @@
 
 singleton_test:	singleton_test.cpp Makefile
 	@rm -f singleton_test
-	g++ -c singleton_test.cpp -I ../include -std=gnu++0x
-	g++ -o singleton_test singleton_test.o ../obj/base_thread.o ../obj/common.o ../obj/serializer.o -lpthread -std=gnu++0x
+	g++ -c singleton_test.cpp -I ../include ${switches}
+	g++ -o singleton_test singleton_test.o ../obj/serializer.o -lpthread ${switches}
 
 clean:
 	@rm -rvf *.o singleton_test ../include/singleton.h

=== modified file 'cpp/common/singleton/singleton.h'
--- obsolete/Cpp/common/singleton/singleton.h	2011-08-13 13:13:25 +0000
+++ cpp/common/singleton/singleton.h	2013-08-09 21:47:12 +0000
@@ -25,7 +25,9 @@
 #ifndef nrtb_singleton_h
 #define nrtb_singleton_h
 
-#include <base_thread.h>
+#include <mutex>
+#include <memory>
+#include <atomic>
 
 namespace nrtb
 {
@@ -55,68 +57,70 @@
 template <class T, int mytag=0>
 class singleton: public T
 {
-	private:
-		static mutex __mylock;
-		static singleton * __me;
-	protected:
-		singleton() : T() {};
-		virtual ~singleton() {};
-		singleton(const singleton &) {};
-	public:
-		/** Used to access the object.
-		 ** 
-		 ** Returns a reference to the instanciated singleton object. If
-		 ** the object has not been accessed before, the object will be 
-		 ** instanciated automatically.
-		 ** 
-		 ** As is usual for the method that provides access to a singleton, 
-		 ** this method is static, allowing it to be called via the class 
-		 ** name as shown. Remember you can only assign the return value to
-		 ** a reference:
-		 ** 
-		 ** 	mytype & a = mytype::get_instance();
-		 ** 
-		 ** Attempts to make a copy of the instance should throw a compiler
-		 ** error.
-		 ** 
-		 ** This method is thread safe, but that does not imply that the 
-		 ** class returned is thread-safe overall; that would depend on the 
-		 ** implementation of the class used to instaciate the template.
-		 **/
-		static singleton & get_instance()
-		{
-			// First test avoids expensive mutex cycle
-			// if the object is already allocated.
-			if (!__me)
-			{
-				scope_lock lock(__mylock);
-				// second test required in case multiple threads
-				// get past the first check.
-				if (!__me) 
-				{ 
-					__me = new singleton;
-				};
-			};
-			return *__me;
-		};
+private:
+  static std::mutex __mylock;
+  static singleton<T,mytag> * __me ;
+protected:
+  singleton() : T() {};
+  virtual ~singleton() {};
+  singleton(const singleton &) = delete;
+public:
+  /** Used to access the object.
+    ** 
+    ** Returns a reference to the instanciated singleton object. If
+    ** the object has not been accessed before, the object will be 
+    ** instanciated automatically.
+    ** 
+    ** As is usual for the method that provides access to a singleton, 
+    ** this method is static, allowing it to be called via the class 
+    ** name as shown. Remember you can only assign the return value to
+    ** a reference:
+    ** 
+    ** 	mytype & a = mytype::get_instance();
+    ** 
+    ** Attempts to make a copy of the instance should throw a compiler
+    ** error.
+    ** 
+    ** This method is thread safe, but that does not imply that the 
+    ** class returned is thread-safe overall; that would depend on the 
+    ** implementation of the class used to instaciate the template.
+    **/
+  static singleton & get_reference()
+  {
+    // First test avoids expensive mutex cycle
+    // if the object is already allocated.
+    if (!__me)
+    {
+      std::unique_lock<std::mutex> lock(__mylock);
+      // second test required in case multiple threads
+      // get past the first check.
+      if (!__me) 
+      { 
+	__me = new singleton;
+      };
+    };
+    return *__me;
+  };
 
-		/** Destructs and deallocates the singleton object.
-		 ** 
-		 ** After a call to this method, the singleton object will
-		 ** be destructed and deallocated from memory. However, it
-		 ** will be automatically reconstruted and allocated if
-		 ** get_instance() called at any time afterword.
-		 **/
-		void delete_me()
-		{
-			scope_lock lock(__mylock);
-			if (__me) delete __me;
-			__me = 0;
-		};
+  /** Destructs and deallocates the singleton object.
+    ** 
+    ** After a call to this method, the singleton object will
+    ** be destructed and deallocated from memory. However, it
+    ** will be automatically reconstruted and allocated if
+    ** get_instance() called at any time afterword.
+    **/
+  void delete_me()
+  {
+    std::unique_lock<std::mutex> lock(__mylock);
+    if (__me) delete __me;
+    __me = 0;
+  };
 };
 
-template <class T, int mytag> mutex singleton<T,mytag>::__mylock;
-template <class T, int mytag> singleton<T,mytag> * singleton<T,mytag>::__me = 0; 
+template <class T, int mytag> 
+  std::mutex singleton<T,mytag>::__mylock;
+template <class T, int mytag> 
+  singleton<T,mytag> * singleton<T,mytag>::__me; 
 
 } // namespace nrtb;
 

=== modified file 'cpp/common/singleton/singleton_test.cpp'
--- obsolete/Cpp/common/singleton/singleton_test.cpp	2011-08-13 14:19:56 +0000
+++ cpp/common/singleton/singleton_test.cpp	2013-08-09 21:47:12 +0000
@@ -32,24 +32,25 @@
   
   cout << "============== singleton unit test ================" 
 	<< endl;
-  int er_count = 0;
+  int er_count {0};
   
-  sequence_type & a = sequence_type::get_instance();
+  sequence_type & a = sequence_type::get_reference();
   
   for (int i=0; i<10; i++)
   {
-	cout << a();
+    cout << a();
   };
   
-  sequence_type & b = sequence_type::get_instance();
+  sequence_type & b = sequence_type::get_reference();
   
   if ( b() != 10)
   {
-	er_count++;
+    er_count++;
   };
   
-  cout << "\n=========== singleton test " << (er_count ? "failed" : "passed")
-	<< " =============" << endl;
+  cout << "\n=========== singleton test " 
+    << (er_count ? "failed" : "passed")
+    << " =============" << endl;
 
   return er_count;
 };

=== modified file 'cpp/common/sockets/Makefile'
--- obsolete/Cpp/common/sockets/Makefile	2012-03-31 21:56:49 +0000
+++ cpp/common/sockets/Makefile	2013-08-09 21:47:12 +0000
@@ -16,6 +16,8 @@
 #
 #***********************************************
 
+switches=-std=gnu++11 -D _GLIBCXX_USE_SCHED_YIELD -D _GLIBCXX_USE_NANOSLEEP
+
 lib:	socket_test
 	@./socket_test
 	@cp -v base_socket.h ../include/
@@ -24,13 +26,13 @@
 
 socket_test:	base_socket.o socket_test.cpp
 	@rm -f socket_test
-	g++ -c -O3 socket_test.cpp -I ../include -std=gnu++0x 
-	g++ -o socket_test socket_test.o base_socket.o ../obj/hires_timer.o ../obj/common.o ../obj/base_thread.o -lpthread  -std=gnu++0x
+	g++ -c -O3 socket_test.cpp -I ../include ${switches} 
+	g++ -o socket_test socket_test.o base_socket.o ../obj/common.o -lpthread ${switches}
 
 
 base_socket.o:	base_socket.cpp base_socket.h Makefile
 	@rm -f base_socket.o
-	g++ -c -O3 base_socket.cpp -I ../include -std=gnu++0x 
+	g++ -c -O3 base_socket.cpp -I ../include ${switches} 
 
 clean:
 	@rm -vf *.o ../include/base_socket.h socket_test

=== modified file 'cpp/common/sockets/base_socket.cpp'
--- obsolete/Cpp/common/sockets/base_socket.cpp	2012-04-07 14:16:46 +0000
+++ cpp/common/sockets/base_socket.cpp	2013-08-09 21:47:12 +0000
@@ -19,11 +19,13 @@
 // see base_socket.h for documentation
 
 #include "base_socket.h"
+#include <boost/lexical_cast.hpp>
 #include <string.h>
 #include <errno.h>
 #include <arpa/inet.h>
 #include <netdb.h>
-#include <boost/lexical_cast.hpp>
+#include <vector>
+#include <regex>
 
 // testing
 #include <iostream>
@@ -34,554 +36,527 @@
 namespace nrtb
 {
 
-// added for Solaris 2.6 
-#ifdef no_inet_aton
-int inet_aton(const char * addr, in_addr * inp)
-{
-	// this workaround defines inet_aton in term in_addr. Drawbacks are
-	// that there is no useful error checking.
-	inp->s_addr = inet_addr(addr);
-	return (inp->s_addr != 0);
-};
-#endif // no_inet_aton
-
-// added for solaris 2.6
-#ifdef no_socklen_t
-typedef int socklen_t;
-#endif // no_sock_len_t
-
 int tcp_socket::transmit(const string & data)
 {
-	return send(mysock,data.c_str(),data.length(),MSG_DONTWAIT);
+  return send(mysock,data.c_str(),data.length(),MSG_DONTWAIT);
 };
 
 int tcp_socket::receive(std::string & data, int limit)
 {
-	errno = 0;
-	data = "";
-	// make more room in the input buffer if needed.
-	int bufsize = limit + 1;
-	if (bufsize > inbuff.size()) inbuff.resize(bufsize);
-	// get the data to inbuff
-	int returnme = recv(mysock,(void *) &(inbuff[0]),limit,0);
-	// did we get anything? 
-	if (returnme > 0)
-	{
-		// yes.. store for the caller.
-		data.resize(returnme,0);
-		for (int i=0; i<returnme; i++)
-		{
-		  data[i] = inbuff[i];
-		};
-	}
-	// ... or was there an error?
-	else if (errno) 
-	{
-		// flag it for the caller.
-		returnme = -1;
-	};
-	return returnme;
+  errno = 0;
+  data = "";
+  // make more room in the input buffer if needed.
+  int bufsize = limit + 1;
+  if (bufsize > inbuff.size()) inbuff.resize(bufsize);
+  // get the data to inbuff
+  int returnme = recv(mysock,(void *) &(inbuff[0]),limit,0);
+  // did we get anything? 
+  if (returnme > 0)
+  {
+    // yes.. store for the caller.
+    data.resize(returnme,0);
+    for (int i=0; i<returnme; i++)
+    {
+      data[i] = inbuff[i];
+    };
+  }
+  // ... or was there an error?
+  else if (errno) 
+  {
+    // flag it for the caller.
+    returnme = -1;
+  };
+  return returnme;
 };
 
 tcp_socket::tcp_socket(bool autoclose)
 {
-	close_on_destruct = autoclose;
-	mysock = socket(AF_INET,SOCK_STREAM,0);
-	_status = sock_init;
-	_last_error = 0;
+  close_on_destruct = autoclose;
+  mysock = socket(AF_INET,SOCK_STREAM,0);
+  _status = state::sock_init;
+  _last_error = 0;
 };
 
 tcp_socket::tcp_socket(int existing_socket, bool autoclose)
 {
-	close_on_destruct = autoclose;
-	mysock = existing_socket;
-	_status = sock_connect;
-	_last_error = 0;
+  close_on_destruct = autoclose;
+  mysock = existing_socket;
+  _status = state::sock_connect;
+  _last_error = 0;
 };
 
 tcp_socket::~tcp_socket()
 {	
-	if (close_on_destruct)
-	{
-		try {shutdown(mysock,SHUT_RDWR); } catch (...) {};
-		try {::close(mysock); } catch (...) {};
-		_status = sock_undef;
-	};
+  if (close_on_destruct)
+  {
+    try {shutdown(mysock,SHUT_RDWR); } catch (...) {};
+    try {::close(mysock); } catch (...) {};
+    _status = state::sock_undef;
+  };
 };
 
 void tcp_socket::reset()
 {
-	// close the old socket if we can.
-	try { close(); } catch (tcp_socket::general_exception) {};
-	// get a new one.
-	mysock = socket(AF_INET,SOCK_STREAM,0);
-	// set up the default conditions;
-	_status = sock_init;
-	_last_error = 0;
+  // close the old socket if we can.
+  try { close(); } catch (tcp_socket::general_exception) {}
+  // get a new one.
+  mysock = socket(AF_INET,SOCK_STREAM,0);
+  // set up the default conditions;
+  _status = state::sock_init;
+  _last_error = 0;
 };
 
 sockaddr_in tcp_socket::str_to_sockaddr(const string & address)
 {
-	sockaddr_in in_address;
-	// init our address structure.
-	memset(&in_address,0,sizeof(in_address));
-	//in_address.sin_len = 16;
-	in_address.sin_family = AF_INET;
-	// seperate the IP and port addresses.
-	const int IP = 0; 
-	const int PORT = 1;
-	strlist addr;
-	addr = split(address,':');
-	if (addr.size() != 2)
-	{
-		throw bad_address_exception();
-	};
-	if (addr[IP] != "*")
-	{
-		// first attempt name resolution
-		hostent * name = gethostbyname(addr[IP].c_str());
-		if ((name != 0) && (name->h_length > 0))
-		{
-			in_address.sin_addr = *( (in_addr *) (name->h_addr_list[0]));
-		}
-		else if (!inet_aton(addr[IP].c_str(),&in_address.sin_addr))
-		{
-			throw bad_address_exception();
-		};
-	};
-	if (addr[PORT] != "*")
-	{
-		// get the good port;
-		uint16_t port = lexical_cast<uint16_t>(addr[PORT]);
-		in_address.sin_port = htons(port);
-	};
-	return in_address;
+  sockaddr_in in_address;
+  // init our address structure.
+  memset(&in_address,0,sizeof(in_address));
+  //in_address.sin_len = 16;
+  in_address.sin_family = AF_INET;
+  // seperate the IP and port addresses.
+  const int IP = 0; 
+  const int PORT = 1;
+  strlist addr;
+  addr = split(address,':');
+  if (addr.size() != 2)
+  {
+    throw bad_address_exception();
+  };
+  if (addr[IP] != "*")
+  {
+    // first attempt name resolution
+    hostent * name = gethostbyname(addr[IP].c_str());
+    if ((name != 0) && (name->h_length > 0))
+    {
+      in_address.sin_addr = *( (in_addr *) (name->h_addr_list[0]));
+    }
+    else if (!inet_aton(addr[IP].c_str(),&in_address.sin_addr))
+    {
+      throw bad_address_exception();
+    };
+  };
+  if (addr[PORT] != "*")
+  {
+    // get the good port;
+    uint16_t port = lexical_cast<uint16_t>(addr[PORT]);
+    in_address.sin_port = htons(port);
+  };
+  return in_address;
 };
 
 string tcp_socket::sockaddr_to_str(const sockaddr_in & address)
 {
-	// get the IP address.
-	string returnme = inet_ntoa(address.sin_addr);
-	// adjust for wild card if appropriate.
-	if (returnme == "0.0.0.0") { returnme = "*"; };
-	// get the port address
-	returnme += ":";
-	uint16_t myport = ntohs(address.sin_port);
-	if (myport > 0 )
-	{
-		returnme += lexical_cast<string>(myport);
-	}
-	else
-	{
-		returnme += "*";
-	};
-	return returnme;
+  // get the IP address.
+  string returnme = inet_ntoa(address.sin_addr);
+  // adjust for wild card if appropriate.
+  if (returnme == "0.0.0.0") { returnme = "*"; };
+  // get the port address
+  returnme += ":";
+  uint16_t myport = ntohs(address.sin_port);
+  if (myport > 0 )
+  {
+    returnme += lexical_cast<string>(myport);
+  }
+  else
+  {
+    returnme += "*";
+  };
+  return returnme;
 };
 
 void tcp_socket::bind(const string & address)
 {
-	if (address != "*:*")
-	{
-		sockaddr_in in_address = str_to_sockaddr(address);
-		socklen_t socklen = sizeof(in_address);
-		// try bind.
-		if (::bind(mysock, (sockaddr*) &in_address, socklen))
-		{
-			// failed in some way.
-			_last_error = errno;
-			cant_bind_exception e;
-			e.store(address);
-			throw e;
-		};
-	}; // nop if "*:*" is passed in.
+  if (address != "*:*")
+  {
+    sockaddr_in in_address = str_to_sockaddr(address);
+    socklen_t socklen = sizeof(in_address);
+    // try bind.
+    if (::bind(mysock, (sockaddr*) &in_address, socklen))
+    {
+      // failed in some way.
+      _last_error = errno;
+      cant_bind_exception e;
+      e.store(address);
+      throw e;
+    };
+  }; // nop if "*:*" is passed in.
 };
 
 void tcp_socket::connect(const string & address, int timeout)
 {
-	sockaddr_in in_address = str_to_sockaddr(address);
-	if (::connect(mysock, ( sockaddr *) &in_address, sizeof(in_address)))
-	{
-		_last_error = errno;
-		bad_connect_exception e;
-		e.store(address);
-		throw e;
-	}
-	else
-	{
-		_status = sock_connect;
-	};
+  sockaddr_in in_address = str_to_sockaddr(address);
+  if (::connect(mysock, ( sockaddr *) &in_address, sizeof(in_address)))
+  {
+    _last_error = errno;
+    bad_connect_exception e;
+    e.store(address);
+    throw e;
+  }
+  else
+  {
+    _status = state::sock_connect;
+  };
 };
 
 void tcp_socket::close()
 {
-	if (::close(mysock))
-	{
-		_last_error = errno;
-		throw close_exception();
-	}
-	else 
-	{
-		_status = sock_close;
-	};
+  if (::close(mysock))
+  {
+    _last_error = errno;
+    throw close_exception();
+  }
+  else 
+  {
+    _status = state::sock_close;
+  };
 };
 
 int tcp_socket::put(string s, int timeout)
 {
-	// set up for the testing loop.
-	time_t endtime = time(NULL);
-	int orig_len = s.length();
-	endtime += timeout;
-	// Try to send.
-	bool done = false;
-	while (!done)
-	{
-		// make an attempt.
-		int results = transmit(s);
-		// remove the chars already sent from the buffer and set done 
-		// if appropriate.
-		if (results > 0) 
-		{ 
-			s.erase(0,results);
-			done = (s.length() == 0) ? true : false;
-		};
-		// decide what do do about any possible error results.
-		if (results == -1)
-		{
-			switch (errno)
-			{
-				case EBADF :
-				case ENOTSOCK: 
-					{
-						done = true; 
-						_last_error = errno;
-						_status = sock_close;
-						not_open_exception e;
-						e.store(s);
-						throw e;
-					 	break;
-					};
-				case ENOBUFS :
-				case ENOMEM  :
-					{
-						done = true;
-						_last_error = errno;
-						buffer_full_exception e;
-						e.store(s);
-						throw e;
-						break;
-					};
-				case EINTR:
-				case EAGAIN :
-//				case EWOULDBLOCK :
-					{
-						usleep(50);
-						break;
-					};
-				default : 
-					{
-						done = true;
-						_last_error = errno;
-						general_exception e;
-						e.store(s);
-						throw e;
-						break;
-					};
-			}; // switch (errno)
-		}; // until error, 
-		if ((timeout > 0) && ((time(NULL) >= endtime)))
-		{
-			done =  true;
-		};
-	}; // continue sending until success or error or timeout.
-	// check for timeout.
-	int sent = orig_len - s.length();
-	if (sent != orig_len)
-	{
-		timeout_exception e;
-		e.store(s);
-		throw e;
-	};
-	return sent;
+  // set up for the testing loop.
+  time_t endtime = time(NULL);
+  int orig_len = s.length();
+  endtime += timeout;
+  // Try to send.
+  bool done = false;
+  while (!done)
+  {
+    // make an attempt.
+    int results = transmit(s);
+    // remove the chars already sent from the buffer and set done 
+    // if appropriate.
+    if (results > 0) 
+    { 
+      s.erase(0,results);
+      done = (s.length() == 0) ? true : false;
+    };
+    // decide what do do about any possible error results.
+    if (results == -1)
+    {
+      switch (errno)
+      {
+	case EBADF :
+	case ENOTSOCK: 
+	{
+	  done = true; 
+	  _last_error = errno;
+	  _status = state::sock_close;
+	  not_open_exception e;
+	  e.store(s);
+	  throw e;
+	  break;
+	};
+	case ENOBUFS :
+	case ENOMEM  :
+	{
+	  done = true;
+	  _last_error = errno;
+	  buffer_full_exception e;
+	  e.store(s);
+	  throw e;
+	  break;
+	};
+	case EINTR:
+	case EAGAIN :
+	{
+	  usleep(50);
+	  break;
+	};
+	default : 
+	{
+	  done = true;
+	  _last_error = errno;
+	  general_exception e;
+	  e.store(s);
+	  throw e;
+	  break;
+	};
+      }; // switch (errno)
+    }; // until error, 
+    if ((timeout > 0) && ((time(NULL) >= endtime)))
+    {
+      done =  true;
+    };
+  }; // continue sending until success or error or timeout.
+  // check for timeout.
+  int sent = orig_len - s.length();
+  if (sent != orig_len)
+  {
+    timeout_exception e;
+    e.store(s);
+    throw e;
+  };
+  return sent;
 };
 
 string tcp_socket::get(int maxlen, int timeout)
 {
-/*
-micro_timer run_time;
-run_time.start();
-std::cerr << "ENTER get(" << maxlen << "," << timeout << ")" << std::endl;
-*/
-	string returnme = "";
-	returnme.reserve(maxlen);
-	string in_buffer;
-	// set out timeout marker.
-	time_t endtime = time(NULL);
-	endtime += timeout; 
-	timeval wait;
-	// input loop
-	bool done = false;
-	while (!done)
-	{
-		time_t waittime = endtime - time(NULL);
-		wait.tv_sec = (waittime > 0) ? waittime : 0;
-		wait.tv_usec = 10;
-		// set max timeout. 
-		//  the assert is used because some platforms may not properly support
-		//  the SO_RCVTIMEO socket option.
-		setsockopt(mysock,SOL_SOCKET,SO_RCVTIMEO,&wait,sizeof(wait));
-		// is there any data waiting?
-		int results = receive(in_buffer,maxlen-returnme.size());
-		// was there an error?
-		switch (results)
-		{
-			case 0:
-			{
-				if (returnme == "") 
-				{
-					throw not_open_exception();
-				}
-				else
-				{
-					done = true;
-				}
-				break;
-			}
-			case -1 :
-			{
-				switch (errno)
-				{
-					case EBADF :
-					case ENOTCONN :
-					case ENOTSOCK :
-					{
-						done = true;
-						_last_error = errno;
-						_status = sock_close;
-						if (returnme == "")
-						{
-							not_open_exception e;
-							e.store(returnme);
-							throw e;
-						};
-						break;
-					}
-					case EAGAIN :      // shouldn't happen, but .....
-					case EINTR :       // this too....
-					{
-						if (timeout == 0)
-						{
-							done = true;
-						};
-						usleep(50);
-						break;
-					}
-					default :
-					{
-						done = true;
-						_last_error = errno;
-						if (returnme == "")
-						{
-							general_exception e;
-							e.store(returnme);
-							throw e;
-						};
-						break;
-					}
-				}; // there was an error.
-				break;
-			}
-			default: 
-			{
-				returnme += in_buffer;
-				break;
-			}
-		};
-		// check boundry conditions;
-		// -- maxlen only effective if maxlen > 0.
-		if ((maxlen > 0) && (returnme.length() >= maxlen)) { done = true; };
-		// -- timeout only effective if timeout > 0.
-		if ((timeout > 0) && (time(NULL) > endtime))      { done = true; };
-		if (timeout == 0) { done = true; };
-/*
-std::cerr << "\tstatus: " << returnme.size() 
-<< ", done = " << done 
-<< " (" << run_time.interval() << ")"	
-<< std::endl;
-*/
-	}; // input loop.
-	// did we time out?
-	if ((timeout > 0) && (time(NULL) > endtime))
-	{
-		timeout_exception e;
-		e.store(returnme);
-		throw e;
-	};
-	// done! 
-	return returnme;
+  string returnme = "";
+  returnme.reserve(maxlen);
+  string in_buffer;
+  // set out timeout marker.
+  time_t endtime = time(NULL);
+  endtime += timeout; 
+  timeval wait;
+  // input loop
+  bool done = false;
+  while (!done)
+  {
+    time_t waittime = endtime - time(NULL);
+    wait.tv_sec = (waittime > 0) ? waittime : 0;
+    wait.tv_usec = 10;
+    // set max timeout. 
+    //  the assert is used because some platforms may not properly support
+    //  the SO_RCVTIMEO socket option.
+    setsockopt(mysock,SOL_SOCKET,SO_RCVTIMEO,&wait,sizeof(wait));
+    // is there any data waiting?
+    int results = receive(in_buffer,maxlen-returnme.size());
+    // was there an error?
+    switch (results)
+    {
+      case 0:
+      {
+	if (returnme == "") 
+	{
+	  throw not_open_exception();
+	}
+	else
+	{
+	  done = true;
+	}
+	break;
+      }
+      case -1 :
+      {
+	switch (errno)
+	{
+	  case EBADF :
+	  case ENOTCONN :
+	  case ENOTSOCK :
+	  {
+	    done = true;
+	    _last_error = errno;
+	    _status = state::sock_close;
+	    if (returnme == "")
+	    {
+	      not_open_exception e;
+	      e.store(returnme);
+	      throw e;
+	    };
+	    break;
+	  }
+	  case EAGAIN :      // shouldn't happen, but .....
+	  case EINTR :       // this too....
+	  {
+	    if (timeout == 0)
+	    {
+	      done = true;
+	    };
+	    usleep(50);
+	    break;
+	  }
+	  default :
+	  {
+	    done = true;
+	    _last_error = errno;
+	    if (returnme == "")
+	    {
+	      general_exception e;
+	      e.store(returnme);
+	      throw e;
+	    };
+	    break;
+	  }
+	}; // there was an error.
+	break;
+      }
+      default: 
+      {
+	returnme += in_buffer;
+	break;
+      }
+    };
+    // check boundry conditions;
+    // -- maxlen only effective if maxlen > 0.
+    if ((maxlen > 0) && (returnme.length() >= maxlen)) { done = true; };
+    // -- timeout only effective if timeout > 0.
+    if ((timeout > 0) && (time(NULL) > endtime))      { done = true; };
+    if (timeout == 0) { done = true; };
+  }; // input loop.
+  // did we time out?
+  if ((timeout > 0) && (time(NULL) > endtime))
+  {
+    timeout_exception e;
+    e.store(returnme);
+    throw e;
+  };
+  // done! 
+  return returnme;
 };
 
-
 string tcp_socket::getln(string eol, int maxlen, int timeout)
 {
-	// args check.
-	if (eol == "")
-	{
-		throw bad_args_exception();
-		return eol;
-	};
-	// setup.
-	string returnme = "";
-	returnme.reserve(maxlen);
-	int targetlen = eol.length();
-	int searchlen = targetlen - 1;
-	time_t endtime = time(NULL);
-	endtime += timeout;
-	bool done = false;
-	bool success = false;
-	// first, get at least as many characters as are in the eol string.
-	try
-	{
-		int wait_time = timeout;
-		if (timeout < 0) { wait_time = 0; };	
-		returnme = get(targetlen,wait_time);
-	}
-	catch (timeout_exception e)
-	{	
-		// if get timed out we may be done.
-		if (timeout >= 0) { done = true; };
-		returnme = e.comment();
-	};
-	// We only need to continue if we have not gotten our token yet.
-	if ((!done) && (returnme.length() >= targetlen))
-	{
-//		success = returnme.substr(returnme.length()-targetlen,targetlen) == eol;
-		success = returnme.find(eol,returnme.length()-targetlen) != string::npos;
-	};
-	while (!done && !success)
-	{
-		// still more to get, if we have time.
-		int timeleft = endtime - time(NULL);
-		timeleft = (timeleft > 0) ? timeleft : 0;
-		// can we increase our get length?
-		int getlen = 1;
-		if (searchlen > 1)
-		{
-			// see if a token start is near.
-			if (returnme.find(eol[0],returnme.length()-searchlen) == string::npos)
-			{
-				// great!.. get just less than one token's worth.
-				getlen = searchlen;
-			}
-		};
-		// okay.. let's get the next chunk
-		try
-		{
-			returnme += get(getlen,timeleft);
-		}
-		catch (timeout_exception e)
-		{
-			if (timeout >= 0) { done = true; };
-		};
-		// check boundary conditions.
-		// -- did we get it?
-		if (returnme.length() >= targetlen)
-		{
-//			success = returnme.substr(returnme.length()-targetlen,targetlen) == eol;
-			success = returnme.find(eol,returnme.length()-targetlen) != string::npos;
-		};
-		// -- maxlen only effective if maxlen > 0.
-		if ((maxlen > 0) && (returnme.length() >= maxlen)) { done = true; };
-	};
-	// did we error out?
-	if (!success)
-	{
-		// what type of error was it?
-		if ((maxlen > 0) && (returnme.length() >= maxlen))
-		{
-			overrun_exception e;
-			e.store(returnme);
-			throw e;
-		}
-		else
-		{
-			timeout_exception e;
-			e.store(returnme);
-			throw e;
-		};
-	};
-	return returnme;
+  // args check.
+  if (eol == "")
+  {
+    throw bad_args_exception();
+    return eol;
+  };
+  // setup.
+  string returnme = "";
+  returnme.reserve(maxlen);
+  int targetlen = eol.length();
+  int searchlen = targetlen - 1;
+  time_t endtime = time(NULL);
+  endtime += timeout;
+  bool done = false;
+  bool success = false;
+  // first, get at least as many characters as are in the eol string.
+  try
+  {
+    int wait_time = timeout;
+    if (timeout < 0) { wait_time = 0; };	
+    returnme = get(targetlen,wait_time);
+  }
+  catch (timeout_exception e)
+  {	
+    // if get timed out we may be done.
+    if (timeout >= 0) { done = true; };
+    returnme = e.comment();
+  };
+  // We only need to continue if we have not gotten our token yet.
+  if ((!done) && (returnme.length() >= targetlen))
+  {
+    success = returnme.find(eol,returnme.length()-targetlen) != string::npos;
+  };
+  while (!done && !success)
+  {
+    // still more to get, if we have time.
+    int timeleft = endtime - time(NULL);
+    timeleft = (timeleft > 0) ? timeleft : 0;
+    // can we increase our get length?
+    int getlen = 1;
+    if (searchlen > 1)
+    {
+      // see if a token start is near.
+      if (returnme.find(eol[0],returnme.length()-searchlen) == string::npos)
+      {
+	// great!.. get just less than one token's worth.
+	getlen = searchlen;
+      }
+    };
+    // okay.. let's get the next chunk
+    try
+    {
+      returnme += get(getlen,timeleft);
+    }
+    catch (timeout_exception e)
+    {
+      if (timeout >= 0) { done = true; };
+    };
+    // check boundary conditions.
+    // -- did we get it?
+    if (returnme.length() >= targetlen)
+    {
+      success = returnme.find(eol,returnme.length()-targetlen) != string::npos;
+    };
+    // -- maxlen only effective if maxlen > 0.
+    if ((maxlen > 0) && (returnme.length() >= maxlen)) { done = true; };
+  };
+  // did we error out?
+  if (!success)
+  {
+    // what type of error was it?
+    if ((maxlen > 0) && (returnme.length() >= maxlen))
+    {
+      overrun_exception e;
+      e.store(returnme);
+      throw e;
+    }
+    else
+    {
+      timeout_exception e;
+      e.store(returnme);
+      throw e;
+    };
+  };
+  return returnme;
 };
 
 string tcp_socket::get_local_address()
 {	
-	sockaddr_in myaddr;
-	socklen_t len = sizeof(myaddr);
-	int results = getsockname(mysock,(sockaddr *) &myaddr,&len);
-	// check that getsockname was okay.
-	if (results == -1)
-	{
-		// some type of error occurred.
-		switch (errno)
-		{
-			case ENOBUFS :
-				{
-					throw buffer_full_exception();
-					break;
-				};
-			default :
-				{
-					throw general_exception();
-					break;
-				};
-		}; // switch errno
-	}
-	return sockaddr_to_str(myaddr);
+  sockaddr_in myaddr;
+  socklen_t len = sizeof(myaddr);
+  int results = getsockname(mysock,(sockaddr *) &myaddr,&len);
+  // check that getsockname was okay.
+  if (results == -1)
+  {
+    // some type of error occurred.
+    switch (errno)
+    {
+      case ENOBUFS :
+      {
+	throw buffer_full_exception();
+	break;
+      };
+      default :
+      {
+	throw general_exception();
+	break;
+      };
+    }; // switch errno
+  }
+  return sockaddr_to_str(myaddr);
 };
 
 string tcp_socket::get_remote_address()
 {
-	sockaddr_in myaddr;
-	socklen_t len = sizeof(myaddr);
-	int results = getpeername(mysock,(sockaddr *) &myaddr,&len);
-	// check that getsockname was okay.
-	if (results == -1)
-	{
-		// some type of error occurred.
-		switch (errno)
-		{
-			case ENOTCONN :
-				{
-					_status = sock_close;
-					throw not_open_exception();
-					break;
-				};
-			case ENOBUFS :
-				{
-					throw buffer_full_exception();
-					break;
-				};
-			default :
-				{
-					throw general_exception();
-					break;
-				};
-		}; // switch errno
-	}
-	return sockaddr_to_str(myaddr);
+  sockaddr_in myaddr;
+  socklen_t len = sizeof(myaddr);
+  int results = getpeername(mysock,(sockaddr *) &myaddr,&len);
+  // check that getsockname was okay.
+  if (results == -1)
+  {
+    // some type of error occurred.
+    switch (errno)
+    {
+      case ENOTCONN :
+      {
+	_status = state::sock_close;
+	throw not_open_exception();
+	break;
+      };
+      case ENOBUFS :
+      {
+	throw buffer_full_exception();
+	break;
+      };
+      default :
+      {
+	throw general_exception();
+	break;
+      };
+    }; // switch errno
+  }
+  return sockaddr_to_str(myaddr);
 };
 
 
 tcp_server_socket_factory::tcp_server_socket_factory(
-		const string & address, const unsigned short int & backlog = 5)
+		const string & address, 
+		const unsigned short int backlog,
+		const int queue_size)
 {
-	// does not attempt to set up the connection initially.
-	_address = address;
-	_backlog = backlog;
-	_last_thread_fault = 0;
+  // does not attempt to set up the connection initially.
+  _address = address;
+  _backlog = backlog;
+  pending.resize(queue_size);
 };
 
 tcp_server_socket_factory::~tcp_server_socket_factory()
 {
+  // Shutdown the queue and notify the workers.
+  try { pending.shutdown(); } catch (...) {};
   // make sure we've stopped doing anything.
   try { stop_listen(); } catch (...) {};
 };
@@ -589,10 +564,15 @@
 void tcp_server_socket_factory::start_listen()
 {
   // take no action if the listen thread is already running.
-  if (!is_running())
+  if (in_run_method or work_thread.joinable())
+  {
+    throw already_running_exception();
+  }
+  else
   {
     // start it up!
-    start();
+    work_thread = 
+      std::thread(tcp_server_socket_factory::run, this);
     int countdown = 99;
     while (!listening() and countdown)
     {
@@ -605,10 +585,6 @@
       e.store(_address);
       throw e;
     };
-  }
-  else
-  {
-    throw already_running_exception();
   };
 };
 
@@ -617,20 +593,22 @@
   // take action only if the listen thread is running.
   if (listening())
   {
-    // stop the listener thread
-    stop();
-    join();
     listen_sock.reset();
   };
+  if (work_thread.joinable()) work_thread.join();
+  // just in case.
+  pending.shutdown();
+  _last_thread_fault = 0;
+  in_run_method == false;
 };
 
 bool tcp_server_socket_factory::listening()
 {
-  bool running = is_running();
+  bool running = in_run_method and work_thread.joinable();
   if (listen_sock)
   {
-    running = running
-      and listen_sock->status() == tcp_socket::sock_connect;
+    running = running and listen_sock->status() == 
+	tcp_socket::state::sock_connect;
   }
   else
   {
@@ -646,124 +624,113 @@
 
 unsigned short int tcp_server_socket_factory::backlog()
 {
-	return _backlog;
+  return _backlog;
 };
 
-void tcp_server_socket_factory::run()
+void tcp_server_socket_factory::run(
+  tcp_server_socket_factory * server )
 {
-  // set up the listening socket.
-  int sock;
-  _last_thread_fault = 0;
-  bool go = false;
+  server->in_run_method = true;
   try
   {
-    sock = socket(AF_INET,SOCK_STREAM,0);
-    sockaddr_in myaddr;
-    myaddr = tcp_socket::str_to_sockaddr(_address);
-    int a = bind(sock,(sockaddr *) &myaddr,sizeof(myaddr));
-    int b = listen(sock,_backlog);
-    if (a || b)
+    // set up the listening socket.
+    int sock;
+    server->_last_thread_fault = 0;
+    bool go = false;
+    try
     {
-      go = false;
-      if (a) _last_thread_fault += 1;
-      if (b) _last_thread_fault += 2;
+      sock = socket(AF_INET,SOCK_STREAM,0);
+      sockaddr_in myaddr;
+      myaddr = tcp_socket::str_to_sockaddr(server->_address);
+      int a = bind(sock,(sockaddr *) &myaddr,sizeof(myaddr));
+      int b = listen(sock,server->_backlog);
+      if (a || b)
+      {
+	go = false;
+	if (a) server->_last_thread_fault += 1;
+	if (b) server->_last_thread_fault += 2;
+      }
+      else
+      {
+	go = true;
+      };
     }
-    else
-    {
-      go = true;
-    };
-  }
-  catch (...)
-  {
-    _last_thread_fault = 100;
-  };
-  // if not in a good state, terminate the thread.
-  if (!go)
-  {
-    _last_thread_fault =+ 200;
-    exit(0);
-  };
-  // make sure the listener is closed when we exit.
-  // also prevides an external hook to socket.
-  listen_sock.reset(new tcp_socket(sock));
-  // processing loop
-  while
-  (
-    go
-    and listen_sock
-    and (listen_sock->status() == tcp_socket::sock_connect)
-  )
-  {
-    // accept a new connection
-    bool good_connect = true;
-    int new_conn = accept(sock,NULL,NULL);
-    // is the listener still open?
-    if
+    catch (...)
+    {
+      server->_last_thread_fault = 100;
+    };
+    // if not in a good state, terminate the thread.
+    if (!go)
+    {
+      server->_last_thread_fault =+ 200;
+      exit(0);
+    };
+    // make sure the listener is closed when we exit.
+    // also prevides an external hook to socket.
+    server->listen_sock.reset(new tcp_socket(sock));
+    // processing loop
+    while
     (
-      (!listen_sock)
-      and (listen_sock->status() != tcp_socket::sock_connect)
+      go
+      and server->listen_sock
+      and (server->listen_sock->status() 
+	== tcp_socket::state::sock_connect)
     )
     {
-      // the listner socket is not available.. get out of here.
-      listen_sock.reset();
-      _last_thread_fault = 300;
-      exit(0);
-    };
-    // validate the accept return value.
-    if (new_conn == -1)
-    {
-      // accept returned an error.
-      switch (errno)
-      {
-        case EPROTO :
-        case EHOSTDOWN :
-        case EHOSTUNREACH :
-        case EAGAIN :
-        case ECONNABORTED :
-        {
-          // abandon this connection
-          good_connect = false;
-          break;
-        };
-        default :
-        {
-          // for any other error, we're going to shutdown the
-          // this listener thread.
-          go = false;
-          good_connect = false;
-          _last_thread_fault = errno;
-          break;
-        };
-      };  // switch (errno)
-    }; // error thrown by accept.
-    if (good_connect)
-    {
-      connect_sock.reset(new tcp_socket(new_conn));
-      set_cancel_anytime();
-      // call the connection handler.
-      try
-      {
-        go = on_accept();
-      }
-      catch (...)
-      {
-        go = false;
-        _last_thread_fault = 501;
-      };
-      set_deferred_cancel();
-      // safety check.
-      if (connect_sock)
-      {
-        std::cerr << "WARNING: on_accept() did not take ownership of "
-          << "connect_sock.\n"
-          << "  This can lead to leaks and should be fixed."
-          << std::endl;
-        connect_sock.reset();
-        _last_thread_fault = 500;
-        go = false;
-      };
-    };
-  }; // while go;
+      // accept a new connection
+      bool good_connect = true;
+      int new_conn = accept(sock,NULL,NULL);
+      // is the listener still open?
+      if
+      (
+	(!server->listen_sock)
+	or (server->listen_sock->status() 
+	  != tcp_socket::state::sock_connect)
+      )
+      {
+	// the listner socket is not available.. get out of here.
+	server->listen_sock.reset();
+	server->_last_thread_fault = 300;
+	good_connect = false;
+	go = false;
+	break;
+      };
+      // validate the accept return value.
+      if (new_conn == -1)
+      {
+	// accept returned an error.
+	switch (errno)
+	{
+	  case EPROTO :
+	  case EHOSTDOWN :
+	  case EHOSTUNREACH :
+	  case EAGAIN :
+	  case ECONNABORTED :
+	  {
+	    // abandon this connection
+	    good_connect = false;
+	    break;
+	  };
+	  default :
+	  {
+	    // for any other error, we're going to shutdown the
+	    // this listener thread.
+	    go = false;
+	    good_connect = false;
+	    server->_last_thread_fault = errno;
+	    break;
+	  };
+	};  // switch (errno)
+      }; // error thrown by accept.
+      if (good_connect)
+      {
+	tcp_socket_p storeme(new tcp_socket(new_conn));
+	server->pending.push(storeme);
+      };
+    }; // while go;
+  }
+  catch (...) {};
+  server->in_run_method = false;
 };
 
 } // namespace nrtb

=== modified file 'cpp/common/sockets/base_socket.h'
--- obsolete/Cpp/common/sockets/base_socket.h	2012-04-07 13:33:10 +0000
+++ cpp/common/sockets/base_socket.h	2013-08-09 21:47:12 +0000
@@ -19,8 +19,11 @@
 #ifndef base_socket_header
 #define base_socket_header
 
-#include <base_thread.h>
 #include <memory>
+#include <atomic>
+#include <thread>
+#include <common.h>
+#include <circular_queue.h>
 #include <sys/socket.h>
 #include <netinet/in.h>
 
@@ -39,539 +42,480 @@
  **/
 class tcp_socket
 {
-	public:
-	
-		typedef enum {sock_undef,sock_init,sock_connect,sock_close} state;
-		
-	protected:
-
-		int mysock;
-		bool close_on_destruct;
-		state _status;
-		int _last_error;
-		std::vector<unsigned char> inbuff;
-
-		virtual int transmit(const std::string & data);
-		virtual int receive(std::string & data,int limit);
-
-	public:
-
-		/// Use to catch all socket exceptions.
-		class general_exception: public base_exception {};
-		/// Thrown by send or get* if the socket is not open for use.
-		class not_open_exception: public general_exception {};
-		/// Thrown by get* if more than maxlen chars are receieved.
-		class overrun_exception: public general_exception {};
-		/// Thrown if a timeout occured during an operation.
-		class timeout_exception: public general_exception {};
-		/// Thrown if the socket could not connect to the target.
-		class bad_connect_exception: public general_exception {};
-		/// Thrown if the address argument is not interpretable.
-		class bad_address_exception: public general_exception {};
-		/// Thrown by bind() if the address/port is not bindable.
-		class cant_bind_exception: public general_exception {};
-		/// Thrown by close() if an error is reported.
-		class close_exception: public general_exception {};
-		/// Thrown by send if the message is too large.
-		class msg_too_large_exception: public general_exception {};
-		/// Thrown by send if buffer overflows.
-		class buffer_full_exception: public general_exception {};
-		/// Thrown if the socket lib complains of bad args.
-		class bad_args_exception: public general_exception {};
-
-		/** Constructs a tcp_socket.
-		 ** 
-		 ** Prepares this socket for use. If autoclose=true the socket will be
-		 ** closed when the object is distructed, otherwise it will be left in
-		 ** whatever state it happened to be in at the time.
-		 ** 
-		 ** BTW, I _don't_ recommend you leave the socket open. If the tcp_socket
-		 ** was instanciated via this constructor, there will not be any other 
-		 ** references to the socket save the one held privately, so a socket left
-		 ** open will be there forever. This will almost certainly warrent an 
-		 ** unpleasent visit by one or more SAs of the box(es) hosting your
-		 ** application over time. 
-		 ** 
-		 ** autoclose=true; it's the only way to be sure. ;)
-		 **/
-		tcp_socket(bool autoclose=true);
-
-		/** Constructs from an already existing socket.
-		 ** 
-		 ** Constructs the tcp_socket from an already existing socket.  This 
-		 ** constructor is specifically for use with the traditional listen()
-		 ** sockets function, and probably should not be used in other contexts.
-		 ** 
-		 ** If autoclose is true the socket will be closed on destruction of the 
-		 ** object, otherwise the socket will be left in whatever state it happened
-		 ** to be in at the time. As a general rule I suspect you'll want leave 
-		 ** autoclose defaulted to true.
-		 ** 
-		 ** In most cases where you would use listen(), take a look at the 
-		 ** tcp_server_socket_factory class; it'll probably do everything you need
-		 ** with a minimum of programming overhead.
-		 ** 
-		 ** BTW, I _don't_ recommend you leave the socket open. If the socket variable
-		 ** used for instanciation was discarded, there will not be any other 
-		 ** references to the socket save the one held privately, so a socket left
-		 ** open will be there forever. This will almost certainly warrent an 
-		 ** unpleasent visit by one or more SAs of the box(es) hosting your
-		 ** application over time. 
-		 ** 
-		 ** autoclose=true; it's the only way to be sure. ;)
-		 **/
-		tcp_socket(int existing_socket, bool autoclose=true);
-
-		/** Destructs a tcp_socket.
-		 ** 
-		 ** If autoclose was set to true, the socket will be closed if it is open
-		 ** at the time of destruction. If no, the socket will be left in whatever
-		 ** state it happened to be in at the time.
-		 **/
-		virtual ~tcp_socket();
-
-		/** Resets the socket after a hard error.
-		 **
-		 ** In cases where the socket was invlidated by the operating system
-		 ** (typically cases where a SIGPIPE was raised by the TCP/IP stack),
-		 ** use this function to discard the old socket id and aquire a new one.
-		 ** Understand that this will make the tcp_socket useful again, but you
-		 ** will have to reconnect before any traffic can be sent.
-		 **/
-		virtual void reset();
-
-		/** Creates a sockaddr_in from a formatted string.
-		 ** 
-		 ** address is an "IP:port" formatted string; i.e. 129.168.1.1:80. 
-		 ** "*" may use used to substatute for the IP, port or both.
-		 ** 
-		 ** Returns a properly formatted sockaddr_in struct for use with connect,
-		 ** bind, etc. Throws a bad_address_exception if the address argument is 
-		 ** mal-formed.
-		 **/
-		static sockaddr_in str_to_sockaddr(const std::string & address);
-
-		/** Creates a string from a sockaddr_in.
-		 ** 
-		 ** The returned string is of the same format accepted as arguments to the 
-		 ** to the bind() and connect() methods.
-		 ** 
-		 ** May throw a bad_address_exception if the sock_addr_in is not 
-		 ** properly formatted.
-		 **/
-		static std::string sockaddr_to_str(const sockaddr_in & address);
-
-		/** binds the tcp_socket to a local address/port.
-		 ** 
-		 ** You do _not_ need to use this method if you are setting up a tcp_socket
-		 ** for client use. If you don't call bind  an ephemeral port and the host's 
-		 ** IP number will be assigned, as is normal and preferred for client sockets.
-		 ** 
-		 ** In very rare cases where you have a multi-homed host and a real
-		 ** requirement to specify which IP this connection uses as local, you can
-		 ** use this method to select the port and address the client will use.
-		 ** 
-		 ** address: string of the format IP:port; example "255.255.255.255:91". 
-		 ** If you wish to accept input on any active IP address in this host, 
-		 ** use "*" for the IP address, as in "*:80". If you want to fix the address
-		 ** but leave the port up to the host, use "*" for the port, as in 
-		 ** "10.101.78.33:*". Obviously, using "*:*" as the address gives the 
-		 ** same results as not calling this method at all.
-		 ** 
-		 ** If the address argument is mal-formed a bad_address_exception will be
-		 ** thrown and no changes will be made to the tcp_socket.
-		 ** 
-		 ** If the address is not bindable (already in use is a common cause) a 
-		 ** cant_bind_exception will be thrown.
-		 **/
-		void bind(const std::string & address);
-
-		/** Opens the connection.
-		 **
-		 ** address: string of the format IP:port; example "255.255.255.255:91". 
-		 ** If the address is mal-formed a bad_address_exception will be thrown.
-		 ** 
-		 ** If timeout is specified and >0, the system will not wait more than
-		 ** timeout seconds before throwing a timeout_exception.
-		 ** 
-		 ** If the connection is not set up properly, a bad_connection_exception
-		 ** will be thrown.
-		 **/
-		void connect(const std::string & address, int timeout=0);
-
-		/** Closes an open connection.
-		 ** 
-		 ** If a problem is reported a close_exception will be thrown. Possible
-		 ** causes include the socket not being open, unsent data pending in the 
-		 ** tcp stack, etc.
-		 **/
-		virtual void close();
-		
-		/** Returns the current status.
-		 ** 
-		 ** Possibles states are tcp_socket::undef, tcp_socket::init, 
-		 ** tcp_socket::connect, and tcp_socket::close.
-		 **/
-		state status() { return _status; };
-
-		/** Returns the last socket error recieved.
-		 ** 
-		 ** Will contain zero if no errors have occured on the socket since 
-		 ** the tcp_socket was instanciated, or the errno returned on the most recent
-		 ** error otherwise.
-		 ** 
-		 ** Check the man pages for bind(), connect(), close(), socket(), send(),
-		 ** and recv() for possible values. They are defined in error.h.
-		 **/
-		int last_error() { return _last_error; };
-
-		/** Sends the string to the target host.
-		 ** 
-		 ** If timeout is specified and >0, a timeout_exception will be thrown 
-		 ** if the send does not succeed within timeout seconds. 
-		 ** 
-		 ** If socket is not connected or closes during sending a 
-		 ** not_open_exception will be thrown. 
-		 ** 
-		 ** If an exception is thrown, the characters that were not
-		 ** sent will be available via the exception's comment() method (as
-		 ** a string, of course).
-		 **/
-		int put(std::string s, int timeout=10);
-
-		/** gets a string of characters from the socket.
-		 ** 
-		 ** This method allows the reception of a string of characters 
-		 ** limited by length and time. Use this method when you are expecting a 
-		 ** stream if data that you either know the length of or where there is
-		 ** no specific ending character.  If the expected traffic is organized 
-		 ** into messages or lines ending with a specific character or string, 
-		 ** use the getln() method instead.
-		 ** 
-		 ** Examples:
-		 ** 
-		 ** get() or get(1) will return a string containing a single
-		 ** character or throw a timeout in 10 seconds if one is not
-		 ** recieved.
-		 ** 
-		 ** get(100,30) will return when 100 characters have been recieved or 
-		 ** throw a timeout in 30 seconds.
-		 ** 
-		 ** get(100,-1) will return after 100 characters have been recieved, and will 
-		 ** _never_ time out. I strongly recommend that at the very least use timeout
-		 ** values >= 0 to this method to prevent program long term program stalls.
-		 ** 
-		 ** If maxlen==0, this method will return immediately with whatever characters
-		 ** happen to be in the socket's input buffer at the time.
-		 ** 
-		 ** If maxlen>0 and timeout<0, this method will block until maxlen characters
-		 ** have been recieved and then return. NOTE: this method could block 
-		 ** forever if the sending host does not send maxlen characters and timeout
-		 ** is < 0.
-		 ** 
-		 ** If maxlen>0 and timeout>0 this method will return upon recieving 
-		 ** maxlen characters or throw a timeout_exception after timeout seconds 
-		 ** have expired in the worse case.
-		 ** 
-		 ** In all cases the method returns a string containing the characters 
-		 ** recieved, if any.
-		 ** 
-		 ** If the timeout expires before the required number of characters are
-		 ** recieved a timeout_exception will be thrown. 
-		 ** 
-		 ** If the socket is not connected or closes while being read a 
-		 ** not_open_exception will be thrown.
-		 ** 
-		 ** If an exception is thrown, any characters already recieved 
-		 ** will be available via the exception's comment() method.
-		 **/
-		std::string get(int maxlen=1, int timeout=10);
-
-		/** gets a string of characters from the socket.
-		 ** 
-		 ** This method is for the reception of messages (or lines) that have a 
-		 ** specific ending string. As such it considers the recept of maxlen
-		 ** characters or a timeout without the designated eol string to be 
-		 ** a problem and will throw an exception in those cases. This behavor 
-		 ** differs from that of the get() method, which simply returns when it 
-		 ** has received its limit.
-		 ** 
-		 ** If there is no specific eol or eom string in your expected data 
-		 ** stream use the get() method instead.
-		 ** 
-		 ** Examples:
-		 ** 
-		 ** getln() will return all characters recieved up to and including the 
-		 ** first carrage return or throw a timeout if a carrage return is not
-		 ** recieved after 10 seconds.
-		 ** 
-		 ** getln("</alert>") will return all characters recieved up to and
-		 ** including "</alert>" or throw a timeout if "</alert>" is not recieved 
-		 ** within 10 seconds.
-		 ** 
-		 ** getln(":",30) will return all characters recieved up to and including 
-		 ** ":" if ":" is recieved by the 30th character. If 30 characters are recieved 
-		 ** before ":", an overrun_exception would be thrown. A timeout would be
-		 ** thrown if ":" is not recieved within 10 seconds.
-		 ** 
-		 ** getln(":",30,20) would react exactly like getln(":",30) except the timeout
-		 ** period would be 20 seconds instead of the default 10.
-		 ** 
-		 ** getln(":",30,-1) will react exactly like getln(":",30) except that no
-		 ** timeout will ever be thrown. In this case, the method may block 
-		 ** forever if no ":" is received and it never receives 30 characters.
-		 ** I strongly recommend that at the very least that timeout be a 
-		 ** value >= 0 to this method to prevent program long term program stalls.
-		 ** 
-		 ** If maxlen==0 and timeout<0, this method will block until the eol
-		 ** string is recieved from the host or maxlen characters
-		 ** have been recieved. and then return. NOTE: this method could block 
-		 ** forever if the sending host does not send maxlen characters or the
-		 ** eol string and timeout is < 0;
-		 ** 
-		 ** If maxlen>0 and timeout>0 this method will return upon recieving the 
-		 ** eol string, when maxlen characters have be recieved or when 
-		 ** timeout seconds have expired.
-		 ** 
-		 ** In all cases the method returns a string containing the characters 
-		 ** recieved, if any, including the eol string.
-		 ** 
-		 ** If the timeout expires before eol is recieved or maxlen characters are
-		 ** recieved a timeout_exception will be thrown.
-		 ** 
-		 ** If maxlen characters are recieved before the eol string is recieved 
-		 ** an overrun_exception will be thown.
-		 ** 
-		 ** If the socket is not connected or closes while being read a 
-		 ** not_open_exception will be thrown.
-		 ** 
-		 ** If an exception is thrown, any characters already recieved 
-		 ** will be available via the exception's comment() method.
-		 **/
-		std::string getln(std::string eol="\r", int maxlen=0, int timeout=10);
-
-		/** Returns the local address.
-		 ** 
-		 ** Returns the address in the same form that it needs to be in for the 
-		 ** bind and connect addess arguments.
-		 ** 
-		 ** May throw a buffer_full_exception if there are not enough resources, 
-		 ** or a general_exception if some other problem occurs.
-		 **/
-		std::string get_local_address();
-
-		/** Returns the remote address.
-		 ** 
-		 ** Returns the address in the same form that it needs to be in for the 
-		 ** bind and connect addess arguments.
-		 ** 
-		 ** May throw a buffer_full_exception if there are not enough resources,
-		 ** a not_open_exception if the socket has not been connected to a remote
-		 ** host, or a general_exception if some other problem occurs.
-		 **/
-		std::string get_remote_address();
+public:
+
+  enum class state {sock_undef,sock_init,sock_connect,sock_close};
+  
+protected:
+
+  int mysock {0};
+  bool close_on_destruct {true};
+  state _status {state::sock_undef};
+  int _last_error {0};
+  std::vector<unsigned char> inbuff;
+
+  virtual int transmit(const std::string & data);
+  virtual int receive(std::string & data,int limit);
+
+public:
+
+  /// Use to catch all socket exceptions.
+  class general_exception: public base_exception {};
+  /// Thrown by send or get* if the socket is not open for use.
+  class not_open_exception: public general_exception {};
+  /// Thrown by get* if more than maxlen chars are receieved.
+  class overrun_exception: public general_exception {};
+  /// Thrown if a timeout occured during an operation.
+  class timeout_exception: public general_exception {};
+  /// Thrown if the socket could not connect to the target.
+  class bad_connect_exception: public general_exception {};
+  /// Thrown if the address argument is not interpretable.
+  class bad_address_exception: public general_exception {};
+  /// Thrown by bind() if the address/port is not bindable.
+  class cant_bind_exception: public general_exception {};
+  /// Thrown by close() if an error is reported.
+  class close_exception: public general_exception {};
+  /// Thrown by send if the message is too large.
+  class msg_too_large_exception: public general_exception {};
+  /// Thrown by send if buffer overflows.
+  class buffer_full_exception: public general_exception {};
+  /// Thrown if the socket lib complains of bad args.
+  class bad_args_exception: public general_exception {};
+
+  /** Constructs a tcp_socket.
+    ** 
+    ** Prepares this socket for use. If autoclose=true the socket will be
+    ** closed when the object is distructed, otherwise it will be left in
+    ** whatever state it happened to be in at the time.
+    ** 
+    ** BTW, I _don't_ recommend you leave the socket open. If the tcp_socket
+    ** was instanciated via this constructor, there will not be any other 
+    ** references to the socket save the one held privately, so a socket left
+    ** open will be there forever. This will almost certainly warrent an 
+    ** unpleasent visit by one or more SAs of the box(es) hosting your
+    ** application over time. 
+    ** 
+    ** autoclose=true; it's the only way to be sure. ;)
+    **/
+  tcp_socket(bool autoclose=true);
+
+  /** Constructs from an already existing socket.
+    ** 
+    ** Constructs the tcp_socket from an already existing socket.  This 
+    ** constructor is specifically for use with the traditional listen()
+    ** sockets function, and probably should not be used in other contexts.
+    ** 
+    ** If autoclose is true the socket will be closed on destruction of the 
+    ** object, otherwise the socket will be left in whatever state it happened
+    ** to be in at the time. As a general rule I suspect you'll want leave 
+    ** autoclose defaulted to true.
+    ** 
+    ** In most cases where you would use listen(), take a look at the 
+    ** tcp_server_socket_factory class; it'll probably do everything you need
+    ** with a minimum of programming overhead.
+    ** 
+    ** BTW, I _don't_ recommend you leave the socket open. If the socket variable
+    ** used for instanciation was discarded, there will not be any other 
+    ** references to the socket save the one held privately, so a socket left
+    ** open will be there forever. This will almost certainly warrent an 
+    ** unpleasent visit by one or more SAs of the box(es) hosting your
+    ** application over time. 
+    ** 
+    ** autoclose=true; it's the only way to be sure. ;)
+    **/
+  tcp_socket(int existing_socket, bool autoclose=true);
+
+  /** Destructs a tcp_socket.
+    ** 
+    ** If autoclose was set to true, the socket will be closed if it is open
+    ** at the time of destruction. If no, the socket will be left in whatever
+    ** state it happened to be in at the time.
+    **/
+  virtual ~tcp_socket();
+
+  /** Resets the socket after a hard error.
+    **
+    ** In cases where the socket was invlidated by the operating system
+    ** (typically cases where a SIGPIPE was raised by the TCP/IP stack),
+    ** use this function to discard the old socket id and aquire a new one.
+    ** Understand that this will make the tcp_socket useful again, but you
+    ** will have to reconnect before any traffic can be sent.
+    **/
+  virtual void reset();
+
+  /** Creates a sockaddr_in from a formatted string.
+    ** 
+    ** address is an "IP:port" formatted string; i.e. 129.168.1.1:80. 
+    ** "*" may use used to substatute for the IP, port or both.
+    ** 
+    ** Returns a properly formatted sockaddr_in struct for use with connect,
+    ** bind, etc. Throws a bad_address_exception if the address argument is 
+    ** mal-formed.
+    **/
+  static sockaddr_in str_to_sockaddr(const std::string & address);
+
+  /** Creates a string from a sockaddr_in.
+    ** 
+    ** The returned string is of the same format accepted as arguments to the 
+    ** to the bind() and connect() methods.
+    ** 
+    ** May throw a bad_address_exception if the sock_addr_in is not 
+    ** properly formatted.
+    **/
+  static std::string sockaddr_to_str(const sockaddr_in & address);
+
+  /** binds the tcp_socket to a local address/port.
+    ** 
+    ** You do _not_ need to use this method if you are setting up a tcp_socket
+    ** for client use. If you don't call bind  an ephemeral port and the host's 
+    ** IP number will be assigned, as is normal and preferred for client sockets.
+    ** 
+    ** In very rare cases where you have a multi-homed host and a real
+    ** requirement to specify which IP this connection uses as local, you can
+    ** use this method to select the port and address the client will use.
+    ** 
+    ** address: string of the format IP:port; example "255.255.255.255:91". 
+    ** If you wish to accept input on any active IP address in this host, 
+    ** use "*" for the IP address, as in "*:80". If you want to fix the address
+    ** but leave the port up to the host, use "*" for the port, as in 
+    ** "10.101.78.33:*". Obviously, using "*:*" as the address gives the 
+    ** same results as not calling this method at all.
+    ** 
+    ** If the address argument is mal-formed a bad_address_exception will be
+    ** thrown and no changes will be made to the tcp_socket.
+    ** 
+    ** If the address is not bindable (already in use is a common cause) a 
+    ** cant_bind_exception will be thrown.
+    **/
+  void bind(const std::string & address);
+
+  /** Opens the connection.
+    **
+    ** address: string of the format IP:port; example "255.255.255.255:91". 
+    ** If the address is mal-formed a bad_address_exception will be thrown.
+    ** 
+    ** If timeout is specified and >0, the system will not wait more than
+    ** timeout seconds before throwing a timeout_exception.
+    ** 
+    ** If the connection is not set up properly, a bad_connection_exception
+    ** will be thrown.
+    **/
+  void connect(const std::string & address, int timeout=0);
+
+  /** Closes an open connection.
+    ** 
+    ** If a problem is reported a close_exception will be thrown. Possible
+    ** causes include the socket not being open, unsent data pending in the 
+    ** tcp stack, etc.
+    **/
+  virtual void close();
+  
+  /** Returns the current status.
+    ** 
+    ** Possibles states are tcp_socket::undef, tcp_socket::init, 
+    ** tcp_socket::connect, and tcp_socket::close.
+    **/
+  state status() { return _status; };
+
+  /** Returns the last socket error recieved.
+    ** 
+    ** Will contain zero if no errors have occured on the socket since 
+    ** the tcp_socket was instanciated, or the errno returned on the most recent
+    ** error otherwise.
+    ** 
+    ** Check the man pages for bind(), connect(), close(), socket(), send(),
+    ** and recv() for possible values. They are defined in error.h.
+    **/
+  int last_error() { return _last_error; };
+
+  /** Sends the string to the target host.
+    ** 
+    ** If timeout is specified and >0, a timeout_exception will be thrown 
+    ** if the send does not succeed within timeout seconds. 
+    ** 
+    ** If socket is not connected or closes during sending a 
+    ** not_open_exception will be thrown. 
+    ** 
+    ** If an exception is thrown, the characters that were not
+    ** sent will be available via the exception's comment() method (as
+    ** a string, of course).
+    **/
+  int put(std::string s, int timeout=10);
+
+  /** gets a string of characters from the socket.
+    ** 
+    ** This method allows the reception of a string of characters 
+    ** limited by length and time. Use this method when you are expecting a 
+    ** stream if data that you either know the length of or where there is
+    ** no specific ending character.  If the expected traffic is organized 
+    ** into messages or lines ending with a specific character or string, 
+    ** use the getln() method instead.
+    ** 
+    ** Examples:
+    ** 
+    ** get() or get(1) will return a string containing a single
+    ** character or throw a timeout in 10 seconds if one is not
+    ** recieved.
+    ** 
+    ** get(100,30) will return when 100 characters have been recieved or 
+    ** throw a timeout in 30 seconds.
+    ** 
+    ** get(100,-1) will return after 100 characters have been recieved, and will 
+    ** _never_ time out. I strongly recommend that at the very least use timeout
+    ** values >= 0 to this method to prevent program long term program stalls.
+    ** 
+    ** If maxlen==0, this method will return immediately with whatever characters
+    ** happen to be in the socket's input buffer at the time.
+    ** 
+    ** If maxlen>0 and timeout<0, this method will block until maxlen characters
+    ** have been recieved and then return. NOTE: this method could block 
+    ** forever if the sending host does not send maxlen characters and timeout
+    ** is < 0.
+    ** 
+    ** If maxlen>0 and timeout>0 this method will return upon recieving 
+    ** maxlen characters or throw a timeout_exception after timeout seconds 
+    ** have expired in the worse case.
+    ** 
+    ** In all cases the method returns a string containing the characters 
+    ** recieved, if any.
+    ** 
+    ** If the timeout expires before the required number of characters are
+    ** recieved a timeout_exception will be thrown. 
+    ** 
+    ** If the socket is not connected or closes while being read a 
+    ** not_open_exception will be thrown.
+    ** 
+    ** If an exception is thrown, any characters already recieved 
+    ** will be available via the exception's comment() method.
+    **/
+  std::string get(int maxlen=1, int timeout=10);
+
+  /** gets a string of characters from the socket.
+    ** 
+    ** This method is for the reception of messages (or lines) that have a 
+    ** specific ending string. As such it considers the recept of maxlen
+    ** characters or a timeout without the designated eol string to be 
+    ** a problem and will throw an exception in those cases. This behavor 
+    ** differs from that of the get() method, which simply returns when it 
+    ** has received its limit.
+    ** 
+    ** If there is no specific eol or eom string in your expected data 
+    ** stream use the get() method instead.
+    ** 
+    ** Examples:
+    ** 
+    ** getln() will return all characters recieved up to and including the 
+    ** first carrage return or throw a timeout if a carrage return is not
+    ** recieved after 10 seconds.
+    ** 
+    ** getln("</alert>") will return all characters recieved up to and
+    ** including "</alert>" or throw a timeout if "</alert>" is not recieved 
+    ** within 10 seconds.
+    ** 
+    ** getln(":",30) will return all characters recieved up to and including 
+    ** ":" if ":" is recieved by the 30th character. If 30 characters are recieved 
+    ** before ":", an overrun_exception would be thrown. A timeout would be
+    ** thrown if ":" is not recieved within 10 seconds.
+    ** 
+    ** getln(":",30,20) would react exactly like getln(":",30) except the timeout
+    ** period would be 20 seconds instead of the default 10.
+    ** 
+    ** getln(":",30,-1) will react exactly like getln(":",30) except that no
+    ** timeout will ever be thrown. In this case, the method may block 
+    ** forever if no ":" is received and it never receives 30 characters.
+    ** I strongly recommend that at the very least that timeout be a 
+    ** value >= 0 to this method to prevent program long term program stalls.
+    ** 
+    ** If maxlen==0 and timeout<0, this method will block until the eol
+    ** string is recieved from the host or maxlen characters
+    ** have been recieved. and then return. NOTE: this method could block 
+    ** forever if the sending host does not send maxlen characters or the
+    ** eol string and timeout is < 0;
+    ** 
+    ** If maxlen>0 and timeout>0 this method will return upon recieving the 
+    ** eol string, when maxlen characters have be recieved or when 
+    ** timeout seconds have expired.
+    ** 
+    ** In all cases the method returns a string containing the characters 
+    ** recieved, if any, including the eol string.
+    ** 
+    ** If the timeout expires before eol is recieved or maxlen characters are
+    ** recieved a timeout_exception will be thrown.
+    ** 
+    ** If maxlen characters are recieved before the eol string is recieved 
+    ** an overrun_exception will be thown.
+    ** 
+    ** If the socket is not connected or closes while being read a 
+    ** not_open_exception will be thrown.
+    ** 
+    ** If an exception is thrown, any characters already recieved 
+    ** will be available via the exception's comment() method.
+    **/
+  std::string getln(std::string eol="\r", int maxlen=0, int timeout=10);
+
+  /** Returns the local address.
+    ** 
+    ** Returns the address in the same form that it needs to be in for the 
+    ** bind and connect addess arguments.
+    ** 
+    ** May throw a buffer_full_exception if there are not enough resources, 
+    ** or a general_exception if some other problem occurs.
+    **/
+  std::string get_local_address();
+
+  /** Returns the remote address.
+    ** 
+    ** Returns the address in the same form that it needs to be in for the 
+    ** bind and connect addess arguments.
+    ** 
+    ** May throw a buffer_full_exception if there are not enough resources,
+    ** a not_open_exception if the socket has not been connected to a remote
+    ** host, or a general_exception if some other problem occurs.
+    **/
+  std::string get_remote_address();
 };
 
 /// smart pointer for use with tcp_sockets
-typedef std::unique_ptr<nrtb::tcp_socket> tcp_socket_p;
+typedef std::shared_ptr<nrtb::tcp_socket> tcp_socket_p;
 
-/** Abstract "listener" TCP/IP socket for servers. 
- ** 
- ** Simplifies the use of TCP/IP sockets for applications providing services.
- ** base_sock implements a free running thread that listens for connections on 
- ** the address and port specified and on connection calls the abstract method
- ** on_accept(). Upon return from on_accept the class returns to listening for
- ** the next connection.
- ** 
- ** Normal useage: This is an abstract class, so you must make a descendent 
- ** class that at a minimum overrides on_accept() to provide connection handling.
- ** That aside, a typical sequence for a descendent of this class would be: 
- ** 
- ** (1) construct the object providing the address, port and backlog; 
- ** 
- ** (2) when the application is ready to accept traffic it calls the 
- ** start_listen() method to start the listening on the socket; 
- ** 
- ** (3) as each connection is accepted, a new connect_sock* is contructed and 
- ** then on_accept() is called;
- ** 
- ** (4) on_accept() processes the connection, using connect_sock* to receive and
- ** send data. In most cases, on_accept will only place the new tcp_socket in 
- ** a queue for other threads to process so that on_accept() can return quickly;
- ** 
- ** (5) when on_accept() returns we start listening for the next connection.
- ** 
- ** (6) When the application wishes to stop accepting connections, it calls
- ** the stop_listen() method, which will return when as soon any current calls
- ** to on_accept() complete.
- ** 
- ** --NOTE--- This class is a tcp_socket_p factory in that a new one 
- ** is created for each request received. As the tcp_socket_p is a 
- ** smart pointer, the allocated socket will be closed and deallocated 
- ** when the last reference to the socket goes out of scope automatically.
- **
- ** Descendent classes must override on_accept() to provide the necessary
- ** connection handling. See the documentation on on_accept for more details.
+/** "listener" TCP/IP socket socket factory for servers. 
+ ** 
+ ** Upon construction this class establishes a listening socket
+ ** on the specified address and port. Each incomming connection
+ ** is automatically accepted and its socket put on queue for other 
+ ** tasks to process.  
  **/
-class tcp_server_socket_factory: private thread
+class tcp_server_socket_factory
 {
-
-	private:
-	
-		int _last_thread_fault;
-		// Provides the listener thread.
-		void run();
-    // pointer to the listener socket
-    typedef std::shared_ptr<tcp_socket> lsock_p;
-    lsock_p listen_sock;
-		
-	protected:
-
-		/// the address:port the listening socket will connect to.
-		std::string _address;
-		unsigned short int _backlog;
-		
-		/** Pointer to the socket for the current connection. This is 
-		 ** only safe to use/manipulate after entry of the method on_accept(); 
-		 ** at any other time this pointer may be altered without notice. 
-		 ** 
-		 ** At entry to on_accept() this will point to a valid tcp_socket_p
-		 ** smart pointer. As with all smart pointers, the object it 
-		 ** points to will be deleted automatically when the last 
-		 ** reference to it goes out of scope. 
-		 **/
-		tcp_socket_p connect_sock;
-
-		/** Abstract method to process connections. An on_accept() call is 
-		 ** made on every connection accepted immediately after constructing a 
-		 ** new base_sock socket for it (pointed to by connect_sock).
-		 ** 
-		 ** It is expected that a useful on_accept() method must either place
-		 ** the connection information (presumably including conect_sock*) on 
-		 ** a queue for the application to process later, or process the connection
-		 ** itself. It is desireable for on_accept() to return quickly to minimize
-		 ** connection latency, so for most applications you'll want to queue
-		 ** the connection for processing by another thread.
-		 ** 
-		 ** on_accept() should return true to contine processing, or false 
-		 ** to force a shutdown of the listener.
-		 ** 
-		 ** WARNING: While this class attempts to respect the integrity of any code
-		 ** placed in on_accept(), you must be aware that it may be cancelled 
-		 ** quite rudely if any given call to on_accept() takes more than 30 
-		 ** seconds to process. on_accept() is run with the cancel_anytime attribute
-		 ** set, and this can not be changed from within the method. Therefore, 
-		 ** take care that on_accept() either runs within 30 seconds or at the 
-		 ** very least that it does not hold any resource (mutex, etc.) locks 
-		 ** by the time it's run over 20 seconds or so. Failure to follow these
-		 ** guidelines could result in program deadlocks should on_accept be 
-		 ** cancelled while holding a resource lock.
-		 **/
-		virtual bool on_accept() = 0;
-		
-	public:
-
-		/// Use to catch all server_socket_factory exceptions.
-		class general_exception: public base_exception {};
-		/// Thrown if we can not allocate a new connect_sock* as needed.
-		class mem_exhasted_exception: public general_exception {};
-		/// Thrown by start_listen() if the IP/port could not be bound.
-		class bind_failure_exception: public general_exception {};
-		/** Thrown by stop_listen() if on_accept takes more than 30 seconds 
-		 ** to return.
-		 **/
-		class on_accept_bound_exception: public general_exception {};
-		/// Thrown by by the listen thread in case of unexpected error.
-		class listen_terminated_exception: public general_exception {};
-		
-		/** Construct a tcp_server_socket_factory. 
-		 ** 
-		 ** address: std::string of the format IP:port; example "255.255.255.255:91". 
-		 ** if you wish to accept input on any active IP address in this host, 
-		 ** use "*" for the IP address, as in "*:80". The port number is 
-		 ** required.
-		 ** 
-		 ** backlog: The number of backlog connections (connections pending accept)
-		 ** allowed for this socket. The limit is operating system dependent. If
-		 ** the supplied value is 0 or less, the default value for the operating 
-		 ** system will be used.
-		 **/
-		tcp_server_socket_factory(const std::string & address, 
-			const unsigned short int & backlog);
-
-		/** Destructs a server_sock. 
-		 ** 
-		 ** If the server_sock is currently listening the listener thread is 
-		 ** shut down and the socket released immediately, rudely if necessary.
-		 ** 
-		 ** It's preferable to call stop_listen() before desconstruction to allow 
-		 ** graceful termination of the listener thread and teardown of the port.
-		 **/
-		virtual ~tcp_server_socket_factory();
-
-		/** Initiate listening for inbound connections.
-		 ** 
-		 ** This opens the port and spawns the listener thread, then returns
-		 ** immediately. An exception will be thrown if a problem occurs.  
-		 ** 
-		 ** If the listener thread is already running this method returns
-		 ** immediately without taking any action.
-		 ** 
-		 ** Call this method when your application is ready to start recieving
-		 ** connections. Once started, the server_sock will call on_accept() 
-		 ** for each connection recieved until stop_listen() is called.
-		 **/
-		void start_listen();
-
-		/** Stop listening for inbound connections.
-		 ** 
-		 ** This shuts down the listener thread and tears down the TCP/IP port 
-		 ** before returning. An exception will be thrown if a problem occurs.
-		 ** 
-		 ** If a connection is being actively processed (defined as thread 
-		 ** execution being post accept() and prior to the return of on_accept()),
-		 ** the return will be delayed until on_accept() is complete, though 
-		 ** the listening socket will be torn down immediately. If on_accept()
-		 ** fails to return within 30 seconds, the listener thread will be
-		 ** rudely murdered and an on_accept_bound_exception will be thrown. In the
-		 ** worse case it may be that the listener thread will not die for some time,
-		 ** though it should be cleanly cancelable at most any time.
-		 ** 
-		 ** If the listener thread is not running this method returns immediately
-		 ** without taking any actions.
-		 ** 
-		 ** Call this method when your application wishes to stop recieving input, 
-		 ** even if you are going to restart reception later. 
-		 **/
-		void stop_listen();
-
-		/** Monitors listening status.
-		 ** 	
-		 ** At it's simplist, this method returns true if the socket is listening 
-		 ** for new connections, and false if if it not. Additionally, this 
-		 ** method will throw a listen_terminated_exception if the listener thread
-		 ** died unexpectedly. Therefore, calling this method periodically is an
-		 ** easy way to monitor the health of the listener thread.
-		 **/
-		bool listening();
-
-		/** Returns the last listen thread fault code.
-		 ** 
-		 ** Will be 0 if the listener has never faulted. If -1, an untrapped 
-		 ** exception was caught (likely thrown by on_accept()); if -2 the thread 
-		 ** did not manage to initialize the listening socket successfully, and  
-		 ** if > 0 then it'll be the error code of the socket error caught that 
-		 ** forced the thread shutdown.
-		 ** 
-		 ** check this if you catch a listen_terminated_exception to find out
-		 ** what really happened.
-		 **/
-		 int last_fault();
-
-		/** Returns the max number of backlog connections.
-		 **/
-		unsigned short int backlog();
-
+public:
+
+  /// Use to catch all server_socket_factory exceptions.
+  class general_exception: public base_exception {};
+  /// Thrown if start_listen is called while already listening
+  class already_running_exception: public general_exception {};
+  /// Thrown if we can not allocate a new connect_sock* as needed.
+  class mem_exhasted_exception: public general_exception {};
+  /// Thrown by start_listen() if the IP/port could not be bound.
+  class bind_failure_exception: public general_exception {};
+  /// Thrown by by the listen thread in case of unexpected error.
+  class listen_terminated_exception: public general_exception {};
+  /// handlers should catch this and shutdown gracefully.
+  typedef circular_queue<tcp_socket_p>::queue_not_ready queue_not_ready;
+  
+  /** Construct a tcp_server_socket_factory and puts it online.
+    ** 
+    ** address: std::string of the format IP:port; example "255.255.255.255:91". 
+    ** if you wish to accept input on any active IP address in this host, 
+    ** use "*" for the IP address, as in "*:80". The port number is 
+    ** required.
+    ** 
+    ** backlog: The number of backlog connections (connections pending accept)
+    ** allowed for this socket. The limit is operating system dependent. If
+    ** the supplied value is 0 or less, the default value for the operating 
+    ** system will be used.
+    ** 
+    ** queue_size: Optional; the size of the queue for connections
+    ** waiting to be serviced. Defaults to 10. If queue_size is 
+    ** exceeded, oldest connections will be discarded. 
+    **/
+  tcp_server_socket_factory(const std::string & address, 
+	const unsigned short int backlog = 5,
+	const int queue_size=10);
+
+  /** Destructs a server_sock. 
+    ** 
+    ** If the server_sock is currently listening the listener thread is 
+    ** shut down and the socket released immediately, rudely if necessary.
+    ** 
+    ** It's preferable to call stop_listen() before desconstruction to allow 
+    ** graceful termination of the listener thread and teardown of the port.
+    **/
+  virtual ~tcp_server_socket_factory();
+
+  /// Consumers call this to get a connected socket.
+  tcp_socket_p get_sock() { return pending.pop(); };
+  
+  /// returns the number of connections received.
+  int accepted() { return pending.in_count; };
+  /// returns the number of connections consumed.
+  int processed() { return pending.out_count; };
+  /// returns the number of connections waiting to be consumed.
+  int available() { return pending.size(); };
+  /// returns the number of connections dropped due to overflow.
+  int discarded() 
+  { 
+    return pending.in_count - 
+	pending.out_count - pending.size(); 
+  };
+
+  /** Stop listening for inbound connections.
+    ** 
+    ** This shuts down the listener thread and tears down the TCP/IP port 
+    ** before returning. An exception will be thrown if a problem occurs.
+    ** 
+    ** If a connection is being actively processed (defined as thread 
+    ** execution being post accept() and prior to the return of on_accept()),
+    ** the return will be delayed until on_accept() is complete, though 
+    ** the listening socket will be torn down immediately. If on_accept()
+    ** fails to return within 30 seconds, the listener thread will be
+    ** rudely murdered and an on_accept_bound_exception will be thrown. In the
+    ** worse case it may be that the listener thread will not die for some time,
+    ** though it should be cleanly cancelable at most any time.
+    ** 
+    ** If the listener thread is not running this method returns immediately
+    ** without taking any actions.
+    ** 
+    ** Call this method when your application wishes to stop recieving input, 
+    ** even if you are going to restart reception later. 
+    **/
+  void stop_listen();
+
+  /** Starts a stopped listener
+   **/
+  void start_listen();
+
+  /** Monitors listening status.
+    ** 	
+    ** At it's simplist, this method returns true if the socket is listening 
+    ** for new connections, and false if if it not. Additionally, this 
+    ** method will throw a listen_terminated_exception if the listener thread
+    ** died unexpectedly. Therefore, calling this method periodically is an
+    ** easy way to monitor the health of the listener thread.
+    **/
+  bool listening();
+
+  /** Returns the last listen thread fault code.
+    ** 
+    ** Will be 0 if the listener has never faulted. If -1, an untrapped 
+    ** exception was caught (likely thrown by on_accept()); if -2 the thread 
+    ** did not manage to initialize the listening socket successfully, and  
+    ** if > 0 then it'll be the error code of the socket error caught that 
+    ** forced the thread shutdown.
+    ** 
+    ** check this if you catch a listen_terminated_exception to find out
+    ** what really happened.
+    **/
+    int last_fault();
+
+  /** Returns the max number of backlog connections.
+    **/
+  unsigned short int backlog();
+
+private:
+
+  // the address:port the listening socket will connect to.
+  std::string _address;
+  unsigned short int _backlog;
+  // stuff for the listener thread
+  std::thread work_thread;
+  std::shared_ptr<tcp_socket> listen_sock {nullptr};
+  std::atomic< int > _last_thread_fault {0};
+  std::atomic< bool > in_run_method {false};
+  // The accepted inbound connection queue
+  nrtb::circular_queue<tcp_socket_p> pending;
+  // Provides the listener thread.
+  static void run(tcp_server_socket_factory * server);
+  
 };
 
 } // namepace nrtb

=== modified file 'cpp/common/sockets/socket_test.cpp'
--- obsolete/Cpp/common/sockets/socket_test.cpp	2012-04-07 14:16:46 +0000
+++ cpp/common/sockets/socket_test.cpp	2013-08-09 21:47:12 +0000
@@ -19,57 +19,44 @@
 #include <iostream>
 #include <sstream>
 #include <string>
+#include <future>
+#include <typeinfo>
+#include <common.h>
 #include <boost/random.hpp>
 #include "base_socket.h"
 
 using namespace nrtb;
 using namespace std;
 
-class myserver: public tcp_server_socket_factory
+int request_processor(tcp_server_socket_factory & server)
 {
-public:
-  int hits;
-  int errors;
-
-  // constructor
-  myserver(const string & a, const unsigned short int & b)
-    : tcp_server_socket_factory(a,b)
-  {
-    // Don't need to lock here because we know the
-    // listener thread is not running.
-    hits = 0;
-    errors = 0;
-  };
-
-protected:
-
-  // on_accept() is called on each connection.
-  bool on_accept()
+  int hits {0};
+  bool done {false};
+  while (!done)
   {
     try
     {
-      tcp_socket_p sock = std::move(connect_sock);
+      auto sock = server.get_sock();
       // just return what we've recieved.
       string msg = sock->getln();
       sock->put(msg);
       // Update our hit count.
       hits++;
     }
-    catch (base_exception & e)
+    catch (tcp_server_socket_factory::queue_not_ready)
     {
-      errors++;
-      cerr << "server Caught " << e.what() << endl;
+      done = true;
     }
-    catch (...)
+    catch (exception & e)
     {
-      errors++;
-      cerr << "Unexpected error in on_accept()" << endl;
+      cout << "ReqProc recieved " 
+	<< typeid(e).name()
+	<< endl;
+      done = true;
     };
-    if (hits > 99)
-      return false;
-    else
-      return true;
-  };
+  }; 
+  cout << "Request processor shut down." << endl;
+  return hits;
 };
 
 string transceiver(const string address, const string sendme)
@@ -88,7 +75,11 @@
 
 int main()
 {
-  int er_count = 0;
+  cout << "=========== tcp_socket and server test ============="
+    << endl;
+
+  int er_count {0};
+  int hits {0};
   //set up our port and address
   boost::mt19937 rng;
   rng.seed(time(0));
@@ -98,14 +89,17 @@
   address = s.str();
   cout << "Using " << address << endl;
   
-  myserver test_server(address,5);
+  tcp_server_socket_factory test_server(address);
 
   try
   {
     // start the receiver/server
     test_server.start_listen();
     cout << "test_server ready." << endl;
-
+    auto rp_out = 
+      async(launch::async,request_processor,std::ref(test_server));
+    cout << "Request processor attached." << endl;
+    
     // Send test messages
     for (int i = 0; i < 100; i++)
     {
@@ -117,60 +111,22 @@
       {
         er_count++;
       };
-      cout << returned.substr(0,returned.size()-1) << ": "
-      << ((returned == checkme) ? "Passed" : "Failed")
+    };
+    test_server.stop_listen();
+    hits = rp_out.get();
+  }
+  catch (tcp_server_socket_factory::general_exception & e)
+  {
+    cout << "Server exception " 
+      << typeid(e).name() << " was caught."
+      << "\n\tComment: " << e.comment() 
       << endl;
-    };
-  }
-  catch (myserver::bind_failure_exception)
-  {
-    cout << "Could not bind port" << endl;
-  }
-  catch (myserver::mem_exhasted_exception)
-  {
-    cout << "myserver reports out of memory." << endl;
-  }
-  catch (myserver::listen_terminated_exception)
-  {
-    cout << "Listener terminated unexpectedly." << endl;
-  }
-  catch (myserver::on_accept_bound_exception)
-  {
-    cout << "myserver::on_accept() seems bound." << endl;
-  }
-  catch (tcp_socket::bad_connect_exception & e)
-  {
-    cout << "A bad_connect_exception was thrown.\n"
-      << "  comment: " << e.comment() << endl;
-    cout << "  test_server.last_fault() = "
-      << test_server.last_fault() << endl;
-  }
-  catch (tcp_socket::not_open_exception & e)
-  {
-    cout << "A tcp not open exception was caught.\n"
-      << e.comment() << endl;
-  }
-  catch (tcp_socket::close_exception & e)
-  {
-    cout << "A close_exception was caught.\n"
-      << e.comment() << endl;
-  }
-  catch (tcp_socket::overrun_exception & e)
-  {
-    cout << "An overrun_exception was caught.\n"
-      << e.comment() << endl;
-  }
-  catch (tcp_socket::buffer_full_exception & e)
-  {
-    cout << "A buffer_full_exception was caught.\n"
-      << e.comment() << endl;
   }
   catch (tcp_socket::general_exception & e)
   {
-    cout << "A tcp_socket exception was caught.\n"
-      << "  comment: " << e.comment() << endl;
-    cout << "  test_server.last_fault() = "
-      << test_server.last_fault() << endl;
+    cout << "Socket exception "
+      << typeid(e).name() << " was caught.\n"
+      << "\tComment: " << e.comment() << endl;
   }
   catch (exception & e)
   {
@@ -178,15 +134,25 @@
       << " exception was caught." << endl;
   };
 
+  // test server status billboard
+  cout << "Test Server Results:"
+    << "\n\tAccepted:  " << test_server.accepted()
+    << "\n\tProcessed: " << test_server.processed()
+    << "\n\tAvailable: " << test_server.available()
+    << "\n\tDiscarded: " << test_server.discarded()
+    << "\n\tLast Fault: " << test_server.last_fault()
+    << endl;
   // final check.
-  if (test_server.hits != 100)
+  if (hits != test_server.accepted() 
+    or hits != test_server.processed()
+    or test_server.discarded() != 0  )
   {
     er_count++;
     cout << "Server does not report the proper number of hits.\n"
-      << "\tExpected 100, got " << test_server.hits
+      << "\tExpected 100, got " << hits
       << endl;
   };
-  cout << "=========== tcp_socket test complete ============="
+  cout << "=========== tcp_socket and server test complete ============="
     << endl;
   
   return er_count;

=== added directory 'cpp/common/timer'
=== added file 'cpp/common/timer/Makefile'
--- cpp/common/timer/Makefile	1970-01-01 00:00:00 +0000
+++ cpp/common/timer/Makefile	2013-08-09 21:47:12 +0000
@@ -0,0 +1,38 @@
+#***********************************************
+#This file is part of the NRTB project (https://launchpad.net/nrtb).
+#
+#    NRTB is free software: you can redistribute it and/or modify
+#    it under the terms of the GNU General Public License as published by
+#    the Free Software Foundation, either version 3 of the License, or
+#    (at your option) any later version.
+#
+#    NRTB 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 General Public License for more details.
+#
+#    You should have received a copy of the GNU General Public License
+#    along with NRTB.  If not, see <http://www.gnu.org/licenses/>.
+#
+#***********************************************
+
+switches=-std=gnu++11 -D _GLIBCXX_USE_SCHED_YIELD -D _GLIBCXX_USE_NANOSLEEP
+
+lib:	timer_test
+	@./timer_test
+	@cp -v hires_timer.h ../include
+	@cp -v hires_timer.o ../obj
+	@echo build complete
+
+hires_timer.o:	hires_timer.h hires_timer.cpp Makefile
+	@rm -f hires_timer.o
+	g++ -c -O3 hires_timer.cpp ${switches}
+
+timer_test:	hires_timer.o timer_test.cpp
+	@rm -f timer_test
+	g++ -c timer_test.cpp ${switches}
+	g++ -o timer_test timer_test.o hires_timer.o ${switches}
+
+clean:
+	@rm -rvf *.o timer_test ../include/hires_timer.h ../obj/hires_timer.o
+	@echo all objects and executables have been erased.

=== added file 'cpp/common/timer/hires_timer.cpp'
--- cpp/common/timer/hires_timer.cpp	1970-01-01 00:00:00 +0000
+++ cpp/common/timer/hires_timer.cpp	2013-08-09 21:47:12 +0000
@@ -0,0 +1,174 @@
+/***********************************************
+ This file is part of the NRTB project (https://*launchpad.net/nrtb).
+ 
+ NRTB is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+ 
+ NRTB 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 General Public License for more details.
+ 
+ You should have received a copy of the GNU General Public License
+ along with NRTB.  If not, see <http://www.gnu.org/licenses/>.
+ 
+ **********************************************/
+/* see ricklib_timers.h for whatever documentation you can find */
+#include "hires_timer.h"
+#include <math.h>
+#include <sstream>
+
+namespace nrtb
+{
+
+hirez_timer::hirez_timer(const double init)
+{
+	reset();
+	start(init);
+};
+
+hirez_timer::hirez_timer(const timeval & init)
+{
+	reset();
+	start(init);
+};
+
+void hirez_timer::reset()
+{
+	running = false;
+	starttime = 0;
+	elapsed = 0;
+};
+
+void hirez_timer::start(const double init)
+{
+	if (!running)
+	{
+		timeval startt;
+		gettimeofday(&startt,0);
+		starttime = tv_to_ll(startt);
+		if (init > 0)
+		{
+			starttime -= double_to_ll(init);
+		};
+	};
+	running = true;
+};
+
+void hirez_timer::start(const timeval & init)
+{	
+	starttime = tv_to_ll(init);
+	running = true;
+};
+
+double hirez_timer::stop()
+{
+	stop_timer();
+	return ll_to_double(elapsed);
+};
+
+unsigned long long hirez_timer::stop_as_usec()
+{
+	stop_timer();
+	return elapsed;
+};
+
+double hirez_timer::interval()
+{
+	return ll_to_double(interval_time());
+};
+
+unsigned long long hirez_timer::interval_as_usec()
+{
+	return interval_time();
+};
+
+tm hirez_timer::interval_as_tm()
+{
+	time_t temp = (interval_time()+500000)/1000000;
+	return *gmtime(&temp);
+};
+
+double hirez_timer::ll_to_double(const unsigned long long int ll)
+{
+	return ll / (double) 1e6;
+};
+
+timeval hirez_timer::ll_to_tv(const unsigned long long int ll)
+{
+	timeval t;
+	t.tv_sec = ll / (unsigned long long int) 1e6;
+	t.tv_usec = ll % (unsigned long long int) 1e6;
+	return t;
+};
+
+unsigned long long int hirez_timer::tv_to_ll(const timeval & tv)
+{
+	return ((unsigned long long) tv.tv_sec * (unsigned long long) 1e6) 
+		+ (unsigned long long) tv.tv_usec;
+};
+
+unsigned long long int hirez_timer::double_to_ll(const double d)
+{
+	return (unsigned long long int) floor(d * 1e6);
+};
+
+void hirez_timer::stop_timer()
+{
+	if (running)
+	{
+		timeval endtime;
+		gettimeofday(&endtime,0);
+		elapsed += (tv_to_ll(endtime) - starttime);
+	};
+	running = false;
+};
+
+unsigned long long int hirez_timer::interval_time()
+{
+	if (running)
+	{
+		timeval endtime;
+		gettimeofday(&endtime,0);
+		return elapsed + (tv_to_ll(endtime) - starttime);
+	}
+	else
+	{
+		return elapsed;
+	};
+};
+
+std::string hirez_timer::interval_as_HMS(const bool days)
+{
+	// local working vars.
+	std::stringstream output;
+	double t1;
+	long int t2;
+	t1 = interval();
+	// Days (only if needed)
+	if (days)
+	{
+		t2 = long(t1) / 86400l;
+		if (t2 > 0)
+		{
+			output << t2 << "d, ";
+			t1 -= t2 * 86400l;
+		};
+	};
+	// hours
+	t2 = long(t1) / 3600;
+	output << t2;
+	t1 -=  t2 * 3600;
+	// minutes
+	t2 = long(t1) / 60;
+	output << ((t2 < 10) ? ":0" : ":") << t2;
+	t1 -= t2 * 60;
+	// seconds
+	output << ((t1 < 10) ? ":0" : ":") << t1;
+	return output.str();
+};
+
+} // namespace ricklib;
+

=== added file 'cpp/common/timer/hires_timer.h'
--- cpp/common/timer/hires_timer.h	1970-01-01 00:00:00 +0000
+++ cpp/common/timer/hires_timer.h	2013-08-09 21:47:12 +0000
@@ -0,0 +1,131 @@
+/***********************************************
+ This file is part of the NRTB project (https://*launchpad.net/nrtb).
+ 
+ NRTB is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+ 
+ NRTB 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 General Public License for more details.
+ 
+ You should have received a copy of the GNU General Public License
+ along with NRTB.  If not, see <http://www.gnu.org/licenses/>.
+ 
+ **********************************************/
+#ifndef nrtb_timer_h
+#define nrtb_timer_h
+
+#include <sys/time.h>
+#include <time.h>
+#include <string>
+
+namespace nrtb
+{
+
+/** Provides a timer with microsecond (1e-6 second) resolution.
+ ** 
+ ** Actual resolution on x86 machines is probably closer to 1e-4 or
+ ** -5, but it's still pretty good.
+ ** 
+ ** Usage notes: instanciating this class will start the timer 
+ ** automagically. 
+ **/
+class hirez_timer
+{
+	public:
+		/** initializes the timer and starts it.
+		 ** 
+		 ** Sets the the timer's elapsed time to init number of seconds and
+		 ** then starts the timer.
+		 **/
+		hirez_timer(const double init = 0);
+		/** initalizes the timer and starts it.
+		 ** 
+		 ** The timer's elapsed time is set to match the value provided in
+		 ** init, and the timer is started.
+		 **/
+		hirez_timer(const timeval & init);
+
+		/** Clears the timer.
+		 ** 
+		 ** If the timer is running, this stops it as well.
+		 **/
+		void reset();
+		/** Starts the timer.
+		 ** 
+		 ** Starts the timer, and optionally sets the elapsed time at
+		 ** startup to the value provided in init.
+		 **/
+		void start(const double init = 0);
+		/** Starts the timer.
+		 ** 
+		 ** Sets the elapsed time equal to the value provided in  init
+		 ** and then starts the timer.
+		 **/
+		void start(const timeval & init);
+		/** Stops the timer.
+		 ** 
+		 ** Unconditionally stops the timer, preserving the current
+		 ** values. It may be restarted using the start() method, 
+		 ** acummulating from where is stopped.
+		 ** 
+		 ** Returns the elapsed time in seconds.
+		 **/
+		double stop();
+		/** Stops the timer.
+		 ** Unconditionally stops the timer, preserving the current
+		 ** values. It may be restarted using the start() method, 
+		 ** acummulating from where is stopped.
+		 ** 
+		 ** The return value is the elapsed time in microseconds 
+		 ** (1e-6 seconds).
+		 **/
+		unsigned long long stop_as_usec();
+		/** Returns the current elapsed time.
+		 ** 
+		 ** Returns the number of elapsed seconds on the timer. No change
+		 ** is made to the timer's status.
+		 **/
+		double interval();
+		/** Returns the current elapsed time.
+		 ** 
+		 ** Returns the elapsed time in microseconds (1e-6 seconds). No
+		 ** change is made to the timer's status.
+		 **/
+		unsigned long long interval_as_usec();
+		/** Returns the elapsed time in a tm struct.
+		 ** 
+		 ** See "man gmtime" for the structure of the tm struct. In short
+		 ** though, this method provides the current timer value in a
+		 ** structure where it's broken down into hours, minutes, seconds and
+		 ** the like. No change is made to the timer's status.
+		 **/
+		 tm interval_as_tm();
+		/** Returns the elapsed time in H:MM:SS format
+		 **
+		 ** Returns the elapsed time in a std::string. The formate is
+		 ** H:MM:SS.sssss. No change is made to the timer's status.
+		 ** If the optional days parameter is set to true, the number
+		 ** of days will be displayed and hours will be < 24, otherwise
+		 ** no days are shown and hours will grow as needed (default).
+		**/
+		std::string interval_as_HMS(const bool days = false);
+	private:
+		unsigned long long int starttime;
+		unsigned long long int elapsed;
+		bool running;
+
+		inline double ll_to_double(const unsigned long long int ll);
+		inline timeval ll_to_tv(const unsigned long long int ll);
+		inline unsigned long long int double_to_ll(const double d);
+		inline unsigned long long int tv_to_ll(const timeval & tv);
+		inline void stop_timer();
+		inline unsigned long long int interval_time();
+};
+
+}; // namespace nrtb
+
+#endif // nrtb_timer_h

=== added file 'cpp/common/timer/timer_test.cpp'
--- cpp/common/timer/timer_test.cpp	1970-01-01 00:00:00 +0000
+++ cpp/common/timer/timer_test.cpp	2013-08-09 21:47:12 +0000
@@ -0,0 +1,72 @@
+/***********************************************
+ This file is part of the NRTB project (https://*launchpad.net/nrtb).
+ 
+ NRTB is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+ 
+ NRTB 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 General Public License for more details.
+ 
+ You should have received a copy of the GNU General Public License
+ along with NRTB.  If not, see <http://www.gnu.org/licenses/>.
+ 
+ **********************************************/
+/* hirez_timer test program */
+
+#include <iostream>
+#include <unistd.h>
+#include "hires_timer.h"
+
+using namespace nrtb;
+using namespace std;
+
+int main()
+{
+	hirez_timer overall;
+	hirez_timer interval;
+	int returnme = 0;
+	try
+	{
+	  overall.start();
+	  interval.start();
+	  cout << "sleep 0.1 second" << endl;
+	  usleep(1e5);
+	  cout << overall.interval() << " | " << interval.stop() << " (stop)" << endl;
+	  cout << "sleep 0.3 seconds" << endl;
+	  usleep(3e5);
+	  cout << overall.interval() << " | " << interval.stop() << " (start)" << endl;	
+	  interval.start();
+	  cout << "sleep 0.2 seconds" << endl;
+	  usleep(2e5);
+	  cout << overall.interval() << " | " << interval.stop() << " (reset)" << endl;
+	  interval.reset();
+	  interval.start();
+	  cout << "sleep 0.5 seconds" << endl;
+	  usleep(5e5);
+	  cout << overall.interval() << " | " << interval.stop() << endl;
+	  // test the advanced formationg function
+	  interval.start(109472.34);
+	  interval.stop();
+	  cout << "Extended interval_as_HMS() test: \""
+		  << interval.interval_as_HMS(true)
+		  << "\" or \"" << interval.interval_as_HMS() << "\"" << endl;
+	  cout << "Total run time: " << overall.stop() << " seconds." << endl;
+	  if ((overall.interval() < 1.1) or (overall.interval() > 1.105))
+	  {
+		cerr << "Measured runtime " 
+		  << overall.interval()
+		  << " is outside of expected limits, failed test" << endl;
+		returnme = 1;
+	  };
+	}
+	catch (...)
+	{
+	  returnme = 1;
+	};
+	return returnme;
+};
+

=== removed file 'obsolete/Cpp/common/logger/log_setup.cpp'
--- obsolete/Cpp/common/logger/log_setup.cpp	2010-12-27 04:21:16 +0000
+++ obsolete/Cpp/common/logger/log_setup.cpp	1970-01-01 00:00:00 +0000
@@ -1,43 +0,0 @@
-/***********************************************
- This file is part of the NRTB project (https://*launchpad.net/nrtb).
- 
- NRTB is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
- 
- NRTB 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 General Public License for more details.
- 
- You should have received a copy of the GNU General Public License
- along with NRTB.  If not, see <http://www.gnu.org/licenses/>.
- 
- **********************************************/
- 
-#include "log_setup.h"
-
-#include "Poco/SimpleFileChannel.h"
-#include "Poco/FormattingChannel.h"
-#include "Poco/PatternFormatter.h"
-#include "Poco/Logger.h"
-#include "Poco/AutoPtr.h"
-
-using Poco::SimpleFileChannel;
-using Poco::FormattingChannel;
-using Poco::PatternFormatter;
-using Poco::Logger;
-using Poco::AutoPtr;
-
-void nrtb::setup_global_logging(const std::string & logfilename)
-{
-  AutoPtr<SimpleFileChannel> pFile(new SimpleFileChannel);
-  pFile->setProperty("path", logfilename);
-  pFile->setProperty("rotation", "250 K");
-  AutoPtr<PatternFormatter> pPF(new PatternFormatter);
-  pPF->setProperty("pattern", "%Y-%m-%d %H:%M:%S [%s:%p] %t");
-  AutoPtr<FormattingChannel> pFC(new FormattingChannel(pPF, pFile));
-  Logger::root().setChannel(pFC);
-  Logger::root().notice("Logging system initialized");
-}
\ No newline at end of file

=== removed file 'obsolete/Cpp/common/logger/log_setup.h'
--- obsolete/Cpp/common/logger/log_setup.h	2010-12-27 03:55:39 +0000
+++ obsolete/Cpp/common/logger/log_setup.h	1970-01-01 00:00:00 +0000
@@ -1,30 +0,0 @@
-/***********************************************
- This file is part of the NRTB project (https://*launchpad.net/nrtb).
- 
- NRTB is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
- 
- NRTB 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 General Public License for more details.
- 
- You should have received a copy of the GNU General Public License
- along with NRTB.  If not, see <http://www.gnu.org/licenses/>.
- 
- **********************************************/
- 
-#ifndef logger_setup_h
-#define logger_setup_h
-
-#include <string>
-
-namespace nrtb
-{
-
-  void setup_global_logging(const std::string & logfilename);
-}
-
-#endif //logger_setup_h
\ No newline at end of file

=== removed file 'obsolete/Cpp/common/logger/log_test.cpp'
--- obsolete/Cpp/common/logger/log_test.cpp	2010-12-31 12:21:51 +0000
+++ obsolete/Cpp/common/logger/log_test.cpp	1970-01-01 00:00:00 +0000
@@ -1,46 +0,0 @@
-/***********************************************
- This file is part of the NRTB project (https://*launchpad.net/nrtb).
- 
- NRTB is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
- 
- NRTB 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 General Public License for more details.
- 
- You should have received a copy of the GNU General Public License
- along with NRTB.  If not, see <http://www.gnu.org/licenses/>.
- 
- **********************************************/
- 
-#include "log_setup.h"
-
-#include <string>
-#include <iostream>
-#include <Poco/Logger.h>
-#include "Poco/LogStream.h"
-
-using namespace std;
-
-int main()
-{
-  bool set_if_failed = false;
-  try
-  {
-	nrtb::setup_global_logging("test_output.log");
-	Poco::Logger & logger = Poco::Logger::get("log_test");
-	logger.notice("Logging should be set up now.");
-	Poco::LogStream log(logger);
-	log << "This message used the stream interface" << endl;
-	logger.notice("Program run complete.");
-  }
-  catch (...)
-  {
-	set_if_failed = true;
-	cout << "** UNIT TEST FAILED **" << endl;
-  };
-  return set_if_failed;
-}

=== renamed directory 'D_lang' => 'obsolete/D_lang'
=== added directory 'obsolete/cpp'
=== renamed directory 'obsolete/Cpp/common/GPB' => 'obsolete/cpp/GPB'
=== renamed directory 'obsolete/Cpp/common/comm_handlers' => 'obsolete/cpp/comm_handlers'
=== renamed directory 'obsolete/Cpp/common/threads' => 'obsolete/cpp/threads'
=== renamed directory 'obsolete/Cpp/common/timer' => 'obsolete/cpp/timer'
=== renamed directory 'obsolete/Cpp/common/transceiver' => 'obsolete/cpp/transceiver'

Follow ups