You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by ac...@apache.org on 2006/11/29 15:36:12 UTC

svn commit: r480582 [1/2] - in /incubator/qpid/trunk/qpid/cpp: ./ src/qpid/ src/qpid/apr/ src/qpid/broker/ src/qpid/client/ src/qpid/posix/ src/qpid/sys/ test/client/ test/unit/qpid/ test/unit/qpid/posix/

Author: aconway
Date: Wed Nov 29 06:36:08 2006
New Revision: 480582

URL: http://svn.apache.org/viewvc?view=rev&rev=480582
Log:
Posix EventChannel implementation using epoll. Placeholder for kevents.
Dynamic thread pool EventChannelThreads to serve EventChannel.
Misc cleanup/enhancements.

Added:
    incubator/qpid/trunk/qpid/cpp/src/qpid/ExceptionHolder.cpp   (with props)
    incubator/qpid/trunk/qpid/cpp/src/qpid/ExceptionHolder.h   (with props)
    incubator/qpid/trunk/qpid/cpp/src/qpid/posix/EventChannel.cpp   (with props)
    incubator/qpid/trunk/qpid/cpp/src/qpid/posix/EventChannel.h   (with props)
    incubator/qpid/trunk/qpid/cpp/src/qpid/posix/EventChannelThreads.cpp   (with props)
    incubator/qpid/trunk/qpid/cpp/src/qpid/posix/EventChannelThreads.h   (with props)
    incubator/qpid/trunk/qpid/cpp/src/qpid/sys/AtomicCount.h   (with props)
    incubator/qpid/trunk/qpid/cpp/src/qpid/sys/Mutex.h   (with props)
    incubator/qpid/trunk/qpid/cpp/src/qpid/sys/Runnable.cpp   (with props)
    incubator/qpid/trunk/qpid/cpp/test/unit/qpid/ExceptionTest.cpp   (with props)
    incubator/qpid/trunk/qpid/cpp/test/unit/qpid/posix/EventChannelTest.cpp   (with props)
    incubator/qpid/trunk/qpid/cpp/test/unit/qpid/posix/EventChannelThreadsTest.cpp   (with props)
Removed:
    incubator/qpid/trunk/qpid/cpp/src/qpid/posix/EpollEventChannel.cpp
    incubator/qpid/trunk/qpid/cpp/src/qpid/posix/EpollEventChannel.h
    incubator/qpid/trunk/qpid/cpp/src/qpid/sys/EventChannel.h
Modified:
    incubator/qpid/trunk/qpid/cpp/   (props changed)
    incubator/qpid/trunk/qpid/cpp/Makefile
    incubator/qpid/trunk/qpid/cpp/src/qpid/Exception.cpp
    incubator/qpid/trunk/qpid/cpp/src/qpid/Exception.h
    incubator/qpid/trunk/qpid/cpp/src/qpid/QpidError.cpp
    incubator/qpid/trunk/qpid/cpp/src/qpid/QpidError.h
    incubator/qpid/trunk/qpid/cpp/src/qpid/apr/APRBase.cpp
    incubator/qpid/trunk/qpid/cpp/src/qpid/apr/LFProcessor.cpp
    incubator/qpid/trunk/qpid/cpp/src/qpid/apr/Socket.cpp
    incubator/qpid/trunk/qpid/cpp/src/qpid/broker/AutoDelete.cpp
    incubator/qpid/trunk/qpid/cpp/src/qpid/broker/AutoDelete.h
    incubator/qpid/trunk/qpid/cpp/src/qpid/broker/Configuration.cpp
    incubator/qpid/trunk/qpid/cpp/src/qpid/broker/FanOutExchange.cpp
    incubator/qpid/trunk/qpid/cpp/src/qpid/broker/Queue.cpp
    incubator/qpid/trunk/qpid/cpp/src/qpid/broker/TopicExchange.cpp
    incubator/qpid/trunk/qpid/cpp/src/qpid/client/Connection.cpp
    incubator/qpid/trunk/qpid/cpp/src/qpid/client/Connector.cpp
    incubator/qpid/trunk/qpid/cpp/src/qpid/posix/Socket.cpp
    incubator/qpid/trunk/qpid/cpp/src/qpid/posix/check.cpp
    incubator/qpid/trunk/qpid/cpp/src/qpid/posix/check.h
    incubator/qpid/trunk/qpid/cpp/src/qpid/sys/Monitor.h
    incubator/qpid/trunk/qpid/cpp/src/qpid/sys/Runnable.h
    incubator/qpid/trunk/qpid/cpp/src/qpid/sys/Socket.h
    incubator/qpid/trunk/qpid/cpp/src/qpid/sys/Thread.h
    incubator/qpid/trunk/qpid/cpp/src/qpid/sys/Time.cpp
    incubator/qpid/trunk/qpid/cpp/src/qpid/sys/Time.h
    incubator/qpid/trunk/qpid/cpp/test/client/client_test.cpp
    incubator/qpid/trunk/qpid/cpp/test/client/echo_service.cpp
    incubator/qpid/trunk/qpid/cpp/test/client/topic_listener.cpp
    incubator/qpid/trunk/qpid/cpp/test/client/topic_publisher.cpp

Propchange: incubator/qpid/trunk/qpid/cpp/
------------------------------------------------------------------------------
--- svn:ignore (original)
+++ svn:ignore Wed Nov 29 06:36:08 2006
@@ -1,3 +1,6 @@
 qpidd.log
 gen
 build
+apr-debug
+posix-debug
+options-local.mk

Modified: incubator/qpid/trunk/qpid/cpp/Makefile
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/Makefile?view=diff&rev=480582&r1=480581&r2=480582
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/Makefile (original)
+++ incubator/qpid/trunk/qpid/cpp/Makefile Wed Nov 29 06:36:08 2006
@@ -72,6 +72,7 @@
 
 ## Library rules
 
+## DONT COMMIT
 LIB_common  := $(call LIBFILE,common,1.0)
 DIRS_common := qpid qpid/framing qpid/sys qpid/$(PLATFORM)
 $(LIB_common): $(call OBJECTS, $(DIRS_common))
@@ -79,13 +80,13 @@
 
 LIB_client  := $(call LIBFILE,client,1.0)
 DIRS_client := qpid/client
-$(LIB_client): $(call OBJECTS,$(DIRS_client)) $(LIB_common)
-	$(LIB_COMMAND)
+$(LIB_client): $(call OBJECTS,$(DIRS_client)) 
+	$(LIB_COMMAND) $(LIB_common)
 
 LIB_broker  := $(call LIBFILE,broker,1.0)
 DIRS_broker := qpid/broker
-$(LIB_broker): $(call OBJECTS,$(DIRS_broker)) $(LIB_common)
-	$(LIB_COMMAND)
+$(LIB_broker): $(call OBJECTS,$(DIRS_broker)) 
+	$(LIB_COMMAND) $(LIB_common)
 
 ## Daemon executable
 $(BINDIR)/qpidd: $(OBJDIR)/qpidd.o $(LIB_common) $(LIB_broker)
@@ -94,12 +95,20 @@
 all-nogen: $(BINDIR)/qpidd
 
 ## Unit tests.
-UNITTEST_SRC:=$(shell find test/unit -name *Test.cpp)
-UNITTEST_SRC:=$(filter-out test/unit/qpid/$(IGNORE)/%,$(UNITTEST_SRC))
-UNITTESTS:=$(UNITTEST_SRC:test/unit/%.cpp=$(TESTDIR)/%.so)
+define UNITTEST_GROUP
+UNITTEST_SRC_$1 := $(wildcard $(DIRS_$1:%=test/unit/%/*Test.cpp))
+UNITTEST_SO_$1 := $$(UNITTEST_SRC_$1:test/unit/%.cpp=$(TESTDIR)/%.so)
+$$(UNITTEST_SO_$1): $(LIB_$1)
+UNITTESTS := $$(UNITTESTS) $$(UNITTEST_SO_$1)
+endef
 
-unittest: all 
+$(eval $(call UNITTEST_GROUP,common))
+$(eval $(call UNITTEST_GROUP,broker))
+$(eval $(call UNITTEST_GROUP,client))
+
+unittest: $(UNITTESTS)
 	DllPlugInTester -c -b $(UNITTESTS:.cpp=.so)
+
 all-nogen: $(UNITTESTS)
 
 ## Run python tests
@@ -143,7 +152,7 @@
 client: $(CLIENT_TEST_EXE)
 
 ## include dependencies
-DEPFILES:=$(wildcard $(OBJDIR)/*.d $(OBJDIR)/*/*.d $(OBJDIR)/*/*/*.d)
+DEPFILES:=$(shell find $(OBJDIR) $(TESTDIR) -name "*.d")
 ifdef DEPFILES
 -include $(DEPFILES)
 endif

Modified: incubator/qpid/trunk/qpid/cpp/src/qpid/Exception.cpp
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/src/qpid/Exception.cpp?view=diff&rev=480582&r1=480581&r2=480582
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/src/qpid/Exception.cpp (original)
+++ incubator/qpid/trunk/qpid/cpp/src/qpid/Exception.cpp Wed Nov 29 06:36:08 2006
@@ -21,4 +21,22 @@
 
 #include <qpid/Exception.h>
 
-qpid::Exception::~Exception() throw() {}
+namespace qpid {
+
+Exception::Exception() throw() {}
+
+Exception::Exception(const std::string& str) throw() : whatStr(str) {}
+
+Exception::Exception(const char* str) throw() : whatStr(str) {}
+
+Exception::~Exception() throw() {}
+
+const char* Exception::what() const throw() { return whatStr.c_str(); }
+
+std::string Exception::toString() const throw() { return whatStr; }
+
+Exception* Exception::clone() const throw() { return new Exception(*this); }
+
+void Exception::throwSelf() const  { throw *this; }
+
+} // namespace qpid

Modified: incubator/qpid/trunk/qpid/cpp/src/qpid/Exception.h
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/src/qpid/Exception.h?view=diff&rev=480582&r1=480581&r2=480582
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/src/qpid/Exception.h (original)
+++ incubator/qpid/trunk/qpid/cpp/src/qpid/Exception.h Wed Nov 29 06:36:08 2006
@@ -25,6 +25,7 @@
 #include <exception>
 #include <string>
 #include <memory>
+#include <boost/shared_ptr.hpp>
 
 namespace qpid
 {
@@ -37,42 +38,24 @@
     std::string whatStr;
 
   public:
-    Exception() throw() {}
-    Exception(const std::string& str) throw() : whatStr(str) {}
-    Exception(const char* str) throw() : whatStr(str) {}
+    Exception() throw();
+    Exception(const std::string& str) throw();
+    Exception(const char* str) throw();
+    Exception(const std::exception&) throw();
+
     virtual ~Exception() throw();
 
-    virtual const char* what() const throw() { return whatStr.c_str(); }
-    virtual std::string toString() const throw() { return whatStr; }
-};
+    virtual const char* what() const throw();
+    virtual std::string toString() const throw();
 
-/**
- * Wrapper for heap-allocated exceptions. Use like this:
- * <code>
- * std::auto_ptr<Exception> ex = new SomeEx(...)
- * HeapException hex(ex);       // Takes ownership
- * throw hex;                   // Auto-deletes ex
- * </code>
- */
-class HeapException : public Exception, public std::auto_ptr<Exception>
-{
-  public:
-    HeapException() {}
-    HeapException(std::auto_ptr<Exception> e) : std::auto_ptr<Exception>(e) {}
+    virtual Exception* clone() const throw();
+    virtual void throwSelf() const;
 
-    HeapException& operator=(std::auto_ptr<Exception>& e) {
-        std::auto_ptr<Exception>::operator=(e);
-        return *this;
-    }
-
-    ~HeapException() throw() {}
-    
-    virtual const char* what() const throw() { return (*this)->what(); }
-    virtual std::string toString() const throw() {
-        return (*this)->toString();
-    }
+    typedef boost::shared_ptr<Exception> shared_ptr;
 };
-    
+
+
+
 }
 
 #endif  /*!_Exception_*/

Added: incubator/qpid/trunk/qpid/cpp/src/qpid/ExceptionHolder.cpp
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/src/qpid/ExceptionHolder.cpp?view=auto&rev=480582
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/src/qpid/ExceptionHolder.cpp (added)
+++ incubator/qpid/trunk/qpid/cpp/src/qpid/ExceptionHolder.cpp Wed Nov 29 06:36:08 2006
@@ -0,0 +1,32 @@
+/*
+ *
+ * Copyright (c) 2006 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "ExceptionHolder.h"
+
+namespace qpid {
+
+ExceptionHolder::ExceptionHolder(const std::exception& e) {
+    const Exception* ex = dynamic_cast<const Exception*>(&e);
+    if (ex) {
+        reset(ex->clone());
+    } else {
+        reset(new Exception(e.what()));
+    }
+}
+
+}

Propchange: incubator/qpid/trunk/qpid/cpp/src/qpid/ExceptionHolder.cpp
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/qpid/trunk/qpid/cpp/src/qpid/ExceptionHolder.cpp
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: incubator/qpid/trunk/qpid/cpp/src/qpid/ExceptionHolder.h
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/src/qpid/ExceptionHolder.h?view=auto&rev=480582
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/src/qpid/ExceptionHolder.h (added)
+++ incubator/qpid/trunk/qpid/cpp/src/qpid/ExceptionHolder.h Wed Nov 29 06:36:08 2006
@@ -0,0 +1,60 @@
+#ifndef _qpid_ExceptionHolder_h
+#define _qpid_ExceptionHolder_h
+
+/*
+ *
+ * Copyright (c) 2006 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <qpid/Exception.h>
+#include <boost/shared_ptr.hpp>
+
+namespace qpid {
+
+/**
+ * Holder for a heap-allocated exc eption that can be stack allocated
+ * and thrown safely.
+ *
+ * Basically this is a shared_ptr with the Exception functions added
+ * so the catcher need not be aware that it is a pointer rather than a
+ * reference.
+ * 
+ * shared_ptr is chosen over auto_ptr because it has normal 
+ * copy semantics. 
+ */
+class ExceptionHolder : public Exception, public boost::shared_ptr<Exception>
+{
+  public:
+    typedef boost::shared_ptr<Exception> shared_ptr;
+
+    ExceptionHolder() throw() {}
+    ExceptionHolder(Exception* p) throw() : shared_ptr(p) {}
+    ExceptionHolder(shared_ptr p) throw() : shared_ptr(p) {}
+
+    ExceptionHolder(const Exception& e) throw() : shared_ptr(e.clone()) {}
+    ExceptionHolder(const std::exception& e);
+
+    const char* what() const throw() { return (*this)->what(); }
+    std::string toString() const throw() { return (*this)->toString(); }
+    virtual Exception* clone() const throw() { return (*this)->clone(); }
+    virtual void throwSelf() const { (*this)->throwSelf(); }
+};
+
+} // namespace qpid
+
+
+
+#endif  /*!_qpid_ExceptionHolder_h*/

Propchange: incubator/qpid/trunk/qpid/cpp/src/qpid/ExceptionHolder.h
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/qpid/trunk/qpid/cpp/src/qpid/ExceptionHolder.h
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Modified: incubator/qpid/trunk/qpid/cpp/src/qpid/QpidError.cpp
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/src/qpid/QpidError.cpp?view=diff&rev=480582&r1=480581&r2=480582
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/src/qpid/QpidError.cpp (original)
+++ incubator/qpid/trunk/qpid/cpp/src/qpid/QpidError.cpp Wed Nov 29 06:36:08 2006
@@ -24,12 +24,21 @@
 
 using namespace qpid;
 
-QpidError::QpidError(int _code, const std::string& _msg, const std::string& _file, int _line) throw()
-    : code(_code), msg(_msg), file(_file), line(_line) 
+QpidError::QpidError() : code(0) {}
+
+QpidError::QpidError(int _code, const std::string& _msg,
+                     const SrcLine& _loc) throw()
+    : code(_code), msg(_msg), location(_loc)
 {
     std::ostringstream os;
-    os << "QpidError(" << code << ") " << msg << " (" << file << ":" << line << ")";
+    os << "Error [" << code << "] " << msg << " ("
+       << location.file << ":" << location.line << ")";
     whatStr = os.str();
 }
 
 QpidError::~QpidError() throw() {}
+
+Exception* QpidError::clone() const throw() { return new QpidError(*this); }
+
+void QpidError::throwSelf() const  { throw *this; }
+

Modified: incubator/qpid/trunk/qpid/cpp/src/qpid/QpidError.h
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/src/qpid/QpidError.h?view=diff&rev=480582&r1=480581&r2=480582
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/src/qpid/QpidError.h (original)
+++ incubator/qpid/trunk/qpid/cpp/src/qpid/QpidError.h Wed Nov 29 06:36:08 2006
@@ -21,29 +21,47 @@
  *
  */
 #include <string>
+#include <memory>
+#include <ostream>
 #include <qpid/Exception.h>
 
 namespace qpid {
 
-    class QpidError : public Exception { 
-      public:
-        const int code;
-        const std::string msg;
-        const std::string file;
-        const int line;
-
-        QpidError(int _code, const std::string& _msg, const std::string& _file, int _line) throw();
-        ~QpidError() throw();
-    };
-
-#define THROW_QPID_ERROR(A, B) throw QpidError(A, B, __FILE__, __LINE__)
-
-}
-
-#define PROTOCOL_ERROR 10000
-#define APR_ERROR 20000
-#define FRAMING_ERROR 30000
-#define CLIENT_ERROR 40000
-#define INTERNAL_ERROR 50000
+struct SrcLine {
+  public:
+    SrcLine(const std::string& file_="", int line_=0) :
+        file(file_), line(line_) {}
+
+    std::string file;
+    int line;
+};
+    
+class QpidError : public Exception { 
+  public:
+    const int code;
+    const std::string msg;
+    const SrcLine location;
+
+    QpidError();
+    QpidError(int _code, const std::string& _msg, const SrcLine& _loc) throw();
+    ~QpidError() throw();
+    Exception* clone() const throw();
+    void throwSelf() const;
+};
+
+
+} // namespace qpid
+
+#define SRCLINE ::qpid::SrcLine(__FILE__, __LINE__)
+
+#define QPID_ERROR(CODE, MESSAGE) ::qpid::QpidError((CODE), (MESSAGE), SRCLINE)
+
+#define THROW_QPID_ERROR(CODE, MESSAGE) throw QPID_ERROR(CODE,MESSAGE)
+
+const int PROTOCOL_ERROR = 10000;
+const int APR_ERROR = 20000;
+const int FRAMING_ERROR = 30000;
+const int CLIENT_ERROR = 40000;
+const int INTERNAL_ERROR = 50000;
 
 #endif

Modified: incubator/qpid/trunk/qpid/cpp/src/qpid/apr/APRBase.cpp
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/src/qpid/apr/APRBase.cpp?view=diff&rev=480582&r1=480581&r2=480582
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/src/qpid/apr/APRBase.cpp (original)
+++ incubator/qpid/trunk/qpid/cpp/src/qpid/apr/APRBase.cpp Wed Nov 29 06:36:08 2006
@@ -87,7 +87,8 @@
         const int size = 50;
         char tmp[size];
         std::string msg(apr_strerror(status, tmp, size));
-        throw QpidError(APR_ERROR + ((int) status), msg, file, line);
+        throw QpidError(APR_ERROR + ((int) status), msg,
+                        qpid::SrcLine(file, line));
     }
 }
 

Modified: incubator/qpid/trunk/qpid/cpp/src/qpid/apr/LFProcessor.cpp
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/src/qpid/apr/LFProcessor.cpp?view=diff&rev=480582&r1=480581&r2=480582
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/src/qpid/apr/LFProcessor.cpp (original)
+++ incubator/qpid/trunk/qpid/cpp/src/qpid/apr/LFProcessor.cpp Wed Nov 29 06:36:08 2006
@@ -134,8 +134,8 @@
                 session->stopProcessing();
             }
         }
-    }catch(QpidError error){
-	std::cout << "Error [" << error.code << "] " << error.msg << " (" << error.file << ":" << error.line << ")" << std::endl;
+    }catch(std::exception e){
+	std::cout << e.what() << std::endl;
     }
 }
 

Modified: incubator/qpid/trunk/qpid/cpp/src/qpid/apr/Socket.cpp
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/src/qpid/apr/Socket.cpp?view=diff&rev=480582&r1=480581&r2=480582
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/src/qpid/apr/Socket.cpp (original)
+++ incubator/qpid/trunk/qpid/cpp/src/qpid/apr/Socket.cpp Wed Nov 29 06:36:08 2006
@@ -27,21 +27,24 @@
 
 using namespace qpid::sys;
 
-Socket::Socket()
-{
+Socket Socket::createTcp() {
+    Socket s;
     CHECK_APR_SUCCESS(
         apr_socket_create(
-            &socket, APR_INET, SOCK_STREAM, APR_PROTO_TCP,
+            &s.socket, APR_INET, SOCK_STREAM, APR_PROTO_TCP,
             APRPool::get()));
+    return s;
 }
 
-void Socket::setTimeout(long msecs)
-{
-    apr_socket_timeout_set(socket, msecs*1000);
+Socket::Socket(apr_socket_t* s) {
+    socket = s;
 }
 
-void Socket::connect(const std::string& host, int port)
-{
+void Socket::setTimeout(Time interval) {
+    apr_socket_timeout_set(socket, interval/TIME_USEC);
+}
+
+void Socket::connect(const std::string& host, int port) {
     apr_sockaddr_t* address;
     CHECK_APR_SUCCESS(
         apr_sockaddr_info_get(
@@ -50,27 +53,28 @@
     CHECK_APR_SUCCESS(apr_socket_connect(socket, address));
 }
 
-void Socket::close()
-{
+void Socket::close() {
     if (socket == 0) return;
     CHECK_APR_SUCCESS(apr_socket_close(socket));
     socket = 0;
 }
 
-ssize_t Socket::send(const char* data, size_t size)
+ssize_t Socket::send(const void* data, size_t size)
 {
     apr_size_t sent = size;
-    apr_status_t status = apr_socket_send(socket, data, &sent);
+    apr_status_t status =
+        apr_socket_send(socket, reinterpret_cast<const char*>(data), &sent);
     if (APR_STATUS_IS_TIMEUP(status)) return SOCKET_TIMEOUT;
     if (APR_STATUS_IS_EOF(status)) return SOCKET_EOF;
     CHECK_APR_SUCCESS(status);
     return sent;
 }
 
-ssize_t Socket::recv(char* data, size_t size)
+ssize_t Socket::recv(void* data, size_t size)
 {
     apr_size_t received = size;
-    apr_status_t status = apr_socket_recv(socket, data, &received);
+    apr_status_t status =
+        apr_socket_recv(socket, reinterpret_cast<char*>(data), &received);
     if (APR_STATUS_IS_TIMEUP(status)) return SOCKET_TIMEOUT;
     CHECK_APR_SUCCESS(status);
      return received;

Modified: incubator/qpid/trunk/qpid/cpp/src/qpid/broker/AutoDelete.cpp
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/src/qpid/broker/AutoDelete.cpp?view=diff&rev=480582&r1=480581&r2=480582
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/src/qpid/broker/AutoDelete.cpp (original)
+++ incubator/qpid/trunk/qpid/cpp/src/qpid/broker/AutoDelete.cpp Wed Nov 29 06:36:08 2006
@@ -63,7 +63,7 @@
     Monitor::ScopedLock l(monitor);
     while(!stopped){
         process();
-        monitor.wait(period * Time::NSEC_PER_MSEC);
+        monitor.wait(period*TIME_MSEC);
     }
 }
 

Modified: incubator/qpid/trunk/qpid/cpp/src/qpid/broker/AutoDelete.h
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/src/qpid/broker/AutoDelete.h?view=diff&rev=480582&r1=480581&r2=480582
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/src/qpid/broker/AutoDelete.h (original)
+++ incubator/qpid/trunk/qpid/cpp/src/qpid/broker/AutoDelete.h Wed Nov 29 06:36:08 2006
@@ -1,3 +1,5 @@
+#ifndef _AutoDelete_
+#define _AutoDelete_
 /*
  *
  * Licensed to the Apache Software Foundation (ASF) under one
@@ -18,9 +20,6 @@
  * under the License.
  *
  */
-#ifndef _AutoDelete_
-#define _AutoDelete_
-
 #include <iostream>
 #include <queue>
 #include <qpid/sys/Monitor.h>

Modified: incubator/qpid/trunk/qpid/cpp/src/qpid/broker/Configuration.cpp
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/src/qpid/broker/Configuration.cpp?view=diff&rev=480582&r1=480581&r2=480582
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/src/qpid/broker/Configuration.cpp (original)
+++ incubator/qpid/trunk/qpid/cpp/src/qpid/broker/Configuration.cpp Wed Nov 29 06:36:08 2006
@@ -52,7 +52,7 @@
             matched = (*i)->parse(position, argv, argc);
         }
         if(!matched){
-            std::cout << "Warning: skipping unrecognised option " << argv[position] << std::endl;
+            std::cout<< "Warning: skipping unrecognised option " << argv[position] << std::endl;
             position++;
         }
     }

Modified: incubator/qpid/trunk/qpid/cpp/src/qpid/broker/FanOutExchange.cpp
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/src/qpid/broker/FanOutExchange.cpp?view=diff&rev=480582&r1=480581&r2=480582
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/src/qpid/broker/FanOutExchange.cpp (original)
+++ incubator/qpid/trunk/qpid/cpp/src/qpid/broker/FanOutExchange.cpp Wed Nov 29 06:36:08 2006
@@ -43,7 +43,8 @@
     Queue::vector::iterator i = std::find(bindings.begin(), bindings.end(), queue);
     if (i != bindings.end()) {
         bindings.erase(i);
-        // TODO aconway 2006-09-14: What about the ExchangeBinding object? Don't we have to verify routingKey/args match?
+        // TODO aconway 2006-09-14: What about the ExchangeBinding object?
+        // Don't we have to verify routingKey/args match?
     }
 }
 

Modified: incubator/qpid/trunk/qpid/cpp/src/qpid/broker/Queue.cpp
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/src/qpid/broker/Queue.cpp?view=diff&rev=480582&r1=480581&r2=480582
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/src/qpid/broker/Queue.cpp (original)
+++ incubator/qpid/trunk/qpid/cpp/src/qpid/broker/Queue.cpp Wed Nov 29 06:36:08 2006
@@ -42,7 +42,7 @@
     exclusive(0),
     persistenceId(0)
 {
-    if(autodelete) lastUsed = Time::now().msecs();
+    if(autodelete) lastUsed = now()/TIME_MSEC;
 }
 
 Queue::~Queue(){
@@ -137,7 +137,7 @@
 void Queue::cancel(Consumer* c){
     Mutex::ScopedLock locker(lock);
     consumers.erase(find(consumers.begin(), consumers.end(), c));
-    if(autodelete && consumers.empty()) lastUsed = Time::now().msecs();
+    if(autodelete && consumers.empty()) lastUsed = now()*TIME_MSEC;
     if(exclusive == c) exclusive = 0;
 }
 
@@ -170,7 +170,7 @@
 
 bool Queue::canAutoDelete() const{
     Mutex::ScopedLock locker(lock);
-    return lastUsed && (Time::now().msecs() - lastUsed > autodelete);
+    return lastUsed && (now()*TIME_MSEC - lastUsed > autodelete);
 }
 
 void Queue::enqueue(TransactionContext* ctxt, Message::shared_ptr& msg, const string * const xid)

Modified: incubator/qpid/trunk/qpid/cpp/src/qpid/broker/TopicExchange.cpp
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/src/qpid/broker/TopicExchange.cpp?view=diff&rev=480582&r1=480581&r2=480582
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/src/qpid/broker/TopicExchange.cpp (original)
+++ incubator/qpid/trunk/qpid/cpp/src/qpid/broker/TopicExchange.cpp Wed Nov 29 06:36:08 2006
@@ -82,7 +82,8 @@
 
 namespace {
 // TODO aconway 2006-09-20: Ineficient to convert every routingKey to a string.
-// Need more efficient Tokens impl that can operate on a string in place.
+// Need StringRef class that operates on a string in place witout copy.
+// Should be applied everywhere strings are extracted from frames.
 // 
 bool do_match(Tokens::const_iterator pattern_begin,  Tokens::const_iterator pattern_end, Tokens::const_iterator target_begin,  Tokens::const_iterator target_end)
 {

Modified: incubator/qpid/trunk/qpid/cpp/src/qpid/client/Connection.cpp
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/src/qpid/client/Connection.cpp?view=diff&rev=480582&r1=480581&r2=480582
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/src/qpid/client/Connection.cpp (original)
+++ incubator/qpid/trunk/qpid/cpp/src/qpid/client/Connection.cpp Wed Nov 29 06:36:08 2006
@@ -216,7 +216,7 @@
 }
 
 void Connection::channelException(Channel* channel, AMQMethodBody* method, QpidError& e){
-    std::cout << "Caught error from channel [" << e.code << "] " << e.msg << " (" << e.file << ":" << e.line << ")" << std::endl;
+    std::cout << "Caught error from channel [" << e.code << "] " << e.msg << " (" << e.location.file << ":" << e.location.line << ")" << std::endl;
     int code = e.code == PROTOCOL_ERROR ? e.code - PROTOCOL_ERROR : 500;
     string msg = e.msg;
     if(method == 0){

Modified: incubator/qpid/trunk/qpid/cpp/src/qpid/client/Connector.cpp
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/src/qpid/client/Connector.cpp?view=diff&rev=480582&r1=480581&r2=480582
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/src/qpid/client/Connector.cpp (original)
+++ incubator/qpid/trunk/qpid/cpp/src/qpid/client/Connector.cpp Wed Nov 29 06:36:08 2006
@@ -44,6 +44,7 @@
 Connector::~Connector(){ }
 
 void Connector::connect(const std::string& host, int port){
+    socket = Socket::createTcp();
     socket.connect(host, port);
     closed = false;
     receiver = Thread(this);
@@ -92,7 +93,7 @@
     while(written < available && !closed){
 	ssize_t sent = socket.send(data + written, available-written);
         if(sent > 0) {
-            lastOut = Time::now().msecs();
+            lastOut = now() * TIME_MSEC;
             written += sent;
         }
     }
@@ -106,17 +107,17 @@
 
 void Connector::checkIdle(ssize_t status){
     if(timeoutHandler){
-        int64_t now = Time::now().msecs();
+         Time t = now() * TIME_MSEC;
         if(status == Socket::SOCKET_TIMEOUT) {
-            if(idleIn && (now - lastIn > idleIn)){
+            if(idleIn && (t - lastIn > idleIn)){
                 timeoutHandler->idleIn();
             }
         }else if(status == Socket::SOCKET_EOF){
             handleClosed();
         }else{
-            lastIn = now;
+            lastIn = t;
         }
-        if(idleOut && (now - lastOut > idleOut)){
+        if(idleOut && (t - lastOut > idleOut)){
             timeoutHandler->idleOut();
         }
     }
@@ -140,7 +141,7 @@
 }
 
 void Connector::setSocketTimeout(){
-    socket.setTimeout(timeout);
+    socket.setTimeout(timeout*TIME_MSEC);
 }
 
 void Connector::setTimeoutHandler(TimeoutHandler* handler){
@@ -171,7 +172,9 @@
 	    }
 	}
     }catch(QpidError error){
-	std::cout << "Error [" << error.code << "] " << error.msg << " (" << error.file << ":" << error.line << ")" << std::endl;
+	std::cout << "Error [" << error.code << "] " << error.msg
+                  << " (" << error.location.file << ":" << error.location.line
+                  << ")" << std::endl;
         handleClosed();
     }
 }

Added: incubator/qpid/trunk/qpid/cpp/src/qpid/posix/EventChannel.cpp
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/src/qpid/posix/EventChannel.cpp?view=auto&rev=480582
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/src/qpid/posix/EventChannel.cpp (added)
+++ incubator/qpid/trunk/qpid/cpp/src/qpid/posix/EventChannel.cpp Wed Nov 29 06:36:08 2006
@@ -0,0 +1,325 @@
+/*
+ *
+ * Copyright (c) 2006 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <mqueue.h>
+#include <string.h>
+#include <iostream>
+
+#include <sys/errno.h>
+#include <sys/socket.h>
+#include <sys/epoll.h>
+
+#include <typeinfo>
+#include <iostream>
+#include <queue>
+
+#include <boost/ptr_container/ptr_map.hpp>
+#include <boost/current_function.hpp>
+
+#include <qpid/QpidError.h>
+#include <qpid/sys/Monitor.h>
+
+#include "check.h"
+#include "EventChannel.h"
+
+using namespace std;
+
+
+// Convenience template to zero out a struct.
+template <class S> struct ZeroStruct : public S {
+    ZeroStruct() { memset(this, 0, sizeof(*this)); }
+};
+    
+namespace qpid {
+namespace sys {
+
+
+/**
+ * EventHandler wraps an epoll file descriptor. Acts as private
+ * interface between EventChannel and subclasses.
+ *
+ * Also implements Event interface for events that are not associated
+ * with a file descriptor and are passed via the message queue.
+ */ 
+class EventHandler : public Event, private Monitor
+{
+  public:
+    EventHandler(int epollSize = 256);
+    ~EventHandler();
+
+    int getEpollFd() { return epollFd; }
+    void epollAdd(int fd, uint32_t epollEvents, Event* event);
+    void epollMod(int fd, uint32_t epollEvents, Event* event);
+    void epollDel(int fd);
+
+    void mqPut(Event* event);
+    Event* mqGet();
+    
+  protected:
+    // Should never be called, only complete.
+    void prepare(EventHandler&) { assert(0); }
+    Event* complete(EventHandler& eh);
+    
+  private:
+    int epollFd;
+    std::string mqName;
+    int mqFd;
+    std::queue<Event*> mqEvents;
+};
+
+EventHandler::EventHandler(int epollSize)
+{
+    epollFd = epoll_create(epollSize);
+    if (epollFd < 0) throw QPID_POSIX_ERROR(errno);
+
+    // Create a POSIX message queue for non-fd events.
+    // We write one byte and never read it is always ready for read
+    // when we add it to epoll.
+    // 
+    ZeroStruct<struct mq_attr> attr;
+    attr.mq_maxmsg = 1;
+    attr.mq_msgsize = 1;
+    do {
+        char tmpnam[L_tmpnam];
+        tmpnam_r(tmpnam);
+        mqName = tmpnam + 4; // Skip "tmp/"
+        mqFd = mq_open(
+            mqName.c_str(), O_CREAT|O_EXCL|O_RDWR|O_NONBLOCK, S_IRWXU, &attr);
+        if (mqFd < 0) throw QPID_POSIX_ERROR(errno);
+    } while (mqFd == EEXIST);  // Name already taken, try again.
+
+    static char zero = '\0';
+    mq_send(mqFd, &zero, 1, 0);
+    epollAdd(mqFd, 0, this);
+}
+
+EventHandler::~EventHandler() {
+    mq_close(mqFd);
+    mq_unlink(mqName.c_str());
+}
+
+void EventHandler::mqPut(Event* event) {
+    ScopedLock l(*this);
+    assert(event != 0);
+    mqEvents.push(event);
+    epollMod(mqFd, EPOLLIN|EPOLLONESHOT, this);
+}
+
+Event* EventHandler::mqGet() {
+    ScopedLock l(*this);
+    if (mqEvents.empty()) 
+        return 0;
+    Event* event = mqEvents.front();
+    mqEvents.pop();
+    if(!mqEvents.empty())
+        epollMod(mqFd, EPOLLIN|EPOLLONESHOT, this);
+    return event;
+}
+
+void EventHandler::epollAdd(int fd, uint32_t epollEvents, Event* event)
+{
+    ZeroStruct<struct epoll_event> ee;
+    ee.data.ptr = event;
+    ee.events = epollEvents;
+    if (epoll_ctl(epollFd, EPOLL_CTL_ADD, fd, &ee) < 0) 
+        throw QPID_POSIX_ERROR(errno);
+}
+
+void EventHandler::epollMod(int fd, uint32_t epollEvents, Event* event)
+{
+    ZeroStruct<struct epoll_event> ee;
+    ee.data.ptr = event;
+    ee.events = epollEvents;
+    if (epoll_ctl(epollFd, EPOLL_CTL_MOD, fd, &ee) < 0) 
+        throw QPID_POSIX_ERROR(errno);
+}
+
+void EventHandler::epollDel(int fd) {
+    if (epoll_ctl(epollFd, EPOLL_CTL_DEL, fd, 0) < 0)
+        throw QPID_POSIX_ERROR(errno);
+}
+
+Event* EventHandler::complete(EventHandler& eh)
+{
+    assert(&eh == this);
+    Event* event =  mqGet();
+    return event==0 ? 0 : event->complete(eh);
+}
+    
+// ================================================================
+// EventChannel
+
+EventChannel::shared_ptr EventChannel::create() {
+    return shared_ptr(new EventChannel());
+}
+
+EventChannel::EventChannel() : handler(new EventHandler()) {}
+
+EventChannel::~EventChannel() {}
+
+void EventChannel::postEvent(Event& e) 
+{
+    e.prepare(*handler);
+}
+
+Event* EventChannel::getEvent()
+{
+    static const int infiniteTimeout = -1; 
+    ZeroStruct<struct epoll_event> epollEvent;
+
+    // Loop until we can complete the event. Some events may re-post
+    // themselves and return 0 from complete, e.g. partial reads. // 
+    Event* event = 0;
+    while (event == 0) {
+        int eventCount = epoll_wait(handler->getEpollFd(),
+                                    &epollEvent, 1, infiniteTimeout);
+        if (eventCount < 0) {
+            if (errno != EINTR) {
+                // TODO aconway 2006-11-28: Proper handling/logging of errors.
+                cerr << BOOST_CURRENT_FUNCTION << " ignoring error "
+                     << PosixError::getMessage(errno) << endl;
+                assert(0);
+            }
+        }
+        else if (eventCount == 1) {
+            event = reinterpret_cast<Event*>(epollEvent.data.ptr);
+            assert(event != 0);
+            try {
+                event = event->complete(*handler);
+            }
+            catch (const Exception& e) {
+                if (event)
+                    event->setError(e);
+            }
+            catch (const std::exception& e) {
+                if (event)
+                    event->setError(e);
+            }
+        }
+    }
+    return event;
+}
+
+Event::~Event() {}
+    
+void Event::prepare(EventHandler& handler)
+{
+    handler.mqPut(this);
+}
+
+bool Event::hasError() const {
+    return error;
+}
+
+void Event::throwIfError() throw (Exception) {
+    if (hasError())
+        error.throwSelf();
+}
+
+Event* Event::complete(EventHandler&)
+{
+    return this;
+}
+
+void Event::dispatch()
+{
+    try {
+        if (!callback.empty())
+            callback();
+    } catch (const std::exception&) {
+        throw;
+    } catch (...) {
+        throw QPID_ERROR(INTERNAL_ERROR, "Unknown exception.");
+    }
+}
+
+void Event::setError(const ExceptionHolder& e) {
+    error = e;
+}
+
+void ReadEvent::prepare(EventHandler& handler)
+{
+    handler.epollAdd(descriptor, EPOLLIN | EPOLLONESHOT, this);
+}
+
+ssize_t ReadEvent::doRead() {
+    ssize_t n = ::read(descriptor, static_cast<char*>(buffer) + received,
+                       size - received);
+    if (n > 0) received += n;
+    return n;
+}
+
+Event* ReadEvent::complete(EventHandler& handler)
+{
+    // Read as much as possible without blocking.
+    ssize_t n = doRead();
+    while (n > 0 && received < size) doRead();
+
+    if (received == size) {
+        handler.epollDel(descriptor);
+        received = 0;           // Reset for re-use.
+        return this;
+    }
+    else if (n <0 && (errno == EAGAIN)) {
+        // Keep polling for more.
+        handler.epollMod(descriptor, EPOLLIN | EPOLLONESHOT, this);
+        return 0;
+    }
+    else {
+        // Unexpected EOF or error. Throw ENODATA for EOF.
+        handler.epollDel(descriptor);
+        received = 0;           // Reset for re-use.
+        throw QPID_POSIX_ERROR((n < 0) ? errno : ENODATA);
+    }
+}
+
+void WriteEvent::prepare(EventHandler& handler)
+{
+    handler.epollAdd(descriptor, EPOLLOUT | EPOLLONESHOT, this);
+}
+
+Event* WriteEvent::complete(EventHandler& handler)
+{
+    ssize_t n = write(descriptor, static_cast<const char*>(buffer) + written,
+                      size - written);
+    if (n < 0) throw QPID_POSIX_ERROR(errno);
+    written += n;
+    if(written < size) {
+        // Keep polling.
+        handler.epollMod(descriptor, EPOLLOUT | EPOLLONESHOT, this);
+        return 0;
+    }
+    written = 0;                // Reset for re-use.
+    handler.epollDel(descriptor);
+    return this;
+}
+
+void AcceptEvent::prepare(EventHandler& handler)
+{
+    handler.epollAdd(descriptor, EPOLLIN | EPOLLONESHOT, this);
+}
+
+Event* AcceptEvent::complete(EventHandler& handler)
+{
+    handler.epollDel(descriptor);
+    accepted = ::accept(descriptor, 0, 0);
+    if (accepted < 0) throw QPID_POSIX_ERROR(errno);
+    return this;
+}
+
+}}

Propchange: incubator/qpid/trunk/qpid/cpp/src/qpid/posix/EventChannel.cpp
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/qpid/trunk/qpid/cpp/src/qpid/posix/EventChannel.cpp
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: incubator/qpid/trunk/qpid/cpp/src/qpid/posix/EventChannel.h
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/src/qpid/posix/EventChannel.h?view=auto&rev=480582
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/src/qpid/posix/EventChannel.h (added)
+++ incubator/qpid/trunk/qpid/cpp/src/qpid/posix/EventChannel.h Wed Nov 29 06:36:08 2006
@@ -0,0 +1,176 @@
+#ifndef _sys_EventChannel_h
+#define _sys_EventChannel_h
+
+/*
+ *
+ * Copyright (c) 2006 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <qpid/SharedObject.h>
+#include <qpid/ExceptionHolder.h>
+#include <boost/function.hpp>
+#include <memory>
+
+namespace qpid {
+namespace sys {
+
+class Event;
+class EventHandler;
+class EventChannel;
+
+/**
+ * Base class for all Events.
+ */
+class Event
+{
+  public:
+    /** Type for callback when event is dispatched */
+    typedef boost::function0<void> Callback;
+
+    /**
+     * Create an event with optional callback.
+     * Instances of Event are sent directly through the channel.
+     * Derived classes define additional waiting behaviour.
+     *@param cb A callback functor that is invoked when dispatch() is called.
+     */
+    Event(Callback cb = 0) : callback(cb) {}
+
+    virtual ~Event();
+
+    /** Call the callback provided to the constructor, if any. */
+    void dispatch();
+
+    /** True if there was an error processing this event */
+    bool hasError() const;
+
+    /** If hasError() throw the corresponding exception. */
+    void throwIfError() throw(Exception);
+
+  protected:
+    virtual void prepare(EventHandler&);
+    virtual Event* complete(EventHandler&);
+    void setError(const ExceptionHolder& e);
+
+    Callback callback;
+    ExceptionHolder error;
+
+  friend class EventChannel;
+  friend class EventHandler;
+};
+
+template <class BufT>
+class IOEvent : public Event {
+  public:
+    void getDescriptor() const { return descriptor; }
+    size_t getSize() const { return size; }
+    BufT getBuffer() const { return buffer; }
+  
+  protected:
+    IOEvent(int fd, Callback cb, size_t sz, BufT buf) :
+        Event(cb), descriptor(fd), buffer(buf), size(sz) {}
+
+    int descriptor;
+    BufT buffer;
+    size_t size;
+};
+
+/** Asynchronous read event */
+class ReadEvent : public IOEvent<void*>
+{
+  public:
+    explicit ReadEvent(int fd=-1, void* buf=0, size_t sz=0, Callback cb=0) :
+        IOEvent<void*>(fd, cb, sz, buf), received(0) {}
+
+  private:
+    void prepare(EventHandler&);
+    Event* complete(EventHandler&);
+    ssize_t doRead();
+
+    size_t received;
+};
+
+/** Asynchronous write event */
+class WriteEvent : public IOEvent<const void*>
+{
+  public:
+    explicit WriteEvent(int fd=-1, const void* buf=0, size_t sz=0,
+                        Callback cb=0) :
+        IOEvent<const void*>(fd, cb, sz, buf), written(0) {}
+
+  protected:
+    void prepare(EventHandler&);
+    Event* complete(EventHandler&);
+
+  private:
+    ssize_t doWrite();
+    size_t written;
+};
+
+/** Asynchronous socket accept event */
+class AcceptEvent : public Event
+{
+  public:
+    /** Accept a connection on fd. */
+    explicit AcceptEvent(int fd=-1, Callback cb=0) :
+        Event(cb), descriptor(fd), accepted(0) {}
+
+    /** Get descriptor for server socket */
+    int getAcceptedDesscriptor() const { return accepted; }
+
+  private:
+    void prepare(EventHandler&);
+    Event* complete(EventHandler&);
+
+    int descriptor;
+    int accepted;
+};
+
+
+class QueueSet;
+
+/**
+ * Channel to post and wait for events.
+ */
+class EventChannel : public qpid::SharedObject<EventChannel>
+{
+  public:
+    static shared_ptr create();
+    
+    ~EventChannel();
+    
+    /** Post an event to the channel. */
+    void postEvent(Event& event);
+
+    /** Post an event to the channel. Must not be 0. */
+    void postEvent(Event* event) { postEvent(*event); }
+        
+    /**
+     * Wait for the next complete event.
+     *@return Pointer to event. Will never return 0.
+     */
+    Event* getEvent();
+
+  private:
+    EventChannel();
+    boost::shared_ptr<EventHandler> handler;
+};
+
+
+}}
+
+
+
+#endif  /*!_sys_EventChannel_h*/

Propchange: incubator/qpid/trunk/qpid/cpp/src/qpid/posix/EventChannel.h
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/qpid/trunk/qpid/cpp/src/qpid/posix/EventChannel.h
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: incubator/qpid/trunk/qpid/cpp/src/qpid/posix/EventChannelThreads.cpp
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/src/qpid/posix/EventChannelThreads.cpp?view=auto&rev=480582
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/src/qpid/posix/EventChannelThreads.cpp (added)
+++ incubator/qpid/trunk/qpid/cpp/src/qpid/posix/EventChannelThreads.cpp Wed Nov 29 06:36:08 2006
@@ -0,0 +1,119 @@
+/*
+ *
+ * Copyright (c) 2006 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "EventChannelThreads.h"
+#include <qpid/sys/Runnable.h>
+#include <iostream>
+using namespace std;
+#include <boost/bind.hpp>
+
+namespace qpid {
+namespace sys {
+
+EventChannelThreads::shared_ptr EventChannelThreads::create(
+    EventChannel::shared_ptr ec)
+{
+    return EventChannelThreads::shared_ptr(new EventChannelThreads(ec));
+}
+
+EventChannelThreads::EventChannelThreads(EventChannel::shared_ptr ec) :
+    channel(ec), nWaiting(0), state(RUNNING)
+{
+    // TODO aconway 2006-11-15: Estimate initial threads based on CPUs.
+    addThread();
+}
+
+EventChannelThreads::~EventChannelThreads() {
+    shutdown();
+    join();
+}
+
+void EventChannelThreads::shutdown() 
+{
+    ScopedLock lock(*this);
+    if (state != RUNNING)       // Already shutting down.
+        return;
+    for (size_t i = 0; i < workers.size(); ++i) {
+        channel->postEvent(terminate);
+    }
+    state = TERMINATE_SENT;
+    notify();                // Wake up one join() thread.
+}
+
+void EventChannelThreads::join() 
+{
+    {
+        ScopedLock lock(*this);
+        while (state == RUNNING)    // Wait for shutdown to start.
+            wait();
+        if (state == SHUTDOWN)      // Shutdown is complete
+            return;
+        if (state == JOINING) {
+            // Someone else is doing the join.
+            while (state != SHUTDOWN)
+                wait();
+            return;
+        }
+        // I'm the  joining thread
+        assert(state == TERMINATE_SENT); 
+        state = JOINING; 
+    } // Drop the lock.
+
+    for (size_t i = 0; i < workers.size(); ++i) {
+        assert(state == JOINING); // Only this thread can change JOINING.
+        workers[i].join();
+    }
+    state = SHUTDOWN;
+    notifyAll();                // Notify other join() threaeds.
+}
+
+void EventChannelThreads::addThread() {
+    ScopedLock l(*this);
+    workers.push_back(Thread(*this));
+}
+
+void EventChannelThreads::run()
+{
+    // Start life waiting. Decrement on exit.
+    AtomicCount::ScopedIncrement inc(nWaiting);
+    try {
+        while (true) {
+            Event* e = channel->getEvent(); 
+            assert(e != 0);
+            if (e == &terminate) {
+                return;
+            }
+            AtomicCount::ScopedDecrement dec(nWaiting);
+            // I'm no longer waiting, make sure someone is.
+            if (dec == 0)
+                addThread();
+            e->dispatch();
+        }
+    }
+    catch (const std::exception& e) {
+        // TODO aconway 2006-11-15: need better logging across the board.
+        std::cerr << "EventChannelThreads::run() caught: " << e.what()
+                  << std::endl;
+    }
+    catch (...) {
+        std::cerr << "EventChannelThreads::run() caught unknown exception."
+                  << std::endl;
+    }
+}
+
+}}

Propchange: incubator/qpid/trunk/qpid/cpp/src/qpid/posix/EventChannelThreads.cpp
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/qpid/trunk/qpid/cpp/src/qpid/posix/EventChannelThreads.cpp
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: incubator/qpid/trunk/qpid/cpp/src/qpid/posix/EventChannelThreads.h
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/src/qpid/posix/EventChannelThreads.h?view=auto&rev=480582
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/src/qpid/posix/EventChannelThreads.h (added)
+++ incubator/qpid/trunk/qpid/cpp/src/qpid/posix/EventChannelThreads.h Wed Nov 29 06:36:08 2006
@@ -0,0 +1,92 @@
+#ifndef _posix_EventChannelThreads_h
+#define _sys_EventChannelThreads_h
+
+/*
+ *
+ * Copyright (c) 2006 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+#include <vector>
+
+#include <qpid/Exception.h>
+#include <qpid/sys/Time.h>
+#include <qpid/sys/Monitor.h>
+#include <qpid/sys/Thread.h>
+#include <qpid/sys/AtomicCount.h>
+#include "EventChannel.h"
+
+namespace qpid {
+namespace sys {
+
+/**
+   Dynamic thread pool serving an EventChannel.
+
+   Threads run a loop { e = getEvent(); e->dispatch(); }
+   The size of the thread pool is automatically adjusted to optimal size.
+*/
+class EventChannelThreads :
+        public qpid::SharedObject<EventChannelThreads>,
+        public sys::Monitor, private sys::Runnable
+{
+  public:
+    /** Create the thread pool and start initial threads. */
+    static EventChannelThreads::shared_ptr create(
+        EventChannel::shared_ptr channel
+    );
+
+    ~EventChannelThreads();
+
+    /** Post event to the underlying channel */
+    void postEvent(Event& event) { channel->postEvent(event); }
+
+    /** Post event to the underlying channel Must not be 0. */
+    void postEvent(Event* event) { channel->postEvent(event); }
+
+    /**
+     * Terminate all threads.
+     *
+     * Returns immediately, use join() to wait till all threads are
+     * shut down. 
+     */
+    void shutdown();
+    
+    /** Wait for all threads to terminate. */
+    void join();
+
+  private:
+    typedef std::vector<sys::Thread> Threads;
+    typedef enum {
+        RUNNING, TERMINATE_SENT, JOINING, SHUTDOWN
+    } State;
+
+    EventChannelThreads(EventChannel::shared_ptr underlyingChannel);
+    void addThread();
+
+    void run();
+    bool keepRunning();
+    void adjustThreads();
+
+    EventChannel::shared_ptr channel;
+    Threads workers;
+    sys::AtomicCount nWaiting;
+    State state;
+    Event terminate;
+};
+
+
+}}
+
+
+#endif  /*!_sys_EventChannelThreads_h*/

Propchange: incubator/qpid/trunk/qpid/cpp/src/qpid/posix/EventChannelThreads.h
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/qpid/trunk/qpid/cpp/src/qpid/posix/EventChannelThreads.h
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Modified: incubator/qpid/trunk/qpid/cpp/src/qpid/posix/Socket.cpp
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/src/qpid/posix/Socket.cpp?view=diff&rev=480582&r1=480581&r2=480582
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/src/qpid/posix/Socket.cpp (original)
+++ incubator/qpid/trunk/qpid/cpp/src/qpid/posix/Socket.cpp Wed Nov 29 06:36:08 2006
@@ -20,6 +20,7 @@
  */
 
 #include <sys/socket.h>
+#include <sys/errno.h>
 #include <netinet/in.h>
 #include <netdb.h>
 
@@ -31,60 +32,87 @@
 
 using namespace qpid::sys;
 
-Socket::Socket() : socket(::socket (PF_INET, SOCK_STREAM, 0))
+Socket Socket::createTcp() 
 {
-    CHECKNN(socket == 0);
+    int s = ::socket (PF_INET, SOCK_STREAM, 0);
+    if (s < 0) throw QPID_POSIX_ERROR(errno);
+    return s;
 }
 
-void
-Socket::setTimeout(long msecs)
+Socket::Socket(int descriptor) : socket(descriptor) {}
+
+void Socket::setTimeout(Time interval)
 {
     struct timeval tv;
-    tv.tv_sec = msecs / 1000;
-    tv.tv_usec = (msecs % 1000)*1000;
+    tv.tv_sec = interval/TIME_SEC;
+    tv.tv_usec = (interval%TIME_SEC)/TIME_USEC;
     setsockopt(socket, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv));
     setsockopt(socket, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
 }
 
-void
-Socket::connect(const std::string& host, int port)
+void Socket::connect(const std::string& host, int port)
 {
     struct sockaddr_in name;
     name.sin_family = AF_INET;
     name.sin_port = htons(port);
     struct hostent* hp = gethostbyname ( host.c_str() );
-    if (hp == 0) CHECK0(-1);     // TODO aconway 2006-11-09: error message?
+    if (hp == 0) throw QPID_POSIX_ERROR(errno);
     memcpy(&name.sin_addr.s_addr, hp->h_addr_list[0], hp->h_length);
-    CHECK0(::connect(socket, (struct sockaddr*)(&name), sizeof(name)));
+    if (::connect(socket, (struct sockaddr*)(&name), sizeof(name)) < 0)
+        throw QPID_POSIX_ERROR(errno);
 }
 
 void
 Socket::close()
 {
     if (socket == 0) return;
-    CHECK0(::close(socket));
+    if (::close(socket) < 0) throw QPID_POSIX_ERROR(errno);
     socket = 0;
 }
 
 ssize_t
-Socket::send(const char* data, size_t size)
+Socket::send(const void* data, size_t size)
 {
     ssize_t sent = ::send(socket, data, size, 0);
     if (sent < 0) {
         if (errno == ECONNRESET) return SOCKET_EOF;
         if (errno == ETIMEDOUT) return SOCKET_TIMEOUT;
-        CHECK0(sent);
+        throw QPID_POSIX_ERROR(errno);
     }
     return sent;
 }
 
 ssize_t
-Socket::recv(char* data, size_t size)
+Socket::recv(void* data, size_t size)
 {
     ssize_t received = ::recv(socket, data, size, 0);
     if (received < 0) {
         if (errno == ETIMEDOUT) return SOCKET_TIMEOUT;
-        CHECK0(received);
+        throw QPID_POSIX_ERROR(errno);
     }
     return received;
+}
+
+int Socket::listen(int port, int backlog) 
+{
+    struct sockaddr_in name;
+    name.sin_family = AF_INET;
+    name.sin_port = htons(port);
+    name.sin_addr.s_addr = 0;
+    if (::bind(socket, (struct sockaddr*)&name, sizeof(name)) < 0)
+        throw QPID_POSIX_ERROR(errno);
+    if (::listen(socket, backlog) < 0)
+        throw QPID_POSIX_ERROR(errno);
+    
+    socklen_t namelen = sizeof(name);
+    if (::getsockname(socket, (struct sockaddr*)&name, &namelen) < 0)
+        throw QPID_POSIX_ERROR(errno);
+
+    return ntohs(name.sin_port);
+}
+
+
+int Socket::fd() 
+{
+    return socket;
 }

Modified: incubator/qpid/trunk/qpid/cpp/src/qpid/posix/check.cpp
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/src/qpid/posix/check.cpp?view=diff&rev=480582&r1=480581&r2=480582
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/src/qpid/posix/check.cpp (original)
+++ incubator/qpid/trunk/qpid/cpp/src/qpid/posix/check.cpp Wed Nov 29 06:36:08 2006
@@ -19,15 +19,21 @@
  *
  */
 
-#include <qpid/QpidError.h>
+#include <cerrno>
 #include "check.h" 
 
 namespace qpid {
 namespace sys {
 
-std::string errnoToString() {
+std::string
+PosixError::getMessage(int errNo)
+{
     char buf[512];
-    return strerror_r(errno, buf, sizeof(buf));
+    return std::string(strerror_r(errNo, buf, sizeof(buf)));
 }
 
+PosixError::PosixError(int errNo, const qpid::SrcLine& loc) throw()
+    : qpid::QpidError(INTERNAL_ERROR + errNo, getMessage(errNo), loc)
+{ }
+    
 }}

Modified: incubator/qpid/trunk/qpid/cpp/src/qpid/posix/check.h
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/src/qpid/posix/check.h?view=diff&rev=480582&r1=480581&r2=480582
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/src/qpid/posix/check.h (original)
+++ incubator/qpid/trunk/qpid/cpp/src/qpid/posix/check.h Wed Nov 29 06:36:08 2006
@@ -22,18 +22,41 @@
  *
  */
 
-#include <errno.h>
+#include <cerrno>
 #include <string>
 #include <qpid/QpidError.h>
 
 namespace qpid {
 namespace sys {
 
-std::string errnoToString();
+/**
+ * Exception with message from errno.
+ */
+class PosixError : public qpid::QpidError
+{
+  public:
+    static std::string getMessage(int errNo);
+    
+    PosixError(int errNo, const qpid::SrcLine& location) throw();
+    
+    ~PosixError() throw() {}
+    
+    int getErrNo() { return errNo; }
+
+    Exception* clone() const throw() { return new PosixError(*this); }
+        
+    void throwSelf() { throw *this; }
+
+  private:
+    int errNo;
+};
 
-#define CHECK0(N) if ((N)!=0) THROW_QPID_ERROR(INTERNAL_ERROR, errnoToString())
-#define CHECKNN(N) if ((N)<0) THROW_QPID_ERROR(INTERNAL_ERROR, errnoToString())
 }}
 
+/** Create a PosixError for the current file/line and errno. */
+#define QPID_POSIX_ERROR(errNo) ::qpid::sys::PosixError(errNo, SRCLINE)
 
+/** Throw a posix error if errNo is non-zero */
+#define QPID_POSIX_THROW_IF(ERRNO)              \
+    if ((ERRNO) != 0) throw QPID_POSIX_ERROR((ERRNO))
 #endif  /*!_posix_check_h*/

Added: incubator/qpid/trunk/qpid/cpp/src/qpid/sys/AtomicCount.h
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/src/qpid/sys/AtomicCount.h?view=auto&rev=480582
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/src/qpid/sys/AtomicCount.h (added)
+++ incubator/qpid/trunk/qpid/cpp/src/qpid/sys/AtomicCount.h Wed Nov 29 06:36:08 2006
@@ -0,0 +1,71 @@
+#ifndef _posix_AtomicCount_h
+#define _posix_AtomicCount_h
+
+/*
+ *
+ * Copyright (c) 2006 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <boost/detail/atomic_count.hpp>
+#include <boost/noncopyable.hpp>
+
+namespace qpid {
+namespace sys {
+
+/**
+ * Atomic counter.
+ */
+class AtomicCount : boost::noncopyable {
+  public:
+    class ScopedDecrement : boost::noncopyable {
+      public:
+        /** Decrement counter in constructor and increment in destructor. */
+        ScopedDecrement(AtomicCount& c) : count(c) { value = --count; }
+        ~ScopedDecrement() { ++count; }
+        /** Return the value returned by the decrement. */
+        operator long() { return value; }
+      private:
+        AtomicCount& count;
+        long value;
+    };
+
+    class ScopedIncrement : boost::noncopyable {
+      public:
+        /** Increment counter in constructor and increment in destructor. */
+        ScopedIncrement(AtomicCount& c) : count(c) { ++count; }
+        ~ScopedIncrement() { --count; }
+      private:
+        AtomicCount& count;
+    };
+
+    AtomicCount(long value = 0) : count(value) {}
+    
+    void operator++() { ++count ; }
+    
+    long operator--() { return --count; }
+    
+    operator long() const { return count; }
+
+    
+  private:
+    boost::detail::atomic_count  count;
+};
+
+
+}}
+
+
+#endif // _posix_AtomicCount_h

Propchange: incubator/qpid/trunk/qpid/cpp/src/qpid/sys/AtomicCount.h
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/qpid/trunk/qpid/cpp/src/qpid/sys/AtomicCount.h
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Modified: incubator/qpid/trunk/qpid/cpp/src/qpid/sys/Monitor.h
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/src/qpid/sys/Monitor.h?view=diff&rev=480582&r1=480581&r2=480582
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/src/qpid/sys/Monitor.h (original)
+++ incubator/qpid/trunk/qpid/cpp/src/qpid/sys/Monitor.h Wed Nov 29 06:36:08 2006
@@ -22,60 +22,28 @@
  *
  */
 
+#include <sys/errno.h>
 #include <boost/noncopyable.hpp>
+#include <qpid/sys/Mutex.h>
+#include <qpid/sys/Time.h>
 
 #ifdef USE_APR
-#  include <apr_thread_mutex.h>
-#  include <apr_thread_cond.h>
-#  include <qpid/apr/APRBase.h>
-#  include <qpid/apr/APRPool.h>
-#else
-#  include <pthread.h>
-#  include <qpid/sys/Time.h>
-#  include <qpid/posix/check.h>
+#  include <apr-1/apr_thread_cond.h>
 #endif
 
 namespace qpid {
 namespace sys {
 
-template <class L>
-class ScopedLock
-{
-  public:
-    ScopedLock(L& l) : mutex(l) { l.lock(); }
-    ~ScopedLock() { mutex.unlock(); }
-  private:
-    L& mutex;
-};
-
-
-class Mutex : private boost::noncopyable
-{
-  public:
-    typedef ScopedLock<Mutex> ScopedLock;
-    
-    inline Mutex();
-    inline ~Mutex();
-    inline void lock();
-    inline void unlock();
-    inline void trylock();
-
-  protected:
-#ifdef USE_APR
-    apr_thread_mutex_t* mutex;
-#else
-    pthread_mutex_t mutex;
-#endif
-};
-
-/** A condition variable and a mutex */
+/**
+ * A monitor is a condition variable and a mutex
+ */
 class Monitor : public Mutex
 {
   public:
     inline Monitor();
     inline ~Monitor();
     inline void wait();
-    inline bool wait(int64_t nsecs);
+    inline bool wait(const Time& absoluteTime);
     inline void notify();
     inline void notifyAll();
 
@@ -91,25 +59,6 @@
 // APR ================================================================
 #ifdef USE_APR
 
-Mutex::Mutex() {
-    CHECK_APR_SUCCESS(apr_thread_mutex_create(&mutex, APR_THREAD_MUTEX_NESTED, APRPool::get()));
-}
-
-Mutex::~Mutex(){
-    CHECK_APR_SUCCESS(apr_thread_mutex_destroy(mutex));
-}
-
-void Mutex::lock() {
-    CHECK_APR_SUCCESS(apr_thread_mutex_lock(mutex));
-}
-void Mutex::unlock() {
-    CHECK_APR_SUCCESS(apr_thread_mutex_unlock(mutex));
-}
-
-void Mutex::trylock() {
-    CHECK_APR_SUCCESS(apr_thread_mutex_trylock(mutex));
-}
-
 Monitor::Monitor() {
     CHECK_APR_SUCCESS(apr_thread_cond_create(&condition, APRPool::get()));
 }
@@ -122,10 +71,10 @@
     CHECK_APR_SUCCESS(apr_thread_cond_wait(condition, mutex));
 }
 
-bool Monitor::wait(int64_t nsecs){
+bool Monitor::wait(const Time& absoluteTime){
     // APR uses microseconds.
-    apr_status_t status = apr_thread_cond_timedwait(
-        condition, mutex, nsecs/1000);
+    apr_status_t status =
+        apr_thread_cond_timedwait(condition, mutex, absoluteTime/TIME_USEC);
     if(status != APR_TIMEUP) CHECK_APR_SUCCESS(status);
     return status == 0;
 }
@@ -138,93 +87,41 @@
     CHECK_APR_SUCCESS(apr_thread_cond_broadcast(condition));
 }
 
-
-}}
-
-
-// POSIX ================================================================
 #else
-/**
- * PODMutex is a POD, can be static-initialized with
- * PODMutex m = QPID_PODMUTEX_INITIALIZER
- */
-struct PODMutex 
-{
-    typedef ScopedLock<PODMutex> ScopedLock;
-
-    inline void lock();
-    inline void unlock();
-    inline void trylock();
-
-    // Must be public to be a POD:
-    pthread_mutex_t mutex;
-};
-
-#define QPID_MUTEX_INITIALIZER { PTHREAD_MUTEX_INITIALIZER }
-
-
-void PODMutex::lock() {
-    CHECK0(pthread_mutex_lock(&mutex));
-}
-void PODMutex::unlock() {
-    CHECK0(pthread_mutex_unlock(&mutex));
-}
-
-void PODMutex::trylock() {
-    CHECK0(pthread_mutex_trylock(&mutex));
-}
-
-
-Mutex::Mutex() {
-    CHECK0(pthread_mutex_init(&mutex, 0));
-}
-
-Mutex::~Mutex(){
-    CHECK0(pthread_mutex_destroy(&mutex));
-}
-
-void Mutex::lock() {
-    CHECK0(pthread_mutex_lock(&mutex));
-}
-void Mutex::unlock() {
-    CHECK0(pthread_mutex_unlock(&mutex));
-}
-
-void Mutex::trylock() {
-    CHECK0(pthread_mutex_trylock(&mutex));
-}
+// POSIX ================================================================
 
 Monitor::Monitor() {
-    CHECK0(pthread_cond_init(&condition, 0));
+    QPID_POSIX_THROW_IF(pthread_cond_init(&condition, 0));
 }
 
 Monitor::~Monitor() {
-    CHECK0(pthread_cond_destroy(&condition));
+    QPID_POSIX_THROW_IF(pthread_cond_destroy(&condition));
 }
 
 void Monitor::wait() {
-    CHECK0(pthread_cond_wait(&condition, &mutex));
+    QPID_POSIX_THROW_IF(pthread_cond_wait(&condition, &mutex));
 }
 
-bool Monitor::wait(int64_t nsecs){
-    Time t(nsecs);
-    int status = pthread_cond_timedwait(&condition, &mutex, &t.getTimespec());
-    if(status != 0) {
-        if (errno == ETIMEDOUT) return false;
-        CHECK0(status);
+bool Monitor::wait(const Time& absoluteTime){
+    struct timespec ts;
+    toTimespec(ts, absoluteTime);
+    int status = pthread_cond_timedwait(&condition, &mutex, &ts);
+    if (status != 0) {
+        if (status == ETIMEDOUT) return false;
+        throw QPID_POSIX_ERROR(status);
     }
     return true;
 }
 
 void Monitor::notify(){
-    CHECK0(pthread_cond_signal(&condition));
+    QPID_POSIX_THROW_IF(pthread_cond_signal(&condition));
 }
 
 void Monitor::notifyAll(){
-    CHECK0(pthread_cond_broadcast(&condition));
+    QPID_POSIX_THROW_IF(pthread_cond_broadcast(&condition));
 }
+#endif  /*USE_APR*/
 
 
 }}
-#endif  /*USE_APR*/
 #endif  /*!_sys_Monitor_h*/

Added: incubator/qpid/trunk/qpid/cpp/src/qpid/sys/Mutex.h
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/src/qpid/sys/Mutex.h?view=auto&rev=480582
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/src/qpid/sys/Mutex.h (added)
+++ incubator/qpid/trunk/qpid/cpp/src/qpid/sys/Mutex.h Wed Nov 29 06:36:08 2006
@@ -0,0 +1,151 @@
+#ifndef _sys_Mutex_h
+#define _sys_Mutex_h
+
+/*
+ *
+ * Copyright (c) 2006 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifdef USE_APR
+#  include <apr-1/apr_thread_mutex.h>
+#  include <qpid/apr/APRBase.h>
+#  include <qpid/apr/APRPool.h>
+#else
+#  include <pthread.h>
+#  include <qpid/posix/check.h>
+#endif
+#include <boost/noncopyable.hpp>
+
+namespace qpid {
+namespace sys {
+
+/**
+ * Scoped lock template: calls lock() in ctor, unlock() in dtor.
+ * L can be any class with lock() and unlock() functions.
+ */
+template <class L>
+class ScopedLock
+{
+  public:
+    ScopedLock(L& l) : mutex(l) { l.lock(); }
+    ~ScopedLock() { mutex.unlock(); }
+  private:
+    L& mutex;
+};
+
+/**
+ * Mutex lock.
+ */
+class Mutex : private boost::noncopyable {
+  public:
+    typedef ScopedLock<Mutex> ScopedLock;
+    
+    inline Mutex();
+    inline ~Mutex();
+    inline void lock();
+    inline void unlock();
+    inline void trylock();
+
+  protected:
+#ifdef USE_APR
+    apr_thread_mutex_t* mutex;
+#else
+    pthread_mutex_t mutex;
+#endif
+};
+
+#ifdef USE_APR
+// APR ================================================================
+
+Mutex::Mutex() {
+    CHECK_APR_SUCCESS(apr_thread_mutex_create(&mutex, APR_THREAD_MUTEX_NESTED, APRPool::get()));
+}
+
+Mutex::~Mutex(){
+    CHECK_APR_SUCCESS(apr_thread_mutex_destroy(mutex));
+}
+
+void Mutex::lock() {
+    CHECK_APR_SUCCESS(apr_thread_mutex_lock(mutex));
+}
+void Mutex::unlock() {
+    CHECK_APR_SUCCESS(apr_thread_mutex_unlock(mutex));
+}
+
+void Mutex::trylock() {
+    CHECK_APR_SUCCESS(apr_thread_mutex_trylock(mutex));
+}
+
+#else
+// POSIX ================================================================
+
+/**
+ * PODMutex is a POD, can be static-initialized with
+ * PODMutex m = QPID_PODMUTEX_INITIALIZER
+ */
+struct PODMutex 
+{
+    typedef ScopedLock<PODMutex> ScopedLock;
+
+    inline void lock();
+    inline void unlock();
+    inline void trylock();
+
+    // Must be public to be a POD:
+    pthread_mutex_t mutex;
+};
+
+#define QPID_MUTEX_INITIALIZER { PTHREAD_MUTEX_INITIALIZER }
+
+
+void PODMutex::lock() {
+    QPID_POSIX_THROW_IF(pthread_mutex_lock(&mutex));
+}
+void PODMutex::unlock() {
+    QPID_POSIX_THROW_IF(pthread_mutex_unlock(&mutex));
+}
+
+void PODMutex::trylock() {
+    QPID_POSIX_THROW_IF(pthread_mutex_trylock(&mutex));
+}
+
+
+Mutex::Mutex() {
+    QPID_POSIX_THROW_IF(pthread_mutex_init(&mutex, 0));
+}
+
+Mutex::~Mutex(){
+    QPID_POSIX_THROW_IF(pthread_mutex_destroy(&mutex));
+}
+
+void Mutex::lock() {
+    QPID_POSIX_THROW_IF(pthread_mutex_lock(&mutex));
+}
+void Mutex::unlock() {
+    QPID_POSIX_THROW_IF(pthread_mutex_unlock(&mutex));
+}
+
+void Mutex::trylock() {
+    QPID_POSIX_THROW_IF(pthread_mutex_trylock(&mutex));
+}
+
+#endif // USE_APR
+
+}}
+
+
+
+#endif  /*!_sys_Mutex_h*/

Propchange: incubator/qpid/trunk/qpid/cpp/src/qpid/sys/Mutex.h
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/qpid/trunk/qpid/cpp/src/qpid/sys/Mutex.h
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: incubator/qpid/trunk/qpid/cpp/src/qpid/sys/Runnable.cpp
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/src/qpid/sys/Runnable.cpp?view=auto&rev=480582
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/src/qpid/sys/Runnable.cpp (added)
+++ incubator/qpid/trunk/qpid/cpp/src/qpid/sys/Runnable.cpp Wed Nov 29 06:36:08 2006
@@ -0,0 +1,32 @@
+/*
+ *
+ * Copyright (c) 2006 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "Runnable.h"
+#include <boost/bind.hpp>
+
+namespace qpid {
+namespace sys {
+
+Runnable::~Runnable() {}
+
+Runnable::Functor Runnable::functor() 
+{
+    return boost::bind(&Runnable::run, this);
+}
+
+}}

Propchange: incubator/qpid/trunk/qpid/cpp/src/qpid/sys/Runnable.cpp
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/qpid/trunk/qpid/cpp/src/qpid/sys/Runnable.cpp
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Modified: incubator/qpid/trunk/qpid/cpp/src/qpid/sys/Runnable.h
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/src/qpid/sys/Runnable.h?view=diff&rev=480582&r1=480581&r2=480582
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/src/qpid/sys/Runnable.h (original)
+++ incubator/qpid/trunk/qpid/cpp/src/qpid/sys/Runnable.h Wed Nov 29 06:36:08 2006
@@ -1,3 +1,5 @@
+#ifndef _Runnable_
+#define _Runnable_
 /*
  *
  * Licensed to the Apache Software Foundation (ASF) under one
@@ -18,18 +20,28 @@
  * under the License.
  *
  */
-#ifndef _Runnable_
-#define _Runnable_
+
+#include <boost/function.hpp>
 
 namespace qpid {
 namespace sys {
 
-/** Base class for classes that run in a thread. */
+/**
+ * Interface for objects that can be run, e.g. in a thread.
+ */
 class Runnable
 {
   public:
-    virtual ~Runnable() {}
+    /** Type to represent a runnable as a Functor */
+    typedef boost::function0<void> Functor;
+    
+    virtual ~Runnable();
+
+    /** Derived classes override run(). */
     virtual void run() = 0;
+
+    /** Create a functor object that will call this->run(). */
+    Functor functor();
 };
 
 }}

Modified: incubator/qpid/trunk/qpid/cpp/src/qpid/sys/Socket.h
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/src/qpid/sys/Socket.h?view=diff&rev=480582&r1=480581&r2=480582
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/src/qpid/sys/Socket.h (original)
+++ incubator/qpid/trunk/qpid/cpp/src/qpid/sys/Socket.h Wed Nov 29 06:36:08 2006
@@ -23,6 +23,7 @@
  */
 
 #include <string>
+#include <qpid/sys/Time.h>
 
 #ifdef USE_APR
 #  include <apr_network_io.h>
@@ -34,10 +35,18 @@
 class Socket
 {
   public:
-    Socket();
+    /** Create an initialized TCP socket */
+    static Socket createTcp();
 
+    /** Create a socket wrapper for descriptor. */
+#ifdef USE_APR
+    Socket(apr_socket_t* descriptor = 0);
+#else
+    Socket(int descriptor = 0);
+#endif
+    
     /** Set timeout for read and write */
-    void setTimeout(long msecs);
+    void setTimeout(Time interval);
 
     void connect(const std::string& host, int port);
 
@@ -46,19 +55,30 @@
     enum { SOCKET_TIMEOUT=-2, SOCKET_EOF=-3 } ErrorCode;
 
     /** Returns bytes sent or an ErrorCode value < 0. */
-    ssize_t send(const char* data, size_t size);
+    ssize_t send(const void* data, size_t size);
 
     /**
      * Returns bytes received, an ErrorCode value < 0 or 0
      * if the connection closed in an orderly manner.
      */
-    ssize_t recv(char* data, size_t size);
+    ssize_t recv(void* data, size_t size);
+
+    /** Bind to a port and start listening.
+     *@param port 0 means choose an available port.
+     *@param backlog maximum number of pending connections.
+     *@return The bound port.
+     */
+    int listen(int port = 0, int backlog = 10);
 
+    /** Get file descriptor */
+    int fd(); 
+    
   private:
 #ifdef USE_APR    
     apr_socket_t* socket;
 #else
-    int socket;
+    void init() const;
+    mutable int socket;         // Initialized on demand. 
 #endif
 };
 

Modified: incubator/qpid/trunk/qpid/cpp/src/qpid/sys/Thread.h
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/src/qpid/sys/Thread.h?view=diff&rev=480582&r1=480581&r2=480582
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/src/qpid/sys/Thread.h (original)
+++ incubator/qpid/trunk/qpid/cpp/src/qpid/sys/Thread.h Wed Nov 29 06:36:08 2006
@@ -40,11 +40,17 @@
 class Thread
 {
   public:
+    inline static Thread current();
+    inline static void yield();
+
     inline Thread();
     inline explicit Thread(qpid::sys::Runnable*);
+    inline explicit Thread(qpid::sys::Runnable&);
+    
     inline void join();
-    inline static Thread current();
 
+    inline long id();
+        
   private:
 #ifdef USE_APR
     static void* APR_THREAD_FUNC runRunnable(apr_thread_t* thread, void *data);
@@ -68,12 +74,21 @@
         apr_thread_create(&thread, 0, runRunnable, runnable, APRPool::get()));
 }
 
+Thread::Thread(Runnable& runnable) {
+    CHECK_APR_SUCCESS(
+        apr_thread_create(&thread, 0, runRunnable, &runnable, APRPool::get()));
+}
+
 void Thread::join(){
     apr_status_t status;
     if (thread != 0) 
         CHECK_APR_SUCCESS(apr_thread_join(&status, thread));
 }
 
+long Thread::id() {
+    return long(thread);
+}
+
 Thread::Thread(apr_thread_t* t) : thread(t) {}
 
 Thread Thread::current(){
@@ -83,15 +98,29 @@
     return Thread(thr);
 }
 
+void Thread::yield() 
+{
+    apr_thread_yield();
+}
+
+
 // POSIX ================================================================
 #else
 
 Thread::Thread(Runnable* runnable) {
-    CHECK0(pthread_create(&thread, NULL, runRunnable, runnable));
+    QPID_POSIX_THROW_IF(pthread_create(&thread, NULL, runRunnable, runnable));
+}
+
+Thread::Thread(Runnable& runnable) {
+    QPID_POSIX_THROW_IF(pthread_create(&thread, NULL, runRunnable, &runnable));
 }
 
 void Thread::join(){
-    if (thread != 0) CHECK0(pthread_join(thread, 0));
+    QPID_POSIX_THROW_IF(pthread_join(thread, 0));
+}
+
+long Thread::id() {
+    return long(thread);
 }
 
 Thread::Thread(pthread_t thr) : thread(thr) {}
@@ -99,6 +128,13 @@
 Thread Thread::current() {
     return Thread(pthread_self());
 }
+
+void Thread::yield() 
+{
+    QPID_POSIX_THROW_IF(pthread_yield());
+}
+
+
 #endif
 
 }}

Modified: incubator/qpid/trunk/qpid/cpp/src/qpid/sys/Time.cpp
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/src/qpid/sys/Time.cpp?view=diff&rev=480582&r1=480581&r2=480582
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/src/qpid/sys/Time.cpp (original)
+++ incubator/qpid/trunk/qpid/cpp/src/qpid/sys/Time.cpp Wed Nov 29 06:36:08 2006
@@ -27,36 +27,33 @@
 // APR ================================================================
 #if USE_APR
 
-Time Time::now() {
-    return Time(apr_time_now(), NSEC_PER_USEC);
-}
-
-void Time::set(int64_t ticks, long nsec_per_tick) {
-    time = (ticks * nsec_per_tick) / NSEC_PER_USEC;
-}
-
-int64_t Time::nsecs() const {
-    return time * NSEC_PER_USEC;
-}
+Time now() { return apr_time_now() * TIME_USEC; }
 
 // POSIX================================================================
 #else 
 
-Time Time::now() {
-    Time t;
-    clock_gettime(CLOCK_REALTIME, &t.time);
-    return t;
+Time now() {
+    struct timespec ts;
+    clock_gettime(CLOCK_REALTIME, &ts);
+    return toTime(ts);
+}
+
+struct timespec toTimespec(const Time& t) {
+    struct timespec ts;
+    toTimespec(ts, t);
+    return ts;
 }
 
-void Time::set(int64_t ticks, long nsec_per_tick) {
-    int64_t ns = ticks * nsec_per_tick;
-    time.tv_sec  = ns / NSEC_PER_SEC;
-    time.tv_nsec = ns % NSEC_PER_SEC;
+struct timespec& toTimespec(struct timespec& ts, const Time& t) {
+    ts.tv_sec  = t / TIME_SEC;
+    ts.tv_nsec = t % TIME_SEC;
+    return  ts;
 }
 
-int64_t Time::nsecs() const {
-    return time.tv_sec * NSEC_PER_SEC + time.tv_nsec;
+Time toTime(const struct timespec& ts) {
+    return ts.tv_sec*TIME_SEC + ts.tv_nsec;
 }
+
 
 #endif
 }}

Modified: incubator/qpid/trunk/qpid/cpp/src/qpid/sys/Time.h
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/src/qpid/sys/Time.h?view=diff&rev=480582&r1=480581&r2=480582
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/src/qpid/sys/Time.h (original)
+++ incubator/qpid/trunk/qpid/cpp/src/qpid/sys/Time.h Wed Nov 29 06:36:08 2006
@@ -33,43 +33,25 @@
 namespace qpid {
 namespace sys {
 
-class Time
-{
-  public:
-    static Time now();
- 
-    enum {
-        NSEC_PER_SEC=1000*1000*1000,
-        NSEC_PER_MSEC=1000*1000,
-        NSEC_PER_USEC=1000
-    };
+/** Time in nanoseconds */
+typedef int64_t Time;
 
-    inline Time(int64_t ticks=0, long nsec_per_tick=1);
+Time now();
 
-    void set(int64_t ticks, long nsec_per_tick=1);
-        
-    inline int64_t msecs() const;
-    inline int64_t usecs() const;
-    int64_t nsecs() const;
+/** Nanoseconds per second. */
+const Time TIME_SEC  = 1000*1000*1000;
+/** Nanoseconds per millisecond */
+const Time TIME_MSEC = 1000*1000;
+/** Nanoseconds per microseconds. */
+const Time TIME_USEC = 1000;
+/** Nanoseconds per nanosecond. */
+const Time TIME_NSEC = 1;
 
 #ifndef USE_APR
-    const struct timespec& getTimespec() const { return time; }
-    struct timespec& getTimespec() { return time; }
+struct timespec toTimespec(const Time& t);
+struct timespec& toTimespec(struct timespec& ts, const Time& t);
+Time toTime(const struct timespec& ts);
 #endif
-    
-  private:
-#ifdef USE_APR
-    apr_time_t time;
-#else
-    struct timespec time;
-#endif
-};
-
-Time::Time(int64_t ticks, long nsec_per_tick) { set(ticks, nsec_per_tick); }
-
-int64_t Time::msecs() const { return nsecs() / NSEC_PER_MSEC; }
-
-int64_t Time::usecs() const { return nsecs() / NSEC_PER_USEC; }
 
 }}
 

Modified: incubator/qpid/trunk/qpid/cpp/test/client/client_test.cpp
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/test/client/client_test.cpp?view=diff&rev=480582&r1=480581&r2=480582
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/test/client/client_test.cpp (original)
+++ incubator/qpid/trunk/qpid/cpp/test/client/client_test.cpp Wed Nov 29 06:36:08 2006
@@ -90,7 +90,9 @@
 	con.close();	
 	std::cout << "Closed connection." << std::endl;
     }catch(qpid::QpidError error){
-	std::cout << "Error [" << error.code << "] " << error.msg << " (" << error.file << ":" << error.line << ")" << std::endl;
+	std::cout << "Error [" << error.code << "] " << error.msg << " ("
+                  << error.location.file << ":" << error.location.line
+                  << ")" << std::endl;
 	return 1;
     }
     return 0;

Modified: incubator/qpid/trunk/qpid/cpp/test/client/echo_service.cpp
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/test/client/echo_service.cpp?view=diff&rev=480582&r1=480581&r2=480582
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/test/client/echo_service.cpp (original)
+++ incubator/qpid/trunk/qpid/cpp/test/client/echo_service.cpp Wed Nov 29 06:36:08 2006
@@ -107,7 +107,7 @@
             
             connection.close();
         } catch(qpid::QpidError error) {
-            std::cout << "Error [" << error.code << "] " << error.msg << " (" << error.file << ":" << error.line << ")" << std::endl;
+            std::cout << error.what() << std::endl;
         }        
     } else {
         try {
@@ -133,7 +133,7 @@
             
             connection.close();
         } catch(qpid::QpidError error) {
-            std::cout << "Error [" << error.code << "] " << error.msg << " (" << error.file << ":" << error.line << ")" << std::endl;
+            std::cout << error.what() << std::endl;
         }
     }
 }

Modified: incubator/qpid/trunk/qpid/cpp/test/client/topic_listener.cpp
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/test/client/topic_listener.cpp?view=diff&rev=480582&r1=480581&r2=480582
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/test/client/topic_listener.cpp (original)
+++ incubator/qpid/trunk/qpid/cpp/test/client/topic_listener.cpp Wed Nov 29 06:36:08 2006
@@ -38,7 +38,7 @@
     const bool transactional;
     bool init;
     int count;
-    int64_t start;
+    Time start;
     
     void shutdown();
     void report();
@@ -96,7 +96,7 @@
             channel.run();
             connection.close();
         }catch(qpid::QpidError error){
-            std::cout << "Error [" << error.code << "] " << error.msg << " (" << error.file << ":" << error.line << ")" << std::endl;
+            std::cout << error.what() << std::endl;
         }
     }
 }
@@ -106,7 +106,7 @@
 
 void Listener::received(Message& message){
     if(!init){        
-        start = Time::now().msecs();
+        start = now();
         count = 0;
         init = true;
     }
@@ -128,10 +128,11 @@
 }
 
 void Listener::report(){
-    int64_t finish = Time::now().msecs();
-    int64_t time = finish - start;
+    Time finish = now();
+    Time time = finish - start;
     std::stringstream reportstr;
-    reportstr << "Received " << count << " messages in " << time << " ms.";
+    reportstr << "Received " << count << " messages in "
+              << time/TIME_MSEC << " ms.";
     Message msg;
     msg.setData(reportstr.str());
     channel->publish(msg, string(), responseQueue);

Modified: incubator/qpid/trunk/qpid/cpp/test/client/topic_publisher.cpp
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/test/client/topic_publisher.cpp?view=diff&rev=480582&r1=480581&r2=480582
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/test/client/topic_publisher.cpp (original)
+++ incubator/qpid/trunk/qpid/cpp/test/client/topic_publisher.cpp Wed Nov 29 06:36:08 2006
@@ -114,11 +114,13 @@
             int64_t sum(0);
             for(int i = 0; i < batchSize; i++){
                 if(i > 0 && args.getDelay()) sleep(args.getDelay());
-                int64_t time = publisher.publish(args.getMessages(), args.getSubscribers(), args.getSize());
+                Time time = publisher.publish(
+                    args.getMessages(), args.getSubscribers(), args.getSize());
                 if(!max || time > max) max = time;
                 if(!min || time < min) min = time;
                 sum += time;
-                std::cout << "Completed " << (i+1) << " of " << batchSize << " in " << time << "ms" << std::endl;
+                std::cout << "Completed " << (i+1) << " of " << batchSize
+                          << " in " << time/TIME_MSEC << "ms" << std::endl;
             }
             publisher.terminate();
             int64_t avg = sum / batchSize;
@@ -129,7 +131,7 @@
             channel.close();
             connection.close();
         }catch(qpid::QpidError error){
-            std::cout << "Error [" << error.code << "] " << error.msg << " (" << error.file << ":" << error.line << ")" << std::endl;
+            std::cout << error.what() << std::endl;
         }
     }
 }
@@ -153,7 +155,7 @@
 int64_t Publisher::publish(int msgs, int listeners, int size){
     Message msg;
     msg.setData(generateData(size));
-    int64_t start = Time::now().msecs();
+    Time start = now();
     {
         Monitor::ScopedLock l(monitor);
         for(int i = 0; i < msgs; i++){
@@ -170,7 +172,7 @@
         waitForCompletion(listeners);
     }
 
-    int64_t finish(Time::now().msecs());
+    Time finish = now();
     return finish - start; 
 }
 

Added: incubator/qpid/trunk/qpid/cpp/test/unit/qpid/ExceptionTest.cpp
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/test/unit/qpid/ExceptionTest.cpp?view=auto&rev=480582
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/test/unit/qpid/ExceptionTest.cpp (added)
+++ incubator/qpid/trunk/qpid/cpp/test/unit/qpid/ExceptionTest.cpp Wed Nov 29 06:36:08 2006
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+#include <qpid/Exception.h>
+#include <qpid_test_plugin.h>
+
+using namespace qpid;
+
+struct CountDestroyedException : public Exception {
+    int& count;
+    static int staticCount;
+    CountDestroyedException() : count(staticCount) { }
+    CountDestroyedException(int& n) : count(n) {}
+    ~CountDestroyedException() throw() { count++; }
+    void throwSelf() const { throw *this; }
+};
+
+int CountDestroyedException::staticCount = 0;
+         
+        
+class ExceptionTest : public CppUnit::TestCase 
+{
+    CPPUNIT_TEST_SUITE(ExceptionTest);
+    CPPUNIT_TEST(testHeapException);
+    CPPUNIT_TEST_SUITE_END();
+  public:
+    // Verify proper memory management for heap-allocated exceptions.
+    void testHeapException() {
+        int count = 0;
+        try {
+            std::auto_ptr<Exception> p(
+                new CountDestroyedException(count));
+            p.release()->throwSelf();
+            CPPUNIT_FAIL("Expected CountDestroyedException.");
+        } catch (const CountDestroyedException& e) {
+            CPPUNIT_ASSERT(&e.count == &count);
+        }
+        CPPUNIT_ASSERT_EQUAL(1, count);
+    }
+};
+
+    
+// Make this test suite a plugin.
+CPPUNIT_PLUGIN_IMPLEMENT();
+CPPUNIT_TEST_SUITE_REGISTRATION(ExceptionTest);
+

Propchange: incubator/qpid/trunk/qpid/cpp/test/unit/qpid/ExceptionTest.cpp
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/qpid/trunk/qpid/cpp/test/unit/qpid/ExceptionTest.cpp
------------------------------------------------------------------------------
    svn:keywords = Rev Date