summaryrefslogtreecommitdiff
path: root/cpp/src/qpid/sys
diff options
context:
space:
mode:
Diffstat (limited to 'cpp/src/qpid/sys')
-rw-r--r--cpp/src/qpid/sys/AggregateOutput.cpp88
-rw-r--r--cpp/src/qpid/sys/AggregateOutput.h77
-rw-r--r--cpp/src/qpid/sys/AsynchIO.h160
-rw-r--r--cpp/src/qpid/sys/AsynchIOHandler.cpp228
-rw-r--r--cpp/src/qpid/sys/AsynchIOHandler.h80
-rw-r--r--cpp/src/qpid/sys/AtomicCount.h52
-rw-r--r--cpp/src/qpid/sys/AtomicValue.h39
-rw-r--r--cpp/src/qpid/sys/AtomicValue_gcc.h68
-rw-r--r--cpp/src/qpid/sys/AtomicValue_mutex.h83
-rw-r--r--cpp/src/qpid/sys/BlockingQueue.h129
-rw-r--r--cpp/src/qpid/sys/ClusterSafe.cpp66
-rw-r--r--cpp/src/qpid/sys/ClusterSafe.h87
-rw-r--r--cpp/src/qpid/sys/Codec.h52
-rw-r--r--cpp/src/qpid/sys/ConnectionCodec.h68
-rw-r--r--cpp/src/qpid/sys/ConnectionInputHandler.h52
-rw-r--r--cpp/src/qpid/sys/ConnectionInputHandlerFactory.h54
-rw-r--r--cpp/src/qpid/sys/ConnectionOutputHandler.h43
-rw-r--r--cpp/src/qpid/sys/ConnectionOutputHandlerPtr.h56
-rw-r--r--cpp/src/qpid/sys/CopyOnWriteArray.h156
-rw-r--r--cpp/src/qpid/sys/DeletionManager.h162
-rw-r--r--cpp/src/qpid/sys/DispatchHandle.cpp352
-rw-r--r--cpp/src/qpid/sys/DispatchHandle.h150
-rw-r--r--cpp/src/qpid/sys/Dispatcher.cpp40
-rw-r--r--cpp/src/qpid/sys/Dispatcher.h44
-rwxr-xr-xcpp/src/qpid/sys/FileSysDir.h62
-rw-r--r--cpp/src/qpid/sys/Fork.h24
-rw-r--r--cpp/src/qpid/sys/LockFile.h64
-rw-r--r--cpp/src/qpid/sys/LockPtr.h89
-rw-r--r--cpp/src/qpid/sys/OutputControl.h43
-rw-r--r--cpp/src/qpid/sys/OutputTask.h41
-rwxr-xr-xcpp/src/qpid/sys/PipeHandle.h51
-rw-r--r--cpp/src/qpid/sys/PollableCondition.h64
-rw-r--r--cpp/src/qpid/sys/PollableQueue.h176
-rw-r--r--cpp/src/qpid/sys/Poller.h135
-rw-r--r--cpp/src/qpid/sys/ProtocolFactory.h58
-rw-r--r--cpp/src/qpid/sys/RdmaIOPlugin.cpp406
-rw-r--r--cpp/src/qpid/sys/Runnable.cpp32
-rw-r--r--cpp/src/qpid/sys/ScopedIncrement.h67
-rw-r--r--cpp/src/qpid/sys/SecurityLayer.h42
-rw-r--r--cpp/src/qpid/sys/SecuritySettings.h58
-rw-r--r--cpp/src/qpid/sys/Semaphore.h79
-rw-r--r--cpp/src/qpid/sys/Shlib.cpp38
-rw-r--r--cpp/src/qpid/sys/Shlib.h76
-rw-r--r--cpp/src/qpid/sys/ShutdownHandler.h37
-rw-r--r--cpp/src/qpid/sys/Socket.h118
-rw-r--r--cpp/src/qpid/sys/SocketAddress.h53
-rw-r--r--cpp/src/qpid/sys/SslPlugin.cpp191
-rw-r--r--cpp/src/qpid/sys/StateMonitor.h78
-rw-r--r--cpp/src/qpid/sys/TCPIOPlugin.cpp155
-rw-r--r--cpp/src/qpid/sys/TimeoutHandler.h39
-rw-r--r--cpp/src/qpid/sys/Timer.cpp205
-rw-r--r--cpp/src/qpid/sys/Timer.h107
-rw-r--r--cpp/src/qpid/sys/TimerWarnings.cpp82
-rw-r--r--cpp/src/qpid/sys/TimerWarnings.h81
-rw-r--r--cpp/src/qpid/sys/Waitable.h117
-rw-r--r--cpp/src/qpid/sys/alloca.h42
-rw-r--r--cpp/src/qpid/sys/apr/APRBase.cpp89
-rw-r--r--cpp/src/qpid/sys/apr/APRBase.h74
-rw-r--r--cpp/src/qpid/sys/apr/APRPool.cpp41
-rw-r--r--cpp/src/qpid/sys/apr/APRPool.h50
-rw-r--r--cpp/src/qpid/sys/apr/Condition.h84
-rw-r--r--cpp/src/qpid/sys/apr/Mutex.h124
-rw-r--r--cpp/src/qpid/sys/apr/Shlib.cpp49
-rw-r--r--cpp/src/qpid/sys/apr/Socket.cpp114
-rw-r--r--cpp/src/qpid/sys/apr/Thread.cpp34
-rw-r--r--cpp/src/qpid/sys/apr/Thread.h106
-rw-r--r--cpp/src/qpid/sys/apr/Time.cpp36
-rw-r--r--cpp/src/qpid/sys/cyrus/CyrusSecurityLayer.cpp127
-rw-r--r--cpp/src/qpid/sys/cyrus/CyrusSecurityLayer.h68
-rw-r--r--cpp/src/qpid/sys/epoll/EpollPoller.cpp674
-rw-r--r--cpp/src/qpid/sys/posix/AsynchIO.cpp611
-rwxr-xr-xcpp/src/qpid/sys/posix/FileSysDir.cpp54
-rw-r--r--cpp/src/qpid/sys/posix/Fork.cpp129
-rw-r--r--cpp/src/qpid/sys/posix/Fork.h82
-rw-r--r--cpp/src/qpid/sys/posix/IOHandle.cpp44
-rwxr-xr-xcpp/src/qpid/sys/posix/LockFile.cpp108
-rw-r--r--cpp/src/qpid/sys/posix/Mutex.cpp46
-rw-r--r--cpp/src/qpid/sys/posix/PidFile.h62
-rwxr-xr-xcpp/src/qpid/sys/posix/PipeHandle.cpp64
-rw-r--r--cpp/src/qpid/sys/posix/PollableCondition.cpp124
-rw-r--r--cpp/src/qpid/sys/posix/Shlib.cpp60
-rw-r--r--cpp/src/qpid/sys/posix/Socket.cpp294
-rw-r--r--cpp/src/qpid/sys/posix/SocketAddress.cpp97
-rw-r--r--cpp/src/qpid/sys/posix/StrError.cpp41
-rwxr-xr-xcpp/src/qpid/sys/posix/SystemInfo.cpp153
-rw-r--r--cpp/src/qpid/sys/posix/Thread.cpp88
-rw-r--r--cpp/src/qpid/sys/posix/Time.cpp121
-rw-r--r--cpp/src/qpid/sys/rdma/RdmaClient.cpp247
-rw-r--r--cpp/src/qpid/sys/rdma/RdmaIO.cpp720
-rw-r--r--cpp/src/qpid/sys/rdma/RdmaIO.h250
-rw-r--r--cpp/src/qpid/sys/rdma/RdmaServer.cpp210
-rw-r--r--cpp/src/qpid/sys/rdma/rdma_exception.h69
-rw-r--r--cpp/src/qpid/sys/rdma/rdma_factories.cpp105
-rw-r--r--cpp/src/qpid/sys/rdma/rdma_factories.h40
-rw-r--r--cpp/src/qpid/sys/rdma/rdma_wrap.cpp566
-rw-r--r--cpp/src/qpid/sys/rdma/rdma_wrap.h287
-rw-r--r--cpp/src/qpid/sys/solaris/ECFPoller.cpp444
-rwxr-xr-xcpp/src/qpid/sys/solaris/SystemInfo.cpp124
-rw-r--r--cpp/src/qpid/sys/ssl/SslHandler.cpp195
-rw-r--r--cpp/src/qpid/sys/ssl/SslHandler.h78
-rw-r--r--cpp/src/qpid/sys/ssl/SslIo.cpp447
-rw-r--r--cpp/src/qpid/sys/ssl/SslIo.h172
-rw-r--r--cpp/src/qpid/sys/ssl/SslSocket.cpp360
-rw-r--r--cpp/src/qpid/sys/ssl/SslSocket.h132
-rw-r--r--cpp/src/qpid/sys/ssl/check.cpp85
-rw-r--r--cpp/src/qpid/sys/ssl/check.h57
-rw-r--r--cpp/src/qpid/sys/ssl/util.cpp120
-rw-r--r--cpp/src/qpid/sys/ssl/util.h50
-rw-r--r--cpp/src/qpid/sys/uuid.h28
-rw-r--r--cpp/src/qpid/sys/windows/AsynchIO.cpp755
-rwxr-xr-xcpp/src/qpid/sys/windows/AsynchIoResult.h204
-rw-r--r--cpp/src/qpid/sys/windows/FileSysDir.cpp53
-rwxr-xr-xcpp/src/qpid/sys/windows/IOHandle.cpp42
-rwxr-xr-xcpp/src/qpid/sys/windows/IoHandlePrivate.h61
-rwxr-xr-xcpp/src/qpid/sys/windows/IocpPoller.cpp219
-rwxr-xr-xcpp/src/qpid/sys/windows/LockFile.cpp64
-rwxr-xr-xcpp/src/qpid/sys/windows/PipeHandle.cpp101
-rw-r--r--cpp/src/qpid/sys/windows/PollableCondition.cpp114
-rw-r--r--cpp/src/qpid/sys/windows/Shlib.cpp54
-rwxr-xr-xcpp/src/qpid/sys/windows/Socket.cpp348
-rw-r--r--cpp/src/qpid/sys/windows/SocketAddress.cpp76
-rw-r--r--cpp/src/qpid/sys/windows/SslAsynchIO.cpp661
-rw-r--r--cpp/src/qpid/sys/windows/SslAsynchIO.h191
-rwxr-xr-xcpp/src/qpid/sys/windows/StrError.cpp52
-rwxr-xr-xcpp/src/qpid/sys/windows/SystemInfo.cpp203
-rwxr-xr-xcpp/src/qpid/sys/windows/Thread.cpp100
-rw-r--r--cpp/src/qpid/sys/windows/Time.cpp136
-rw-r--r--cpp/src/qpid/sys/windows/mingw32_compat.h39
-rw-r--r--cpp/src/qpid/sys/windows/uuid.cpp67
-rw-r--r--cpp/src/qpid/sys/windows/uuid.h39
130 files changed, 0 insertions, 17509 deletions
diff --git a/cpp/src/qpid/sys/AggregateOutput.cpp b/cpp/src/qpid/sys/AggregateOutput.cpp
deleted file mode 100644
index fc95f46fb9..0000000000
--- a/cpp/src/qpid/sys/AggregateOutput.cpp
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- *
- * 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/sys/AggregateOutput.h"
-#include "qpid/log/Statement.h"
-#include <algorithm>
-
-namespace qpid {
-namespace sys {
-
-AggregateOutput::AggregateOutput(OutputControl& c) : busy(false), control(c) {}
-
-void AggregateOutput::abort() { control.abort(); }
-
-void AggregateOutput::activateOutput() { control.activateOutput(); }
-
-void AggregateOutput::giveReadCredit(int32_t credit) { control.giveReadCredit(credit); }
-
-namespace {
-// Clear the busy flag and notify waiting threads in destructor.
-struct ScopedBusy {
- bool& flag;
- Monitor& monitor;
- ScopedBusy(bool& f, Monitor& m) : flag(f), monitor(m) { f = true; }
- ~ScopedBusy() { flag = false; monitor.notifyAll(); }
-};
-}
-
-bool AggregateOutput::doOutput() {
- Mutex::ScopedLock l(lock);
- ScopedBusy sb(busy, lock);
-
- while (!tasks.empty()) {
- OutputTask* t=tasks.front();
- tasks.pop_front();
- bool didOutput;
- {
- // Allow concurrent call to addOutputTask.
- // removeOutputTask will wait till !busy before removing a task.
- Mutex::ScopedUnlock u(lock);
- didOutput = t->doOutput();
- }
- if (didOutput) {
- tasks.push_back(t);
- return true;
- }
- }
- return false;
-}
-
-void AggregateOutput::addOutputTask(OutputTask* task) {
- Mutex::ScopedLock l(lock);
- tasks.push_back(task);
-}
-
-void AggregateOutput::removeOutputTask(OutputTask* task) {
- Mutex::ScopedLock l(lock);
- while (busy) lock.wait();
- tasks.erase(std::remove(tasks.begin(), tasks.end(), task), tasks.end());
-}
-
-void AggregateOutput::removeAll()
-{
- Mutex::ScopedLock l(lock);
- while (busy) lock.wait();
- tasks.clear();
-}
-
-
-}} // namespace qpid::sys
diff --git a/cpp/src/qpid/sys/AggregateOutput.h b/cpp/src/qpid/sys/AggregateOutput.h
deleted file mode 100644
index d7c0ff29e3..0000000000
--- a/cpp/src/qpid/sys/AggregateOutput.h
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- *
- * 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.
- *
- */
-#ifndef _AggregateOutput_
-#define _AggregateOutput_
-
-#include "qpid/sys/Monitor.h"
-#include "qpid/sys/OutputControl.h"
-#include "qpid/sys/OutputTask.h"
-#include "qpid/CommonImportExport.h"
-
-#include <algorithm>
-#include <deque>
-
-namespace qpid {
-namespace sys {
-
-/**
- * Holds a collection of output tasks, doOutput picks the next one to execute.
- *
- * Tasks are automatically removed if their doOutput() or hasOutput() returns false.
- *
- * Thread safe. addOutputTask may be called in one connection thread while
- * doOutput is called in another.
- */
-
-class QPID_COMMON_CLASS_EXTERN AggregateOutput : public OutputTask, public OutputControl
-{
- typedef std::deque<OutputTask*> TaskList;
-
- Monitor lock;
- TaskList tasks;
- bool busy;
- OutputControl& control;
-
- public:
- QPID_COMMON_EXTERN AggregateOutput(OutputControl& c);
-
- // These may be called concurrently with any function.
- QPID_COMMON_EXTERN void abort();
- QPID_COMMON_EXTERN void activateOutput();
- QPID_COMMON_EXTERN void giveReadCredit(int32_t);
- QPID_COMMON_EXTERN void addOutputTask(OutputTask* t);
-
- // These functions must not be called concurrently with each other.
- QPID_COMMON_EXTERN bool doOutput();
- QPID_COMMON_EXTERN void removeOutputTask(OutputTask* t);
- QPID_COMMON_EXTERN void removeAll();
-
- /** Apply f to each OutputTask* in the tasks list */
- template <class F> void eachOutput(F f) {
- Mutex::ScopedLock l(lock);
- std::for_each(tasks.begin(), tasks.end(), f);
- }
-};
-
-}} // namespace qpid::sys
-
-
-#endif
diff --git a/cpp/src/qpid/sys/AsynchIO.h b/cpp/src/qpid/sys/AsynchIO.h
deleted file mode 100644
index 50da8fa4fc..0000000000
--- a/cpp/src/qpid/sys/AsynchIO.h
+++ /dev/null
@@ -1,160 +0,0 @@
-#ifndef _sys_AsynchIO
-#define _sys_AsynchIO
-/*
- *
- * 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/sys/IntegerTypes.h"
-#include "qpid/CommonImportExport.h"
-
-#include <string.h>
-
-#include <boost/function.hpp>
-#include <boost/shared_ptr.hpp>
-
-namespace qpid {
-namespace sys {
-
-class Socket;
-class Poller;
-
-/*
- * Asynchronous acceptor: accepts connections then does a callback with the
- * accepted fd
- */
-class AsynchAcceptor {
-public:
- typedef boost::function1<void, const Socket&> Callback;
-
- QPID_COMMON_EXTERN static AsynchAcceptor* create(const Socket& s, Callback callback);
- virtual ~AsynchAcceptor() {};
- virtual void start(boost::shared_ptr<Poller> poller) = 0;
-};
-
-/*
- * Asynchronous connector: starts the process of initiating a connection and
- * invokes a callback when completed or failed.
- */
-class AsynchConnector {
-public:
- typedef boost::function1<void, const Socket&> ConnectedCallback;
- typedef boost::function3<void, const Socket&, int, const std::string&> FailedCallback;
-
- // Call create() to allocate a new AsynchConnector object with the
- // specified poller, addressing, and callbacks.
- // This method is implemented in platform-specific code to
- // create a correctly typed object. The platform code also manages
- // deletes. To correctly manage heaps when needed, the allocate and
- // delete should both be done from the same class/library.
- QPID_COMMON_EXTERN static AsynchConnector* create(const Socket& s,
- std::string hostname,
- uint16_t port,
- ConnectedCallback connCb,
- FailedCallback failCb);
- virtual void start(boost::shared_ptr<Poller> poller) = 0;
- virtual void stop() {};
-protected:
- AsynchConnector() {}
- virtual ~AsynchConnector() {}
-};
-
-struct AsynchIOBufferBase {
- char* const bytes;
- const int32_t byteCount;
- int32_t dataStart;
- int32_t dataCount;
-
- AsynchIOBufferBase(char* const b, const int32_t s) :
- bytes(b),
- byteCount(s),
- dataStart(0),
- dataCount(0)
- {}
-
- virtual ~AsynchIOBufferBase()
- {}
-
- void squish() {
- if (dataStart != 0) {
- ::memmove(bytes, bytes + dataStart, dataCount);
- dataStart = 0;
- }
- }
-};
-
-/*
- * Asychronous reader/writer:
- * Reader accepts buffers to read into; reads into the provided buffers
- * and then does a callback with the buffer and amount read. Optionally it
- * can callback when there is something to read but no buffer to read it into.
- *
- * Writer accepts a buffer and queues it for writing; can also be given
- * a callback for when writing is "idle" (ie fd is writable, but nothing
- * to write).
- */
-class AsynchIO {
-public:
- typedef AsynchIOBufferBase BufferBase;
-
- typedef boost::function2<void, AsynchIO&, BufferBase*> ReadCallback;
- typedef boost::function1<void, AsynchIO&> EofCallback;
- typedef boost::function1<void, AsynchIO&> DisconnectCallback;
- typedef boost::function2<void, AsynchIO&, const Socket&> ClosedCallback;
- typedef boost::function1<void, AsynchIO&> BuffersEmptyCallback;
- typedef boost::function1<void, AsynchIO&> IdleCallback;
- typedef boost::function1<void, AsynchIO&> RequestCallback;
-
- // Call create() to allocate a new AsynchIO object with the specified
- // callbacks. This method is implemented in platform-specific code to
- // create a correctly typed object. The platform code also manages
- // deletes. To correctly manage heaps when needed, the allocate and
- // delete should both be done from the same class/library.
- QPID_COMMON_EXTERN static AsynchIO* create(const Socket& s,
- ReadCallback rCb,
- EofCallback eofCb,
- DisconnectCallback disCb,
- ClosedCallback cCb = 0,
- BuffersEmptyCallback eCb = 0,
- IdleCallback iCb = 0);
-public:
- virtual void queueForDeletion() = 0;
-
- virtual void start(boost::shared_ptr<Poller> poller) = 0;
- virtual void queueReadBuffer(BufferBase* buff) = 0;
- virtual void unread(BufferBase* buff) = 0;
- virtual void queueWrite(BufferBase* buff) = 0;
- virtual void notifyPendingWrite() = 0;
- virtual void queueWriteClose() = 0;
- virtual bool writeQueueEmpty() = 0;
- virtual void startReading() = 0;
- virtual void stopReading() = 0;
- virtual void requestCallback(RequestCallback) = 0;
- virtual BufferBase* getQueuedBuffer() = 0;
-
-protected:
- // Derived class manages lifetime; must be constructed using the
- // static create() method. Deletes not allowed from outside.
- AsynchIO() {}
- virtual ~AsynchIO() {}
-};
-
-}}
-
-#endif // _sys_AsynchIO
diff --git a/cpp/src/qpid/sys/AsynchIOHandler.cpp b/cpp/src/qpid/sys/AsynchIOHandler.cpp
deleted file mode 100644
index 30a87d9d44..0000000000
--- a/cpp/src/qpid/sys/AsynchIOHandler.cpp
+++ /dev/null
@@ -1,228 +0,0 @@
-/*
- *
- * 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/sys/AsynchIOHandler.h"
-#include "qpid/sys/AsynchIO.h"
-#include "qpid/sys/Socket.h"
-#include "qpid/sys/SecuritySettings.h"
-#include "qpid/framing/AMQP_HighestVersion.h"
-#include "qpid/framing/ProtocolInitiation.h"
-#include "qpid/log/Statement.h"
-
-#include <boost/bind.hpp>
-
-namespace qpid {
-namespace sys {
-
-// Buffer definition
-struct Buff : public AsynchIO::BufferBase {
- Buff() :
- AsynchIO::BufferBase(new char[65536], 65536)
- {}
- ~Buff()
- { delete [] bytes;}
-};
-
-AsynchIOHandler::AsynchIOHandler(std::string id, ConnectionCodec::Factory* f) :
- identifier(id),
- aio(0),
- factory(f),
- codec(0),
- readError(false),
- isClient(false),
- readCredit(InfiniteCredit)
-{}
-
-AsynchIOHandler::~AsynchIOHandler() {
- if (codec)
- codec->closed();
- delete codec;
-}
-
-void AsynchIOHandler::init(AsynchIO* a, int numBuffs) {
- aio = a;
-
- // Give connection some buffers to use
- for (int i = 0; i < numBuffs; i++) {
- aio->queueReadBuffer(new Buff);
- }
-}
-
-void AsynchIOHandler::write(const framing::ProtocolInitiation& data)
-{
- QPID_LOG(debug, "SENT [" << identifier << "] INIT(" << data << ")");
- AsynchIO::BufferBase* buff = aio->getQueuedBuffer();
- if (!buff)
- buff = new Buff;
- framing::Buffer out(buff->bytes, buff->byteCount);
- data.encode(out);
- buff->dataCount = data.encodedSize();
- aio->queueWrite(buff);
-}
-
-void AsynchIOHandler::abort() {
- // Don't disconnect if we're already disconnecting
- if (!readError) {
- aio->requestCallback(boost::bind(&AsynchIOHandler::eof, this, _1));
- }
-}
-
-void AsynchIOHandler::activateOutput() {
- aio->notifyPendingWrite();
-}
-
-// Input side
-void AsynchIOHandler::giveReadCredit(int32_t credit) {
- // Check whether we started in the don't about credit state
- if (readCredit.boolCompareAndSwap(InfiniteCredit, credit))
- return;
- // TODO In theory should be able to use an atomic operation before taking the lock
- // but in practice there seems to be an unexplained race in that case
- ScopedLock<Mutex> l(creditLock);
- if (readCredit.fetchAndAdd(credit) != 0)
- return;
- assert(readCredit.get() >= 0);
- if (readCredit.get() != 0)
- aio->startReading();
-}
-
-void AsynchIOHandler::readbuff(AsynchIO& , AsynchIO::BufferBase* buff) {
- if (readError) {
- return;
- }
-
- // Check here for read credit
- if (readCredit.get() != InfiniteCredit) {
- if (readCredit.get() == 0) {
- // FIXME aconway 2009-10-01: Workaround to avoid "false wakeups".
- // readbuff is sometimes called with no credit.
- // This should be fixed somewhere else to avoid such calls.
- aio->unread(buff);
- return;
- }
- // TODO In theory should be able to use an atomic operation before taking the lock
- // but in practice there seems to be an unexplained race in that case
- ScopedLock<Mutex> l(creditLock);
- if (--readCredit == 0) {
- assert(readCredit.get() >= 0);
- if (readCredit.get() == 0) {
- aio->stopReading();
- }
- }
- }
-
- size_t decoded = 0;
- if (codec) { // Already initiated
- try {
- decoded = codec->decode(buff->bytes+buff->dataStart, buff->dataCount);
- }catch(const std::exception& e){
- QPID_LOG(error, e.what());
- readError = true;
- aio->queueWriteClose();
- }
- }else{
- framing::Buffer in(buff->bytes+buff->dataStart, buff->dataCount);
- framing::ProtocolInitiation protocolInit;
- if (protocolInit.decode(in)) {
- decoded = in.getPosition();
- QPID_LOG(debug, "RECV [" << identifier << "] INIT(" << protocolInit << ")");
- try {
- codec = factory->create(protocolInit.getVersion(), *this, identifier, SecuritySettings());
- if (!codec) {
- //TODO: may still want to revise this...
- //send valid version header & close connection.
- write(framing::ProtocolInitiation(framing::highestProtocolVersion));
- readError = true;
- aio->queueWriteClose();
- }
- } catch (const std::exception& e) {
- QPID_LOG(error, e.what());
- readError = true;
- aio->queueWriteClose();
- }
- }
- }
- // TODO: unreading needs to go away, and when we can cope
- // with multiple sub-buffers in the general buffer scheme, it will
- if (decoded != size_t(buff->dataCount)) {
- // Adjust buffer for used bytes and then "unread them"
- buff->dataStart += decoded;
- buff->dataCount -= decoded;
- aio->unread(buff);
- } else {
- // Give whole buffer back to aio subsystem
- aio->queueReadBuffer(buff);
- }
-}
-
-void AsynchIOHandler::eof(AsynchIO& a) {
- disconnect(a);
- readError = true;
- aio->queueWriteClose();
-}
-
-void AsynchIOHandler::closedSocket(AsynchIO&, const Socket& s) {
- // If we closed with data still to send log a warning
- if (!aio->writeQueueEmpty()) {
- QPID_LOG(warning, "CLOSING [" << identifier << "] unsent data (probably due to client disconnect)");
- }
- delete &s;
- aio->queueForDeletion();
- delete this;
-}
-
-void AsynchIOHandler::disconnect(AsynchIO&) {
- QPID_LOG(debug, "DISCONNECTED [" << identifier << "]");
- if (codec) codec->closed();
-}
-
-// Notifications
-void AsynchIOHandler::nobuffs(AsynchIO&) {
-}
-
-void AsynchIOHandler::idle(AsynchIO&){
- if (isClient && codec == 0) {
- codec = factory->create(*this, identifier, SecuritySettings());
- write(framing::ProtocolInitiation(codec->getVersion()));
- return;
- }
- if (codec == 0) return;
- try {
- if (codec->canEncode()) {
- // Try and get a queued buffer if not then construct new one
- AsynchIO::BufferBase* buff = aio->getQueuedBuffer();
- if (!buff) buff = new Buff;
- size_t encoded=codec->encode(buff->bytes, buff->byteCount);
- buff->dataCount = encoded;
- aio->queueWrite(buff);
- }
- if (codec->isClosed()) {
- readError = true;
- aio->queueWriteClose();
- }
- } catch (const std::exception& e) {
- QPID_LOG(error, e.what());
- readError = true;
- aio->queueWriteClose();
- }
-}
-
-}} // namespace qpid::sys
diff --git a/cpp/src/qpid/sys/AsynchIOHandler.h b/cpp/src/qpid/sys/AsynchIOHandler.h
deleted file mode 100644
index b9867606c4..0000000000
--- a/cpp/src/qpid/sys/AsynchIOHandler.h
+++ /dev/null
@@ -1,80 +0,0 @@
-#ifndef _sys_AsynchIOHandler_h
-#define _sys_AsynchIOHandler_h
-/*
- *
- * 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/sys/OutputControl.h"
-#include "qpid/sys/ConnectionCodec.h"
-#include "qpid/sys/AtomicValue.h"
-#include "qpid/sys/Mutex.h"
-#include "qpid/CommonImportExport.h"
-
-namespace qpid {
-
-namespace framing {
- class ProtocolInitiation;
-}
-
-namespace sys {
-
-class AsynchIO;
-struct AsynchIOBufferBase;
-class Socket;
-
-class AsynchIOHandler : public OutputControl {
- std::string identifier;
- AsynchIO* aio;
- ConnectionCodec::Factory* factory;
- ConnectionCodec* codec;
- bool readError;
- bool isClient;
- AtomicValue<int32_t> readCredit;
- static const int32_t InfiniteCredit = -1;
- Mutex creditLock;
-
- void write(const framing::ProtocolInitiation&);
-
- public:
- QPID_COMMON_EXTERN AsynchIOHandler(std::string id, ConnectionCodec::Factory* f);
- QPID_COMMON_EXTERN ~AsynchIOHandler();
- QPID_COMMON_EXTERN void init(AsynchIO* a, int numBuffs);
-
- QPID_COMMON_INLINE_EXTERN void setClient() { isClient = true; }
-
- // Output side
- QPID_COMMON_EXTERN void abort();
- QPID_COMMON_EXTERN void activateOutput();
- QPID_COMMON_EXTERN void giveReadCredit(int32_t credit);
-
- // Input side
- QPID_COMMON_EXTERN void readbuff(AsynchIO& aio, AsynchIOBufferBase* buff);
- QPID_COMMON_EXTERN void eof(AsynchIO& aio);
- QPID_COMMON_EXTERN void disconnect(AsynchIO& aio);
-
- // Notifications
- QPID_COMMON_EXTERN void nobuffs(AsynchIO& aio);
- QPID_COMMON_EXTERN void idle(AsynchIO& aio);
- QPID_COMMON_EXTERN void closedSocket(AsynchIO& aio, const Socket& s);
-};
-
-}} // namespace qpid::sys
-
-#endif // _sys_AsynchIOHandler_h
diff --git a/cpp/src/qpid/sys/AtomicCount.h b/cpp/src/qpid/sys/AtomicCount.h
deleted file mode 100644
index 94580c61f3..0000000000
--- a/cpp/src/qpid/sys/AtomicCount.h
+++ /dev/null
@@ -1,52 +0,0 @@
-#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 "qpid/sys/ScopedIncrement.h"
-
-namespace qpid {
-namespace sys {
-
-/**
- * Atomic counter.
- */
-class AtomicCount {
- public:
- typedef ::qpid::sys::ScopedDecrement<AtomicCount> ScopedDecrement;
- typedef ::qpid::sys::ScopedIncrement<AtomicCount> ScopedIncrement;
-
- 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
diff --git a/cpp/src/qpid/sys/AtomicValue.h b/cpp/src/qpid/sys/AtomicValue.h
deleted file mode 100644
index bf995f991e..0000000000
--- a/cpp/src/qpid/sys/AtomicValue.h
+++ /dev/null
@@ -1,39 +0,0 @@
-#ifndef QPID_SYS_ATOMICVALUE_H
-#define QPID_SYS_ATOMICVALUE_H
-
-/*
- *
- * 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.
- *
- */
-
-// Have to check for clang before gcc as clang pretends to be gcc too
-#if defined( __clang__ )
-// Use the clang doesn't support atomic builtins for 64 bit values, so use the slow versions
-#include "qpid/sys/AtomicValue_mutex.h"
-
-#elif defined( __GNUC__ ) && __GNUC__ >= 4 && ( defined( __i686__ ) || defined( __x86_64__ ) )
-// Use the Gnu C built-in atomic operations if compiling with gcc on a suitable platform.
-#include "qpid/sys/AtomicValue_gcc.h"
-
-#else
-// Fall-back to mutex locked operations if we don't have atomic ops.
-#include "qpid/sys/AtomicValue_mutex.h"
-#endif
-
-#endif /*!QPID_SYS_ATOMICVALUE_GCC_H*/
diff --git a/cpp/src/qpid/sys/AtomicValue_gcc.h b/cpp/src/qpid/sys/AtomicValue_gcc.h
deleted file mode 100644
index d022b07c1d..0000000000
--- a/cpp/src/qpid/sys/AtomicValue_gcc.h
+++ /dev/null
@@ -1,68 +0,0 @@
-#ifndef QPID_SYS_ATOMICVALUE_GCC_H
-#define QPID_SYS_ATOMICVALUE_GCC_H
-
-/*
- *
- * 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.
- *
- */
-
-#if !defined(QPID_SYS_ATOMICVALUE_H)
-#error "This file should only be included via AtomicValue.h."
-#endif
-
-namespace qpid {
-namespace sys {
-
-/**
- * Atomic value of type T. T must be an integral type of size 1,2,4 or 8 bytes.
- * All operations are atomic and preform a full memory barrier unless otherwise noted.
- */
-template <class T>
-class AtomicValue
-{
- public:
- AtomicValue(T init=0) : value(init) {}
-
- // Update and return new value.
- inline T operator+=(T n) { return __sync_add_and_fetch(&value, n); }
- inline T operator-=(T n) { return __sync_sub_and_fetch(&value, n); }
- inline T operator++() { return *this += 1; }
- inline T operator--() { return *this -= 1; }
-
- // Update and return old value.
- inline T fetchAndAdd(T n) { return __sync_fetch_and_add(&value, n); }
- inline T fetchAndSub(T n) { return __sync_fetch_and_sub(&value, n); }
- inline T operator++(int) { return fetchAndAdd(1); }
- inline T operator--(int) { return fetchAndSub(1); }
-
- /** If current value == testval then set to newval. Returns the old value. */
- T valueCompareAndSwap(T testval, T newval) { return __sync_val_compare_and_swap(&value, testval, newval); }
-
- /** If current value == testval then set to newval. Returns true if the swap was performed. */
- bool boolCompareAndSwap(T testval, T newval) { return __sync_bool_compare_and_swap(&value, testval, newval); }
-
- T get() const { return const_cast<AtomicValue<T>*>(this)->fetchAndAdd(static_cast<T>(0)); }
-
- private:
- T value;
-};
-
-}} // namespace qpid::sys
-
-#endif /*!QPID_SYS_ATOMICVALUE_GCC_H*/
diff --git a/cpp/src/qpid/sys/AtomicValue_mutex.h b/cpp/src/qpid/sys/AtomicValue_mutex.h
deleted file mode 100644
index e4d433e7f5..0000000000
--- a/cpp/src/qpid/sys/AtomicValue_mutex.h
+++ /dev/null
@@ -1,83 +0,0 @@
-#ifndef QPID_SYS_ATOMICVALUE_MUTEX_H
-#define QPID_SYS_ATOMICVALUE_MUTEX_H
-
-/*
- *
- * 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.
- *
- */
-
-#if !defined(QPID_SYS_ATOMICVALUE_H)
-#error "This file should only be included via AtomicValue.h."
-#endif
-
-#include "qpid/sys/Mutex.h"
-
-namespace qpid {
-namespace sys {
-
-/**
- * Atomic value of type T. T must be an integral type of size 1,2,4 or 8 bytes.
- * All operations are atomic and preform a full memory barrier unless otherwise noted.
- */
-template <class T>
-class AtomicValue
-{
- public:
- AtomicValue(T init=0) : value(init) {}
-
- // Update and return new value.
- inline T operator+=(T n) { Lock l(lock); return value += n; }
- inline T operator-=(T n) { Lock l(lock); return value -= n; }
- inline T operator++() { return *this += 1; }
- inline T operator--() { return *this -= 1; }
-
- // Update and return old value.
- inline T fetchAndAdd(T n) { Lock l(lock); T old=value; value += n; return old; }
- inline T fetchAndSub(T n) { Lock l(lock); T old=value; value -= n; return old; }
- inline T operator++(int) { return fetchAndAdd(1); }
- inline T operator--(int) { return fetchAndSub(1); }
-
- AtomicValue& operator=(T newval) { Lock l(lock); value = newval; return *this; }
-
- /** If current value == testval then set to newval. Returns the old value. */
- T valueCompareAndSwap(T testval, T newval) {
- Lock l(lock);
- T old=value;
- if (value == testval) value = newval;
- return old;
- }
-
- /** If current value == testval then set to newval. Returns true if the swap was performed. */
- bool boolCompareAndSwap(T testval, T newval) {
- Lock l(lock);
- if (value == testval) { value = newval; return true; }
- return false;
- }
-
- T get() const { Lock l(lock); return value; }
-
- private:
- typedef Mutex::ScopedLock Lock;
- T value;
- mutable Mutex lock;
-};
-
-}} // namespace qpid::sys
-
-#endif /*!QPID_SYS_ATOMICVALUE_MUTEX_H*/
diff --git a/cpp/src/qpid/sys/BlockingQueue.h b/cpp/src/qpid/sys/BlockingQueue.h
deleted file mode 100644
index ca6b529930..0000000000
--- a/cpp/src/qpid/sys/BlockingQueue.h
+++ /dev/null
@@ -1,129 +0,0 @@
-#ifndef QPID_SYS_BLOCKINGQUEUE_H
-#define QPID_SYS_BLOCKINGQUEUE_H
-
-/*
- *
- * 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/sys/Waitable.h"
-
-#include <queue>
-
-namespace qpid {
-namespace sys {
-
-/**
- * A simple blocking queue template
- */
-template <class T>
-class BlockingQueue
-{
- mutable sys::Waitable waitable;
- std::queue<T> queue;
-
-public:
- BlockingQueue() {}
- ~BlockingQueue() { close(); }
-
- /** Pop from the queue, block up to timeout if empty.
- *@param result Set to value popped from queue.
- *@param timeout Defaults to infinite.
- *@return true if result was set, false if queue empty after timeout.
- */
- bool pop(T& result, Duration timeout=TIME_INFINITE) {
- Mutex::ScopedLock l(waitable);
- {
- Waitable::ScopedWait w(waitable);
- if (timeout == TIME_INFINITE) {
- while (queue.empty()) waitable.wait();
- } else if (timeout) {
- AbsTime deadline(now(),timeout);
- while (queue.empty() && deadline > now()) waitable.wait(deadline);
- } else {
- //ensure zero timeout pop does not miss the fact that
- //queue is closed
- waitable.checkException();
- }
- }
- if (queue.empty()) return false;
- result = queue.front();
- queue.pop();
- if (!queue.empty())
- waitable.notify(); // Notify another waiter.
- return true;
- }
-
- T pop(Duration timeout=TIME_INFINITE) {
- T result;
- bool ok = pop(result, timeout);
- if (!ok)
- throw Exception("Timed out waiting on a blocking queue");
- return result;
- }
-
- /** Push a value onto the queue.
- * Note it is not an error to push onto a closed queue.
- */
- void push(const T& t) {
- Mutex::ScopedLock l(waitable);
- queue.push(t);
- waitable.notify(); // Notify a waiter.
- }
-
- /**
- * Close the queue.
- *@ex exception to throw to waiting threads. ClosedException by default.
- */
- void close(const ExceptionHolder& ex=ExceptionHolder(new ClosedException()))
- {
- Mutex::ScopedLock l(waitable);
- if (!waitable.hasException()) {
- waitable.setException(ex);
- waitable.notifyAll();
- waitable.waitWaiters(); // Ensure no threads are still waiting.
- }
- }
-
- /** Open a closed queue. */
- void open() {
- Mutex::ScopedLock l(waitable);
- waitable.resetException();
- }
-
- bool isClosed() const {
- Mutex::ScopedLock l(waitable);
- return waitable.hasException();
- }
-
- bool empty() const {
- Mutex::ScopedLock l(waitable);
- return queue.empty();
- }
- size_t size() const {
- Mutex::ScopedLock l(waitable);
- return queue.size();
- }
-};
-
-}}
-
-
-
-#endif /*!QPID_SYS_BLOCKINGQUEUE_H*/
diff --git a/cpp/src/qpid/sys/ClusterSafe.cpp b/cpp/src/qpid/sys/ClusterSafe.cpp
deleted file mode 100644
index dd37615145..0000000000
--- a/cpp/src/qpid/sys/ClusterSafe.cpp
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- *
- * 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 "ClusterSafe.h"
-#include "qpid/log/Statement.h"
-#include "qpid/sys/Thread.h"
-#include <stdlib.h>
-
-namespace qpid {
-namespace sys {
-
-namespace {
-bool inCluster = false;
-QPID_TSS bool inContext = false;
-}
-
-bool isClusterSafe() { return !inCluster || inContext; }
-
-void assertClusterSafe() {
- if (!isClusterSafe()) {
- QPID_LOG(critical, "Modified cluster state outside of cluster context");
- ::abort();
- }
-}
-
-ClusterSafeScope::ClusterSafeScope() {
- save = inContext;
- inContext = true;
-}
-
-ClusterSafeScope::~ClusterSafeScope() {
- assert(inContext);
- inContext = save;
-}
-
-ClusterUnsafeScope::ClusterUnsafeScope() {
- save = inContext;
- inContext = false;
-}
-
-ClusterUnsafeScope::~ClusterUnsafeScope() {
- assert(!inContext);
- inContext = save;
-}
-
-void enableClusterSafe() { inCluster = true; }
-
-}} // namespace qpid::sys
diff --git a/cpp/src/qpid/sys/ClusterSafe.h b/cpp/src/qpid/sys/ClusterSafe.h
deleted file mode 100644
index 27e4eb46a5..0000000000
--- a/cpp/src/qpid/sys/ClusterSafe.h
+++ /dev/null
@@ -1,87 +0,0 @@
-#ifndef QPID_SYS_CLUSTERSAFE_H
-#define QPID_SYS_CLUSTERSAFE_H
-
-/*
- *
- * 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/CommonImportExport.h"
-
-namespace qpid {
-namespace sys {
-
-/**
- * Assertion to add to code that modifies clustered state.
- *
- * In a non-clustered broker this is a no-op.
- *
- * In a clustered broker, checks that it is being called
- * in a context where it is safe to modify clustered state.
- * If not it aborts the process as this is a serious bug.
- *
- * This function is in the common library rather than the cluster
- * library because it is called by code in the broker library.
- */
-QPID_COMMON_EXTERN void assertClusterSafe();
-
-/**
- * In a non-clustered broker, returns true.
- *
- * In a clustered broker returns true if we are in a context where it
- * is safe to modify cluster state.
- *
- * This function is in the common library rather than the cluster
- * library because it is called by code in the broker library.
- */
-QPID_COMMON_EXTERN bool isClusterSafe();
-
-/**
- * Mark a scope as cluster safe. Sets isClusterSafe in constructor and resets
- * to previous value in destructor.
- */
-class ClusterSafeScope {
- public:
- ClusterSafeScope();
- ~ClusterSafeScope();
- private:
- bool save;
-};
-
-/**
- * Mark a scope as cluster unsafe. Clears isClusterSafe in constructor and resets
- * to previous value in destructor.
- */
-class ClusterUnsafeScope {
- public:
- QPID_COMMON_EXTERN ClusterUnsafeScope();
- QPID_COMMON_EXTERN ~ClusterUnsafeScope();
- private:
- bool save;
-};
-
-/**
- * Enable cluster-safe assertions. By default they are no-ops.
- * Called by cluster code.
- */
-void enableClusterSafe();
-
-}} // namespace qpid::sys
-
-#endif /*!QPID_SYS_CLUSTERSAFE_H*/
diff --git a/cpp/src/qpid/sys/Codec.h b/cpp/src/qpid/sys/Codec.h
deleted file mode 100644
index ace721fbcc..0000000000
--- a/cpp/src/qpid/sys/Codec.h
+++ /dev/null
@@ -1,52 +0,0 @@
-#ifndef QPID_SYS_CODEC_H
-#define QPID_SYS_CODEC_H
-
-/*
- *
- * 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 <cstddef>
-
-namespace qpid {
-namespace sys {
-
-/**
- * Generic codec interface
- */
-class Codec
-{
- public:
- virtual ~Codec() {}
-
- /** Decode from buffer, return number of bytes decoded.
- * @return may be less than size if there was incomplete
- * data at the end of the buffer.
- */
- virtual std::size_t decode(const char* buffer, std::size_t size) = 0;
-
-
- /** Encode into buffer, return number of bytes encoded */
- virtual std::size_t encode(const char* buffer, std::size_t size) = 0;
-
- /** Return true if we have data to encode */
- virtual bool canEncode() = 0;
-};
-}} // namespace qpid::sys
-
-#endif /*!QPID_SYS_CODEC_H*/
diff --git a/cpp/src/qpid/sys/ConnectionCodec.h b/cpp/src/qpid/sys/ConnectionCodec.h
deleted file mode 100644
index c2890f06dc..0000000000
--- a/cpp/src/qpid/sys/ConnectionCodec.h
+++ /dev/null
@@ -1,68 +0,0 @@
-#ifndef QPID_SYS_CONNECTION_CODEC_H
-#define QPID_SYS_CONNECTION_CODEC_H
-
-/*
- *
- * 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/sys/Codec.h"
-#include "qpid/framing/ProtocolVersion.h"
-
-namespace qpid {
-
-namespace sys {
-
-class InputHandlerFactory;
-class OutputControl;
-struct SecuritySettings;
-
-/**
- * Interface of coder/decoder for a connection of a specific protocol
- * version.
- */
-class ConnectionCodec : public Codec {
- public:
- virtual ~ConnectionCodec() {}
-
- /** Network connection was closed from other end. */
- virtual void closed() = 0;
-
- virtual bool isClosed() const = 0;
-
- virtual framing::ProtocolVersion getVersion() const = 0;
-
- struct Factory {
- virtual ~Factory() {}
-
- /** Return 0 if version unknown */
- virtual ConnectionCodec* create(
- framing::ProtocolVersion, OutputControl&, const std::string& id,
- const SecuritySettings&
- ) = 0;
-
- /** Return "preferred" codec for outbound connections. */
- virtual ConnectionCodec* create(
- OutputControl&, const std::string& id, const SecuritySettings&
- ) = 0;
- };
-};
-
-}} // namespace qpid::sys
-
-#endif /*!QPID_SYS_CONNECTION_CODEC_H*/
diff --git a/cpp/src/qpid/sys/ConnectionInputHandler.h b/cpp/src/qpid/sys/ConnectionInputHandler.h
deleted file mode 100644
index 92de808308..0000000000
--- a/cpp/src/qpid/sys/ConnectionInputHandler.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- *
- * 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.
- *
- */
-#ifndef _ConnectionInputHandler_
-#define _ConnectionInputHandler_
-
-#include "qpid/framing/InputHandler.h"
-#include "qpid/sys/OutputTask.h"
-#include "qpid/sys/TimeoutHandler.h"
-
-namespace qpid {
-namespace sys {
-
-
-/**
- * ConnectionInputHandler provides methods to process incoming frames
- * using InputHandler::receive() and to generate outgoing messages in
- * OutputTask::doOutput()
- *
- */
-
- class ConnectionInputHandler :
- public qpid::framing::InputHandler,
- public TimeoutHandler, public OutputTask
- {
- public:
-
- virtual void closed() = 0;
- };
-
-}
-}
-
-
-#endif
diff --git a/cpp/src/qpid/sys/ConnectionInputHandlerFactory.h b/cpp/src/qpid/sys/ConnectionInputHandlerFactory.h
deleted file mode 100644
index 9bb7e13686..0000000000
--- a/cpp/src/qpid/sys/ConnectionInputHandlerFactory.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- *
- * 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.
- *
- */
-#ifndef _ConnectionInputHandlerFactory_
-#define _ConnectionInputHandlerFactory_
-
-#include <boost/noncopyable.hpp>
-#include <string>
-
-namespace qpid {
-namespace sys {
-
-class ConnectionOutputHandler;
-class ConnectionInputHandler;
-
-/**
- * Callback interface used by the Acceptor to
- * create a ConnectionInputHandler for each new connection.
- */
-class ConnectionInputHandlerFactory : private boost::noncopyable
-{
- public:
- /**
- *@param out handler for connection output.
- *@param id identify the connection for management purposes.
- */
- virtual ConnectionInputHandler* create(ConnectionOutputHandler* out,
- const std::string& id,
- bool isClient) = 0;
-
- virtual ~ConnectionInputHandlerFactory(){}
-};
-
-}}
-
-
-#endif
diff --git a/cpp/src/qpid/sys/ConnectionOutputHandler.h b/cpp/src/qpid/sys/ConnectionOutputHandler.h
deleted file mode 100644
index 421dd7c269..0000000000
--- a/cpp/src/qpid/sys/ConnectionOutputHandler.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- *
- * 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.
- *
- */
-#ifndef _ConnectionOutputHandler_
-#define _ConnectionOutputHandler_
-
-#include "qpid/framing/OutputHandler.h"
-#include "qpid/sys/OutputControl.h"
-
-namespace qpid {
-namespace sys {
-
-/**
- * Provides the output handler associated with a connection.
- */
-class ConnectionOutputHandler : public virtual qpid::framing::OutputHandler, public OutputControl
-{
- public:
- virtual void close() = 0;
- virtual size_t getBuffered() const { return 0; }
-};
-
-}}
-
-
-#endif
diff --git a/cpp/src/qpid/sys/ConnectionOutputHandlerPtr.h b/cpp/src/qpid/sys/ConnectionOutputHandlerPtr.h
deleted file mode 100644
index 95a08d15ae..0000000000
--- a/cpp/src/qpid/sys/ConnectionOutputHandlerPtr.h
+++ /dev/null
@@ -1,56 +0,0 @@
-#ifndef QPID_SYS_CONNECTIONOUTPUTHANDLERPTR_H
-#define QPID_SYS_CONNECTIONOUTPUTHANDLERPTR_H
-
-/*
- *
- * 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/sys/ConnectionOutputHandler.h"
-
-namespace qpid {
-namespace sys {
-
-/**
- * A ConnectionOutputHandler that delegates to another
- * ConnectionOutputHandler. Allows the "real" ConnectionOutputHandler
- * to be changed without updating all the pointers/references
- * using the ConnectionOutputHandlerPtr
- */
-class ConnectionOutputHandlerPtr : public ConnectionOutputHandler
-{
- public:
- ConnectionOutputHandlerPtr(ConnectionOutputHandler* p) : next(p) { assert(next); }
- void set(ConnectionOutputHandler* p) { next = p; assert(next); }
- ConnectionOutputHandler* get() { return next; }
- const ConnectionOutputHandler* get() const { return next; }
-
- void close() { next->close(); }
- size_t getBuffered() const { return next->getBuffered(); }
- void abort() { next->abort(); }
- void activateOutput() { next->activateOutput(); }
- void giveReadCredit(int32_t credit) { next->giveReadCredit(credit); }
- void send(framing::AMQFrame& f) { next->send(f); }
-
- private:
- ConnectionOutputHandler* next;
-};
-}} // namespace qpid::sys
-
-#endif /*!QPID_SYS_CONNECTIONOUTPUTHANDLERPTR_H*/
diff --git a/cpp/src/qpid/sys/CopyOnWriteArray.h b/cpp/src/qpid/sys/CopyOnWriteArray.h
deleted file mode 100644
index 45a231dfd8..0000000000
--- a/cpp/src/qpid/sys/CopyOnWriteArray.h
+++ /dev/null
@@ -1,156 +0,0 @@
-#ifndef QPID_SYS_COPYONWRITEARRAY_H
-#define QPID_SYS_COPYONWRITEARRAY_H
-
-/*
- *
- * 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/sys/Mutex.h"
-#include <algorithm>
-#include <vector>
-#include <boost/shared_ptr.hpp>
-
-namespace qpid {
-namespace sys {
-
-/**
- * An array that copies on adding/removing element allowing lock-free
- * iteration.
- */
-template <class T>
-class CopyOnWriteArray
-{
-public:
- typedef boost::shared_ptr<const std::vector<T> > ConstPtr;
-
- CopyOnWriteArray() {}
- CopyOnWriteArray(const CopyOnWriteArray& c) : array(c.array) {}
-
- void add(T& t)
- {
- Mutex::ScopedLock l(lock);
- ArrayPtr copy(array ? new std::vector<T>(*array) : new std::vector<T>());
- copy->push_back(t);
- array = copy;
- }
-
- bool remove(T& t)
- {
- Mutex::ScopedLock l(lock);
- if (array && std::find(array->begin(), array->end(), t) != array->end()) {
- ArrayPtr copy(new std::vector<T>(*array));
- copy->erase(std::find(copy->begin(), copy->end(), t));
- array = copy;
- return true;
- } else {
- return false;
- }
- }
-
- bool clear()
- {
- Mutex::ScopedLock l(lock);
- if (array && !array->empty()) {
- ArrayPtr copy;
- array = copy;
- return true;
- } else {
- return false;
- }
- }
-
- template <class F>
- bool add_unless(T& t, F f)
- {
- Mutex::ScopedLock l(lock);
- if (array && std::find_if(array->begin(), array->end(), f) != array->end()) {
- return false;
- } else {
- ArrayPtr copy(array ? new std::vector<T>(*array) : new std::vector<T>());
- copy->push_back(t);
- array = copy;
- return true;
- }
- }
-
- template <class F>
- bool remove_if(F f)
- {
- Mutex::ScopedLock l(lock);
- if (array && std::find_if(array->begin(), array->end(), f) != array->end()) {
- ArrayPtr copy(new std::vector<T>(*array));
- copy->erase(std::remove_if(copy->begin(), copy->end(), f), copy->end());
- array = copy;
- return true;
- }
- return false;
- }
-
- template <class TestFn, class ModifierFn>
- bool modify_if(TestFn f, ModifierFn & m)
- {
- if (!array)
- return false;
- {
- Mutex::ScopedLock l(lock);
- if (std::find_if(array->begin(), array->end(), f) != array->end())
- {
- ArrayPtr copy(new std::vector<T>(*array));
- m(*std::find_if(copy->begin(), copy->end(), f));
- array = copy;
- return true;
- }
- }
- return false;
- }
-
- template <class F>
- F for_each(F f)
- {
- ArrayPtr a;
- {
- Mutex::ScopedLock l(lock);
- a = array;
- }
- if (!a) return f;
- return std::for_each(a->begin(), a->end(), f);
- }
-
- ConstPtr snapshot()
- {
- ConstPtr a;
- {
- Mutex::ScopedLock l(lock);
- a = array;
- }
- return a;
- }
-
-private:
- typedef boost::shared_ptr< std::vector<T> > ArrayPtr;
- Mutex lock;
- ArrayPtr array;
-};
-
-}}
-
-
-
-#endif /*!QPID_SYS_COPYONWRITEARRAY_H*/
diff --git a/cpp/src/qpid/sys/DeletionManager.h b/cpp/src/qpid/sys/DeletionManager.h
deleted file mode 100644
index c1fea19f30..0000000000
--- a/cpp/src/qpid/sys/DeletionManager.h
+++ /dev/null
@@ -1,162 +0,0 @@
-#ifndef _sys_DeletionManager_h
-#define _sys_DeletionManager_h
-
-/*
- *
- * 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 <vector>
-#include <algorithm>
-#include <boost/shared_ptr.hpp>
-
-namespace qpid {
-namespace sys {
-
-struct deleter
-{
- template <typename T>
- void operator()(T* ptr){ delete ptr;}
-};
-
-/**
- * DeletionManager keeps track of handles that need to be deleted but may still be
- * in use by one of the threads concurrently.
- *
- * The mode of operation is like this:
- * - When we want to delete but we might still be using the handle we
- * * Transfer ownership of the handle to this class
- * * Mark the handle as (potentially) in use by every thread
- * - Then subsequently at points where the thread code knows it isn't
- * using any handles it declares that it is using no handles
- * - When the last thread declares no use of a handle it automatically
- * gets deleted by the shared_ptr implementation
- *
- * The class only has static members and data and so can only be used once for
- * any particular handle type
- */
-template <typename H>
-class DeletionManager
-{
- struct ThreadStatus;
-
-public:
- // Mark every thread as using the handle - it will be deleted
- // below after every thread marks the handle as unused
- static void markForDeletion(H* handle) {
- allThreadsStatuses.addHandle(shared_ptr(handle));
- }
-
- // Mark this thread is not using any handle -
- // handles get deleted here when no one else
- // is using them either
- static void markAllUnusedInThisThread() {
- ThreadStatus* threadStatus = getThreadStatus();
- ScopedLock<Mutex> l(threadStatus->lock);
-
- // The actual deletions will happen here when all the shared_ptr
- // ref counts hit 0 (that is when every thread marks the handle unused)
- threadStatus->handles.clear();
- }
-
- static void destroyThreadState() {
- ThreadStatus* threadStatus = getThreadStatus();
- allThreadsStatuses.delThreadStatus(threadStatus);
- delete threadStatus;
- threadStatus = 0;
- }
-
-private:
-
- static ThreadStatus*& getThreadStatus() {
- static __thread ThreadStatus* threadStatus = 0;
-
- // Thread local vars can't be dynamically constructed so we need
- // to check whether we've made it yet and construct it if not
- // (no locking necessary for the check as it's thread local!)
- if (!threadStatus) {
- threadStatus = new ThreadStatus;
- allThreadsStatuses.addThreadStatus(threadStatus);
- }
-
- return threadStatus;
- }
-
- typedef boost::shared_ptr<H> shared_ptr;
-
- // In theory we know that we never need more handles than the number of
- // threads runnning so we could use a fixed size array. However at this point
- // in the code we don't have easy access to this information.
- struct ThreadStatus
- {
- Mutex lock;
- std::vector<shared_ptr> handles;
- };
-
- class AllThreadsStatuses
- {
- Mutex lock;
- std::vector<ThreadStatus*> statuses;
-
- struct handleAdder
- {
- shared_ptr handle;
-
- handleAdder(shared_ptr h): handle(h) {}
-
- void operator()(ThreadStatus* ptr) {
- ScopedLock<Mutex> l(ptr->lock);
- ptr->handles.push_back(handle);
- }
- };
-
- public:
- // Need this to be able to do static initialisation
- explicit AllThreadsStatuses(int) {}
-
- ~AllThreadsStatuses() {
- ScopedLock<Mutex> l(lock);
- std::for_each(statuses.begin(), statuses.end(), deleter());
- }
-
- void addThreadStatus(ThreadStatus* t) {
- ScopedLock<Mutex> l(lock);
- statuses.push_back(t);
- }
-
- void delThreadStatus(ThreadStatus* t) {
- ScopedLock<Mutex> l(lock);
- typename std::vector<ThreadStatus*>::iterator it =
- std::find(statuses.begin(),statuses.end(), t);
- if (it != statuses.end()) {
- statuses.erase(it);
- }
- }
-
- void addHandle(shared_ptr h) {
- ScopedLock<Mutex> l(lock);
- std::for_each(statuses.begin(), statuses.end(), handleAdder(h));
- }
- };
-
- static AllThreadsStatuses allThreadsStatuses;
-};
-
-}}
-#endif // _sys_DeletionManager_h
diff --git a/cpp/src/qpid/sys/DispatchHandle.cpp b/cpp/src/qpid/sys/DispatchHandle.cpp
deleted file mode 100644
index 5d6fc4e72f..0000000000
--- a/cpp/src/qpid/sys/DispatchHandle.cpp
+++ /dev/null
@@ -1,352 +0,0 @@
-/*
- *
- * 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/sys/DispatchHandle.h"
-#include "qpid/log/Statement.h"
-
-#include <algorithm>
-
-#include <boost/cast.hpp>
-
-#include <assert.h>
-
-namespace qpid {
-namespace sys {
-
-DispatchHandle::DispatchHandle(const IOHandle& h, Callback rCb, Callback wCb, Callback dCb) :
- PollerHandle(h),
- readableCallback(rCb),
- writableCallback(wCb),
- disconnectedCallback(dCb),
- state(IDLE)
-{
-}
-
-
-DispatchHandle::~DispatchHandle() {
-}
-
-void DispatchHandle::startWatch(Poller::shared_ptr poller0) {
- bool r = readableCallback;
- bool w = writableCallback;
-
- ScopedLock<Mutex> lock(stateLock);
- assert(state == IDLE);
-
- poller = poller0;
- poller->registerHandle(*this);
- state = WAITING;
- Poller::Direction dir = r ?
- ( w ? Poller::INOUT : Poller::INPUT ) :
- ( w ? Poller::OUTPUT : Poller::NONE );
- poller->monitorHandle(*this, dir);
-}
-
-void DispatchHandle::rewatch() {
- bool r = readableCallback;
- bool w = writableCallback;
- if (!r && !w) {
- return;
- }
- Poller::Direction dir = r ?
- ( w ? Poller::INOUT : Poller::INPUT ) :
- ( w ? Poller::OUTPUT : Poller::NONE );
-
- ScopedLock<Mutex> lock(stateLock);
- switch(state) {
- case IDLE:
- case STOPPING:
- case DELETING:
- return;
- default:
- break;
- }
- assert(poller);
- poller->monitorHandle(*this, dir);
-}
-
-void DispatchHandle::rewatchRead() {
- if (!readableCallback) {
- return;
- }
-
- ScopedLock<Mutex> lock(stateLock);
- switch(state) {
- case IDLE:
- case STOPPING:
- case DELETING:
- return;
- default:
- break;
- }
- assert(poller);
- poller->monitorHandle(*this, Poller::INPUT);
-}
-
-void DispatchHandle::rewatchWrite() {
- if (!writableCallback) {
- return;
- }
-
- ScopedLock<Mutex> lock(stateLock);
- switch(state) {
- case IDLE:
- case STOPPING:
- case DELETING:
- return;
- default:
- break;
- }
- assert(poller);
- poller->monitorHandle(*this, Poller::OUTPUT);
-}
-
-void DispatchHandle::unwatchRead() {
- if (!readableCallback) {
- return;
- }
-
- ScopedLock<Mutex> lock(stateLock);
- switch(state) {
- case IDLE:
- case STOPPING:
- case DELETING:
- return;
- default:
- break;
- }
- assert(poller);
- poller->unmonitorHandle(*this, Poller::INPUT);
-}
-
-void DispatchHandle::unwatchWrite() {
- if (!writableCallback) {
- return;
- }
-
- ScopedLock<Mutex> lock(stateLock);
- switch(state) {
- case IDLE:
- case STOPPING:
- case DELETING:
- return;
- default:
- break;
- }
- assert(poller);
- poller->unmonitorHandle(*this, Poller::OUTPUT);
-}
-
-void DispatchHandle::unwatch() {
- ScopedLock<Mutex> lock(stateLock);
- switch(state) {
- case IDLE:
- case STOPPING:
- case DELETING:
- return;
- default:
- break;
- }
- assert(poller);
- poller->unmonitorHandle(*this, Poller::INOUT);
-}
-
-void DispatchHandle::stopWatch() {
- ScopedLock<Mutex> lock(stateLock);
- switch (state) {
- case IDLE:
- assert(state != IDLE);
- return;
- case STOPPING:
- assert(state != STOPPING);
- return;
- case CALLING:
- state = STOPPING;
- break;
- case WAITING:
- state = IDLE;
- break;
- case DELETING:
- return;
- }
- assert(poller);
- poller->unregisterHandle(*this);
- poller.reset();
-}
-
-// If we are in the IDLE/STOPPING state we can't do the callback as we've
-// not/no longer got the fd registered in any poller
-void DispatchHandle::call(Callback iCb) {
- assert(iCb);
- ScopedLock<Mutex> lock(stateLock);
- switch (state) {
- case IDLE:
- case STOPPING:
- case DELETING:
- return;
- default:
- interruptedCallbacks.push(iCb);
- assert(poller);
- (void) poller->interrupt(*this);
- }
-}
-
-// The slightly strange switch structure
-// is to ensure that the lock is released before
-// we do the delete
-void DispatchHandle::doDelete() {
- {
- ScopedLock<Mutex> lock(stateLock);
- // Ensure that we're no longer watching anything
- switch (state) {
- case IDLE:
- state = DELETING;
- break;
- case STOPPING:
- state = DELETING;
- return;
- case WAITING:
- state = DELETING;
- assert(poller);
- (void) poller->interrupt(*this);
- poller->unregisterHandle(*this);
- return;
- case CALLING:
- state = DELETING;
- assert(poller);
- poller->unregisterHandle(*this);
- return;
- case DELETING:
- return;
- }
- }
- // If we're IDLE we can do this right away
- delete this;
-}
-
-void DispatchHandle::processEvent(Poller::EventType type) {
-
- // Phase I
- {
- ScopedLock<Mutex> lock(stateLock);
-
- switch(state) {
- case IDLE:
- // Can get here if a non connection thread stops watching
- // whilst we were stuck in the above lock
- return;
- case WAITING:
- state = CALLING;
- break;
- case CALLING:
- assert(state!=CALLING);
- return;
- case STOPPING:
- assert(state!=STOPPING);
- return;
- case DELETING:
- // Need to make sure we clean up any pending callbacks in this case
- std::swap(callbacks, interruptedCallbacks);
- goto saybyebye;
- }
-
- std::swap(callbacks, interruptedCallbacks);
- }
-
- // Do callbacks - whilst we are doing the callbacks we are prevented from processing
- // the same handle until we re-enable it. To avoid rentering the callbacks for a single
- // handle re-enabling in the callbacks is actually deferred until they are complete.
- try {
- switch (type) {
- case Poller::READABLE:
- readableCallback(*this);
- break;
- case Poller::WRITABLE:
- writableCallback(*this);
- break;
- case Poller::READ_WRITABLE:
- readableCallback(*this);
- writableCallback(*this);
- break;
- case Poller::DISCONNECTED:
- if (disconnectedCallback) {
- disconnectedCallback(*this);
- }
- break;
- case Poller::INTERRUPTED:
- {
- // We'll actually do the interrupt below
- }
- break;
- default:
- assert(false);
- }
-
- // If we have any callbacks do them now -
- // (because we use a copy from before the previous callbacks we won't
- // do anything yet that was just added)
- while (callbacks.size() > 0) {
- {
- ScopedLock<Mutex> lock(stateLock);
- switch (state) {
- case DELETING:
- goto finishcallbacks;
- default:
- break;
- }
- }
- Callback cb = callbacks.front();
- assert(cb);
- cb(*this);
- callbacks.pop();
- }
- } catch (std::exception& e) {
- // One of the callbacks threw an exception - that's not allowed
- QPID_LOG(error, "Caught exception in state: " << state << " with event: " << type << ": " << e.what());
- // It would be nice to clean up and delete ourselves here, but we can't
- }
-
-finishcallbacks:
- {
- ScopedLock<Mutex> lock(stateLock);
- switch (state) {
- case IDLE:
- assert(state!=IDLE);
- return;
- case STOPPING:
- state = IDLE;
- return;
- case WAITING:
- assert(state!=WAITING);
- return;
- case CALLING:
- state = WAITING;
- return;
- case DELETING:
- break;
- }
- }
-
-saybyebye:
- delete this;
-}
-
-}}
diff --git a/cpp/src/qpid/sys/DispatchHandle.h b/cpp/src/qpid/sys/DispatchHandle.h
deleted file mode 100644
index 115a3c44f7..0000000000
--- a/cpp/src/qpid/sys/DispatchHandle.h
+++ /dev/null
@@ -1,150 +0,0 @@
-#ifndef _sys_DispatchHandle_h
-#define _sys_DispatchHandle_h
-
-/*
- *
- * 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/sys/Poller.h"
-#include "qpid/sys/Mutex.h"
-#include "qpid/CommonImportExport.h"
-#include <boost/function.hpp>
-
-#include <queue>
-
-namespace qpid {
-namespace sys {
-
-class DispatchHandleRef;
-/**
- * In order to have your own handle (file descriptor on Unix) watched by the poller
- * you need to:
- *
- * - Subclass IOHandle, in the constructor supply an appropriate
- * IOHandlerPrivate object for the platform.
- *
- * - Construct a DispatchHandle passing it your IOHandle and
- * callback functions for read, write and disconnect events.
- *
- * - Ensure the DispatchHandle is not deleted until the poller is no longer using it.
- * TODO: astitcher document DispatchHandleRef to simplify this.
- *
- * When an event occurs on the handle, the poller calls the relevant callback and
- * stops watching that handle. Your callback can call rewatch() or related functions
- * to re-enable polling.
- */
-class DispatchHandle : public PollerHandle {
- friend class DispatchHandleRef;
-public:
- typedef boost::function1<void, DispatchHandle&> Callback;
- typedef std::queue<Callback> CallbackQueue;
-
-private:
- Callback readableCallback;
- Callback writableCallback;
- Callback disconnectedCallback;
- CallbackQueue interruptedCallbacks;
- CallbackQueue callbacks; // Double buffer
- Poller::shared_ptr poller;
- Mutex stateLock;
- enum {
- IDLE,
- STOPPING,
- WAITING,
- CALLING,
- DELETING
- } state;
-
-public:
- /**
- * Provide a handle to poll and a set of callbacks. Note
- * callbacks can be 0, meaning you are not interested in that
- * event.
- *
- *@param h: the handle to watch. The IOHandle encapsulates a
- * platfrom-specific handle to an IO object (e.g. a file descriptor
- * on Unix.)
- *@param rCb Callback called when the handle is readable.
- *@param wCb Callback called when the handle is writable.
- *@param dCb Callback called when the handle is disconnected.
- */
- QPID_COMMON_EXTERN DispatchHandle(const IOHandle& h, Callback rCb, Callback wCb, Callback dCb);
- QPID_COMMON_EXTERN ~DispatchHandle();
-
- /** Add this DispatchHandle to the poller to be watched. */
- QPID_COMMON_EXTERN void startWatch(Poller::shared_ptr poller);
-
- /** Resume watching for all non-0 callbacks. */
- QPID_COMMON_EXTERN void rewatch();
- /** Resume watching for read only. */
- QPID_COMMON_EXTERN void rewatchRead();
-
- /** Resume watching for write only. */
- QPID_COMMON_EXTERN void rewatchWrite();
-
- /** Stop watching temporarily. The DispatchHandle remains
- associated with the poller and can be re-activated using
- rewatch. */
- QPID_COMMON_EXTERN void unwatch();
- /** Stop watching for read */
- QPID_COMMON_EXTERN void unwatchRead();
- /** Stop watching for write */
- QPID_COMMON_EXTERN void unwatchWrite();
-
- /** Stop watching permanently. Disassociates from the poller. */
- QPID_COMMON_EXTERN void stopWatch();
-
- /** Interrupt watching this handle and make a serialised callback that respects the
- * same exclusivity guarantees as the other callbacks
- */
- QPID_COMMON_EXTERN void call(Callback iCb);
-
-protected:
- QPID_COMMON_EXTERN void doDelete();
-
-private:
- QPID_COMMON_EXTERN void processEvent(Poller::EventType dir);
-};
-
-class DispatchHandleRef {
- DispatchHandle* ref;
-
-public:
- typedef boost::function1<void, DispatchHandle&> Callback;
- DispatchHandleRef(const IOHandle& h, Callback rCb, Callback wCb, Callback dCb) :
- ref(new DispatchHandle(h, rCb, wCb, dCb))
- {}
-
- ~DispatchHandleRef() { ref->doDelete(); }
-
- void startWatch(Poller::shared_ptr poller) { ref->startWatch(poller); }
- void rewatch() { ref->rewatch(); }
- void rewatchRead() { ref->rewatchRead(); }
- void rewatchWrite() { ref->rewatchWrite(); }
- void unwatch() { ref->unwatch(); }
- void unwatchRead() { ref->unwatchRead(); }
- void unwatchWrite() { ref->unwatchWrite(); }
- void stopWatch() { ref->stopWatch(); }
- void call(Callback iCb) { ref->call(iCb); }
-};
-
-}}
-
-#endif // _sys_DispatchHandle_h
diff --git a/cpp/src/qpid/sys/Dispatcher.cpp b/cpp/src/qpid/sys/Dispatcher.cpp
deleted file mode 100644
index 5f52dcd990..0000000000
--- a/cpp/src/qpid/sys/Dispatcher.cpp
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- *
- * 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/sys/Dispatcher.h"
-
-#include <assert.h>
-
-namespace qpid {
-namespace sys {
-
-Dispatcher::Dispatcher(Poller::shared_ptr poller0) :
- poller(poller0) {
-}
-
-Dispatcher::~Dispatcher() {
-}
-
-void Dispatcher::run() {
- poller->run();
-}
-
-}}
diff --git a/cpp/src/qpid/sys/Dispatcher.h b/cpp/src/qpid/sys/Dispatcher.h
deleted file mode 100644
index e8213d0579..0000000000
--- a/cpp/src/qpid/sys/Dispatcher.h
+++ /dev/null
@@ -1,44 +0,0 @@
-#ifndef _sys_Dispatcher_h
-#define _sys_Dispatcher_h
-
-/*
- *
- * 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/sys/Poller.h"
-#include "qpid/sys/Runnable.h"
-#include "qpid/CommonImportExport.h"
-
-namespace qpid {
-namespace sys {
-
-class Dispatcher : public Runnable {
- const Poller::shared_ptr poller;
-
-public:
- QPID_COMMON_EXTERN Dispatcher(Poller::shared_ptr poller);
- QPID_COMMON_EXTERN ~Dispatcher();
-
- QPID_COMMON_EXTERN void run();
-};
-
-}}
-
-#endif // _sys_Dispatcher_h
diff --git a/cpp/src/qpid/sys/FileSysDir.h b/cpp/src/qpid/sys/FileSysDir.h
deleted file mode 100755
index ffe7823f0a..0000000000
--- a/cpp/src/qpid/sys/FileSysDir.h
+++ /dev/null
@@ -1,62 +0,0 @@
-#ifndef QPID_SYS_FILESYSDIR_H
-#define QPID_SYS_FILESYSDIR_H
-
-/*
- * 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 <string>
-
-namespace qpid {
-namespace sys {
-
-/**
- * @class FileSysDir
- *
- * Represents a filesystem directory accessible from the local host.
- * This class simply checks existence of, and creates, a directory. It could
- * be added to later to list contents, etc.
- */
-class FileSysDir
-{
- const std::string dirPath;
-
- public:
-
- FileSysDir (std::string path) : dirPath(path) {}
- ~FileSysDir () {}
-
- /**
- * Check to see if the directory exists and is a directory. Throws an
- * exception if there is an error checking existence or if the path
- * exists but is not a directory.
- *
- * @retval true if the path exists and is a directory.
- * @retval false if the path does not exist.
- */
- bool exists (void) const;
-
- void mkdir(void);
-
- std::string getPath () { return dirPath; }
-};
-
-}} // namespace qpid::sys
-
-#endif /*!QPID_SYS_FILESYSDIR_H*/
diff --git a/cpp/src/qpid/sys/Fork.h b/cpp/src/qpid/sys/Fork.h
deleted file mode 100644
index 4ec061f7bc..0000000000
--- a/cpp/src/qpid/sys/Fork.h
+++ /dev/null
@@ -1,24 +0,0 @@
-#ifndef QPID_SYS_FORK_H
-#define QPID_SYS_FORK_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 "posix/Fork.h"
-
-#endif /*!QPID_SYS_FORK_H*/
diff --git a/cpp/src/qpid/sys/LockFile.h b/cpp/src/qpid/sys/LockFile.h
deleted file mode 100644
index 14a76cbf3e..0000000000
--- a/cpp/src/qpid/sys/LockFile.h
+++ /dev/null
@@ -1,64 +0,0 @@
-#ifndef _sys_LockFile_h
-#define _sys_LockFile_h
-
-/*
- *
- * Copyright (c) 2008 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/noncopyable.hpp>
-#include <boost/shared_ptr.hpp>
-#include <string>
-
-#include "qpid/CommonImportExport.h"
-#include "qpid/sys/IntegerTypes.h"
-
-namespace qpid {
-namespace sys {
-
-class LockFilePrivate;
-
-/**
- * @class LockFile
- *
- * LockFile represents a locked file suitable for a coarse-grain system
- * lock. For example, the broker uses this to ensure that only one broker
- * runs. A common usage idiom is to store the current "owner" process ID
- * in the lock file - if the lock file exists, but the stored process ID
- * doesn't, the old owner has probably died without cleaning up the lock
- * file.
- */
-class LockFile : private boost::noncopyable
-{
- std::string path;
- bool created;
- boost::shared_ptr<LockFilePrivate> impl;
-
-protected:
- int read(void*, size_t) const;
- int write(void*, size_t) const;
-
-public:
- QPID_COMMON_EXTERN LockFile(const std::string& path_, bool create);
- QPID_COMMON_EXTERN ~LockFile();
-};
-
-}} /* namespace qpid::sys */
-
-#endif /*!_sys_LockFile_h*/
-
-
-
diff --git a/cpp/src/qpid/sys/LockPtr.h b/cpp/src/qpid/sys/LockPtr.h
deleted file mode 100644
index 738a864317..0000000000
--- a/cpp/src/qpid/sys/LockPtr.h
+++ /dev/null
@@ -1,89 +0,0 @@
-#ifndef QPID_SYS_LOCKPTR_H
-#define QPID_SYS_LOCKPTR_H
-
-/*
- *
- * 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/sys/Mutex.h"
-#include <boost/noncopyable.hpp>
-
-namespace qpid {
-namespace sys {
-
-class Mutex;
-
-/**
- * LockPtr is a smart pointer to T. It is constructed from a volatile
- * T* and a Lock (by default a Mutex). It const_casts away the
- * volatile qualifier and locks the Lock for the duration of its
- *
- * Used in conjuntion with the "volatile" keyword to get the compiler
- * to help enforce correct concurrent use of mutli-threaded objects.
- * See ochttp://www.ddj.com/cpp/184403766 for a detailed discussion.
- *
- * To summarize the convention:
- * - Declare thread-safe member functions as volatile.
- * - Declare instances of the class that may be called concurrently as volatile.
- * - Use LockPtr to cast away the volatile qualifier while taking a lock.
- *
- * This means that code calling on a concurrently-used object
- * (declared volatile) can only call thread-safe (volatile) member
- * functions. Code that needs to use thread-unsafe members must use a
- * LockPtr, thereby acquiring the lock and making it safe to do so.
- *
- * A good type-safe pattern is the internally-locked object:
- * - It has it's own private lock member.
- * - All public functions are thread safe and declared volatile.
- * - Any thread-unsafe, non-volatile functions are private.
- * - Only member function implementations use LockPtr to access private functions.
- *
- * This encapsulates all the locking logic inside the class.
- *
- * One nice feature of this convention is the common case where you
- * need a public, locked version of some function foo() and also a
- * private unlocked version to avoid recursive locks. They can be declared as
- * volatile and non-volatile overloads of the same function:
- *
- * // public
- * void Thing::foo() volatile { LockPtr<Thing>(this, myLock)->foo(); }
- * // private
- * void Thing::foo() { ... do stuff ...}
- */
-
-template <class T, class Lock> class LockPtr : public boost::noncopyable {
- public:
- LockPtr(volatile T* p, Lock& l) : ptr(const_cast<T*>(p)), lock(l) { lock.lock(); }
- LockPtr(volatile T* p, volatile Lock& l) : ptr(const_cast<T*>(p)), lock(const_cast<Lock&>(l)) { lock.lock(); }
- ~LockPtr() { lock.unlock(); }
-
- T& operator*() { return *ptr; }
- T* operator->() { return ptr; }
-
- private:
- T* ptr;
- Lock& lock;
-};
-
-
-}} // namespace qpid::sys
-
-
-#endif /*!QPID_SYS_LOCKPTR_H*/
diff --git a/cpp/src/qpid/sys/OutputControl.h b/cpp/src/qpid/sys/OutputControl.h
deleted file mode 100644
index eae99beb0f..0000000000
--- a/cpp/src/qpid/sys/OutputControl.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- *
- * 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/sys/IntegerTypes.h"
-
-#ifndef _OutputControl_
-#define _OutputControl_
-
-namespace qpid {
-namespace sys {
-
- class OutputControl
- {
- public:
- virtual ~OutputControl() {}
- virtual void abort() = 0;
- virtual void activateOutput() = 0;
- virtual void giveReadCredit(int32_t credit) = 0;
- };
-
-}
-}
-
-
-#endif
diff --git a/cpp/src/qpid/sys/OutputTask.h b/cpp/src/qpid/sys/OutputTask.h
deleted file mode 100644
index fb08a63cd0..0000000000
--- a/cpp/src/qpid/sys/OutputTask.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- *
- * 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.
- *
- */
-#ifndef _OutputTask_
-#define _OutputTask_
-
-namespace qpid {
-namespace sys {
-
- class OutputTask
- {
- public:
- virtual ~OutputTask() {}
- /** Generate some output.
- *@return true if output was generated, false if there is no work to do.
- */
- virtual bool doOutput() = 0;
- };
-
-}
-}
-
-
-#endif
diff --git a/cpp/src/qpid/sys/PipeHandle.h b/cpp/src/qpid/sys/PipeHandle.h
deleted file mode 100755
index 8aac76996b..0000000000
--- a/cpp/src/qpid/sys/PipeHandle.h
+++ /dev/null
@@ -1,51 +0,0 @@
-#ifndef _sys_PipeHandle_h
-#define _sys_PipeHandle_h
-
-/*
-*
-* 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/sys/IntegerTypes.h"
-#include "qpid/CommonImportExport.h"
-#include <string>
-
-// This class is a portability wrapper around pipe fds.
-// It currently exists primarily and solely for the purpose of
-// integration with single-threaded components that require QMF
-// integration through a signalling fd.
-
-namespace qpid {
-namespace sys {
-
- class PipeHandle {
- private:
- int writeFd;
- int readFd;
- public:
- QPID_COMMON_EXTERN PipeHandle(bool nonBlocking=true);
- QPID_COMMON_EXTERN ~PipeHandle();
- QPID_COMMON_EXTERN int read(void* buf, size_t bufSize);
- QPID_COMMON_EXTERN int write(const void* buf, size_t bufSize);
- QPID_COMMON_EXTERN int getReadHandle();
- };
-
-}}
-
-#endif /*!_sys_PipeHandle_h*/
diff --git a/cpp/src/qpid/sys/PollableCondition.h b/cpp/src/qpid/sys/PollableCondition.h
deleted file mode 100644
index 2eb6f2d947..0000000000
--- a/cpp/src/qpid/sys/PollableCondition.h
+++ /dev/null
@@ -1,64 +0,0 @@
-#ifndef QPID_SYS_POLLABLECONDITION_H
-#define QPID_SYS_POLLABLECONDITION_H
-
-/*
- *
- * 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/sys/Poller.h"
-#include "qpid/CommonImportExport.h"
-#include <boost/function.hpp>
-#include <boost/shared_ptr.hpp>
-
-
-namespace qpid {
-namespace sys {
-
-class PollableConditionPrivate;
-
-class PollableCondition {
-public:
- typedef boost::function1<void, PollableCondition&> Callback;
-
- QPID_COMMON_EXTERN PollableCondition(const Callback& cb,
- const boost::shared_ptr<sys::Poller>& poller);
-
- QPID_COMMON_EXTERN ~PollableCondition();
-
- /**
- * Set the condition. Triggers callback to Callback from Poller.
- */
- QPID_COMMON_EXTERN void set();
-
- /**
- * Clear the condition. Stops callbacks from Poller.
- */
- QPID_COMMON_EXTERN void clear();
-
- private:
- PollableConditionPrivate *impl;
-
- Callback callback;
- boost::shared_ptr<sys::Poller> poller;
-};
-
-}} // namespace qpid::sys
-
-#endif /*!QPID_SYS_POLLABLECONDITION_H*/
diff --git a/cpp/src/qpid/sys/PollableQueue.h b/cpp/src/qpid/sys/PollableQueue.h
deleted file mode 100644
index 81c2301c1e..0000000000
--- a/cpp/src/qpid/sys/PollableQueue.h
+++ /dev/null
@@ -1,176 +0,0 @@
-#ifndef QPID_SYS_POLLABLEQUEUE_H
-#define QPID_SYS_POLLABLEQUEUE_H
-
-/*
- *
- * 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/sys/PollableCondition.h"
-#include "qpid/sys/Monitor.h"
-#include "qpid/sys/Thread.h"
-#include <boost/function.hpp>
-#include <boost/bind.hpp>
-#include <algorithm>
-#include <vector>
-
-namespace qpid {
-namespace sys {
-
-class Poller;
-
-/**
- * A queue whose item processing is dispatched by sys::Poller.
- * Any thread can push to the queue; items pushed trigger an event the Poller
- * recognizes. When a Poller I/O thread dispatches the event, a
- * user-specified callback is invoked with all items on the queue.
- */
-template <class T>
-class PollableQueue {
- public:
- typedef std::vector<T> Batch;
- typedef T value_type;
-
- /**
- * Callback to process a batch of items from the queue.
- *
- * @param batch Queue of values to process. Any items remaining
- * on return from Callback are put back on the queue.
- * @return iterator pointing to the first un-processed item in batch.
- * Items from this point up to batch.end() are put back on the queue.
- */
- typedef boost::function<typename Batch::const_iterator (const Batch& batch)> Callback;
-
- /**
- * Constructor; sets necessary parameters.
- *
- * @param cb Callback that will be called to process items on the
- * queue. Will be called from a Poller I/O thread.
- * @param poller Poller to use for dispatching queue events.
- */
- PollableQueue(const Callback& cb,
- const boost::shared_ptr<sys::Poller>& poller);
-
- ~PollableQueue();
-
- /** Push a value onto the queue. Thread safe */
- void push(const T& t);
-
- /** Start polling. */
- void start();
-
- /** Stop polling and wait for the current callback, if any, to complete. */
- void stop();
-
- /** Are we currently stopped?*/
- bool isStopped() const { ScopedLock l(lock); return stopped; }
-
- size_t size() { ScopedLock l(lock); return queue.size(); }
- bool empty() { ScopedLock l(lock); return queue.empty(); }
-
- /**
- * Allow any queued events to be processed; intended for calling
- * after all dispatch threads exit the Poller loop in order to
- * ensure clean shutdown with no events left on the queue.
- */
- void shutdown();
-
- private:
- typedef sys::Monitor::ScopedLock ScopedLock;
- typedef sys::Monitor::ScopedUnlock ScopedUnlock;
-
- void dispatch(PollableCondition& cond);
- void process();
-
- mutable sys::Monitor lock;
- Callback callback;
- PollableCondition condition;
- Batch queue, batch;
- Thread dispatcher;
- bool stopped;
-};
-
-template <class T> PollableQueue<T>::PollableQueue(
- const Callback& cb, const boost::shared_ptr<sys::Poller>& p)
- : callback(cb),
- condition(boost::bind(&PollableQueue<T>::dispatch, this, _1), p),
- stopped(true)
-{
-}
-
-template <class T> void PollableQueue<T>::start() {
- ScopedLock l(lock);
- if (!stopped) return;
- stopped = false;
- if (!queue.empty()) condition.set();
-}
-
-template <class T> PollableQueue<T>::~PollableQueue() {
-}
-
-template <class T> void PollableQueue<T>::push(const T& t) {
- ScopedLock l(lock);
- if (queue.empty() && !stopped) condition.set();
- queue.push_back(t);
-}
-
-template <class T> void PollableQueue<T>::dispatch(PollableCondition& cond) {
- ScopedLock l(lock);
- assert(!dispatcher);
- dispatcher = Thread::current();
- process();
- dispatcher = Thread();
- if (queue.empty()) cond.clear();
- if (stopped) lock.notifyAll();
-}
-
-template <class T> void PollableQueue<T>::process() {
- // Called with lock held
- while (!stopped && !queue.empty()) {
- assert(batch.empty());
- batch.swap(queue);
- typename Batch::const_iterator putBack;
- {
- ScopedUnlock u(lock); // Allow concurrent push to queue.
- putBack = callback(batch);
- }
- // put back unprocessed items.
- queue.insert(queue.begin(), putBack, typename Batch::const_iterator(batch.end()));
- batch.clear();
- }
-}
-
-template <class T> void PollableQueue<T>::shutdown() {
- ScopedLock l(lock);
- process();
-}
-
-template <class T> void PollableQueue<T>::stop() {
- ScopedLock l(lock);
- if (stopped) return;
- condition.clear();
- stopped = true;
- // Avoid deadlock if stop is called from the dispatch thread
- if (dispatcher && dispatcher != Thread::current())
- while (dispatcher) lock.wait();
-}
-
-}} // namespace qpid::sys
-
-#endif /*!QPID_SYS_POLLABLEQUEUE_H*/
diff --git a/cpp/src/qpid/sys/Poller.h b/cpp/src/qpid/sys/Poller.h
deleted file mode 100644
index 01ee139ee6..0000000000
--- a/cpp/src/qpid/sys/Poller.h
+++ /dev/null
@@ -1,135 +0,0 @@
-#ifndef _sys_Poller_h
-#define _sys_Poller_h
-
-/*
- *
- * 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/sys/Time.h"
-#include "qpid/sys/Runnable.h"
-#include "qpid/CommonImportExport.h"
-#include <boost/shared_ptr.hpp>
-
-namespace qpid {
-namespace sys {
-
-/**
- * Poller is an abstract base class that registers callbacks to be
- * called when there is IO activity. Concrete derived classes
- * implement polling APIs such as epoll or equivalents on other
- * operating systems.
- *
- * On the broker, Connection::received() is called with incoming
- * frames from clients, and Connection::doOutput() is called when a
- * connection is writeable.
- *
- * @see DispatchHandler for more details of normal use.
- */
-class PollerHandle;
-class PollerPrivate;
-class Poller : public Runnable {
- PollerPrivate* const impl;
-
-public:
- typedef boost::shared_ptr<Poller> shared_ptr;
-
- enum Direction {
- NONE = 0,
- INPUT,
- OUTPUT,
- INOUT
- };
-
- enum EventType {
- INVALID = 0,
- READABLE,
- WRITABLE,
- READ_WRITABLE,
- DISCONNECTED,
- SHUTDOWN,
- TIMEOUT,
- INTERRUPTED
- };
-
- struct Event {
- PollerHandle* handle;
- EventType type;
-
- Event(PollerHandle* handle0, EventType type0) :
- handle(handle0),
- type(type0) {
- }
-
- void process();
- };
-
- QPID_COMMON_EXTERN Poller();
- QPID_COMMON_EXTERN ~Poller();
- /** Note: this function is async-signal safe */
- QPID_COMMON_EXTERN void shutdown();
-
- // Interrupt waiting for a specific poller handle
- // returns true if we could interrupt the handle
- // - in this case on return the handle is no longer being monitored,
- // but we will receive an event from some invocation of poller::wait
- // with the handle and the INTERRUPTED event type
- // if it returns false then the handle is not being monitored by the poller
- // - This can either be because it has just received an event which has been
- // reported and has not been reenabled since.
- // - Because it was removed from the monitoring set
- // - Or because it is already being interrupted
- QPID_COMMON_EXTERN bool interrupt(PollerHandle& handle);
-
- // Poller run loop
- QPID_COMMON_EXTERN void run();
-
- QPID_COMMON_EXTERN void registerHandle(PollerHandle& handle);
- QPID_COMMON_EXTERN void unregisterHandle(PollerHandle& handle);
- QPID_COMMON_EXTERN void monitorHandle(PollerHandle& handle, Direction dir);
- QPID_COMMON_EXTERN void unmonitorHandle(PollerHandle& handle, Direction dir);
- QPID_COMMON_EXTERN Event wait(Duration timeout = TIME_INFINITE);
-
- QPID_COMMON_EXTERN bool hasShutdown();
-};
-
-/**
- * Handle class to use for polling
- */
-class IOHandle;
-class PollerHandlePrivate;
-class PollerHandle {
- friend class Poller;
- friend class PollerPrivate;
- friend struct Poller::Event;
-
- PollerHandlePrivate* const impl;
- QPID_COMMON_INLINE_EXTERN virtual void processEvent(Poller::EventType) {};
-
-public:
- QPID_COMMON_EXTERN PollerHandle(const IOHandle& h);
- QPID_COMMON_EXTERN virtual ~PollerHandle();
-};
-
-inline void Poller::Event::process() {
- handle->processEvent(type);
-}
-
-}}
-#endif // _sys_Poller_h
diff --git a/cpp/src/qpid/sys/ProtocolFactory.h b/cpp/src/qpid/sys/ProtocolFactory.h
deleted file mode 100644
index b233b2da1a..0000000000
--- a/cpp/src/qpid/sys/ProtocolFactory.h
+++ /dev/null
@@ -1,58 +0,0 @@
-#ifndef _sys_ProtocolFactory_h
-#define _sys_ProtocolFactory_h
-
-/*
- *
- * 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/sys/IntegerTypes.h"
-#include "qpid/SharedObject.h"
-#include "qpid/sys/ConnectionCodec.h"
-#include <boost/function.hpp>
-
-namespace qpid {
-namespace sys {
-
-class Poller;
-
-class ProtocolFactory : public qpid::SharedObject<ProtocolFactory>
-{
- public:
- typedef boost::function2<void, int, std::string> ConnectFailedCallback;
-
- virtual ~ProtocolFactory() = 0;
- virtual uint16_t getPort() const = 0;
- virtual std::string getHost() const = 0;
- virtual void accept(boost::shared_ptr<Poller>, ConnectionCodec::Factory*) = 0;
- virtual void connect(
- boost::shared_ptr<Poller>,
- const std::string& host, int16_t port,
- ConnectionCodec::Factory* codec,
- ConnectFailedCallback failed) = 0;
- virtual bool supports(const std::string& /*capability*/) { return false; }
-};
-
-inline ProtocolFactory::~ProtocolFactory() {}
-
-}}
-
-
-
-#endif //!_sys_ProtocolFactory_h
diff --git a/cpp/src/qpid/sys/RdmaIOPlugin.cpp b/cpp/src/qpid/sys/RdmaIOPlugin.cpp
deleted file mode 100644
index d53db20598..0000000000
--- a/cpp/src/qpid/sys/RdmaIOPlugin.cpp
+++ /dev/null
@@ -1,406 +0,0 @@
-/*
- *
- * 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/sys/ProtocolFactory.h"
-
-#include "qpid/Plugin.h"
-#include "qpid/broker/Broker.h"
-#include "qpid/framing/AMQP_HighestVersion.h"
-#include "qpid/log/Statement.h"
-#include "qpid/sys/rdma/RdmaIO.h"
-#include "qpid/sys/rdma/rdma_exception.h"
-#include "qpid/sys/OutputControl.h"
-#include "qpid/sys/SecuritySettings.h"
-
-#include <boost/bind.hpp>
-#include <boost/lexical_cast.hpp>
-#include <memory>
-
-#include <netdb.h>
-
-using std::auto_ptr;
-using std::string;
-using std::stringstream;
-
-namespace qpid {
-namespace sys {
-
-class RdmaIOHandler : public OutputControl {
- std::string identifier;
- ConnectionCodec::Factory* factory;
- ConnectionCodec* codec;
- bool readError;
-
- sys::Mutex pollingLock;
- bool polling;
-
- Rdma::AsynchIO* aio;
- Rdma::Connection::intrusive_ptr connection;
-
- void write(const framing::ProtocolInitiation&);
- void disconnectAction();
-
- public:
- RdmaIOHandler(Rdma::Connection::intrusive_ptr c, ConnectionCodec::Factory* f);
- ~RdmaIOHandler();
- void init(Rdma::AsynchIO* a);
- void start(Poller::shared_ptr poller);
-
- // Output side
- void close();
- void abort();
- void activateOutput();
- void giveReadCredit(int32_t credit);
- void initProtocolOut();
-
- // Input side
- void readbuff(Rdma::AsynchIO& aio, Rdma::Buffer* buff);
- void initProtocolIn(Rdma::Buffer* buff);
-
- // Notifications
- void full(Rdma::AsynchIO& aio);
- void idle(Rdma::AsynchIO& aio);
- void error(Rdma::AsynchIO& aio);
- void disconnected();
- void drained();
-};
-
-RdmaIOHandler::RdmaIOHandler(Rdma::Connection::intrusive_ptr c, qpid::sys::ConnectionCodec::Factory* f) :
- identifier(c->getFullName()),
- factory(f),
- codec(0),
- readError(false),
- polling(false),
- connection(c)
-{
-}
-
-RdmaIOHandler::~RdmaIOHandler() {
- if (codec)
- codec->closed();
- delete codec;
- delete aio;
-}
-
-void RdmaIOHandler::init(Rdma::AsynchIO* a) {
- aio = a;
-}
-
-void RdmaIOHandler::start(Poller::shared_ptr poller) {
- Mutex::ScopedLock l(pollingLock);
- assert(!polling);
-
- polling = true;
-
- aio->start(poller);
-}
-
-void RdmaIOHandler::write(const framing::ProtocolInitiation& data)
-{
- QPID_LOG(debug, "Rdma: SENT [" << identifier << "] INIT(" << data << ")");
- Rdma::Buffer* buff = aio->getSendBuffer();
- assert(buff);
- framing::Buffer out(buff->bytes(), buff->byteCount());
- data.encode(out);
- buff->dataCount(data.encodedSize());
- aio->queueWrite(buff);
-}
-
-void RdmaIOHandler::close() {
- aio->drainWriteQueue(boost::bind(&RdmaIOHandler::drained, this));
-}
-
-// TODO: Dummy implementation, need to fill this in for heartbeat timeout to work
-void RdmaIOHandler::abort() {
-}
-
-void RdmaIOHandler::activateOutput() {
- aio->notifyPendingWrite();
-}
-
-void RdmaIOHandler::idle(Rdma::AsynchIO&) {
- // TODO: Shouldn't need this test as idle() should only ever be called when
- // the connection is writable anyway
- if ( !aio->writable() ) {
- return;
- }
- if (codec == 0) return;
- if (!codec->canEncode()) {
- return;
- }
- Rdma::Buffer* buff = aio->getSendBuffer();
- if (buff) {
- size_t encoded=codec->encode(buff->bytes(), buff->byteCount());
- buff->dataCount(encoded);
- aio->queueWrite(buff);
- if (codec->isClosed()) {
- close();
- }
- }
-}
-
-void RdmaIOHandler::initProtocolOut() {
- // We mustn't have already started the conversation
- // but we must be able to send
- assert( codec == 0 );
- assert( aio->writable() );
- codec = factory->create(*this, identifier, SecuritySettings());
- write(framing::ProtocolInitiation(codec->getVersion()));
-}
-
-void RdmaIOHandler::error(Rdma::AsynchIO&) {
- disconnected();
-}
-
-namespace {
- void stopped(RdmaIOHandler* async) {
- delete async;
- }
-}
-
-void RdmaIOHandler::disconnectAction() {
- {
- Mutex::ScopedLock l(pollingLock);
- // If we're closed already then we'll get to drained() anyway
- if (!polling) return;
- polling = false;
- }
- aio->stop(boost::bind(&stopped, this));
-}
-
-void RdmaIOHandler::disconnected() {
- aio->requestCallback(boost::bind(&RdmaIOHandler::disconnectAction, this));
-}
-
-void RdmaIOHandler::drained() {
- // We know we've drained the write queue now, but we don't have to do anything
- // because we can rely on the client to disconnect to trigger the connection
- // cleanup.
-}
-
-void RdmaIOHandler::full(Rdma::AsynchIO&) {
- QPID_LOG(debug, "Rdma: buffer full [" << identifier << "]");
-}
-
-// TODO: Dummy implementation of read throttling
-void RdmaIOHandler::giveReadCredit(int32_t) {
-}
-
-// The logic here is subtly different from TCP as RDMA is message oriented
-// so we define that an RDMA message is a frame - in this case there is no putting back
-// of any message remainder - there shouldn't be any. And what we read here can't be
-// smaller than a frame
-void RdmaIOHandler::readbuff(Rdma::AsynchIO&, Rdma::Buffer* buff) {
- if (readError) {
- return;
- }
- size_t decoded = 0;
- try {
- if (codec) {
- decoded = codec->decode(buff->bytes(), buff->dataCount());
- }else{
- // Need to start protocol processing
- initProtocolIn(buff);
- }
- }catch(const std::exception& e){
- QPID_LOG(error, e.what());
- readError = true;
- close();
- }
-}
-
-void RdmaIOHandler::initProtocolIn(Rdma::Buffer* buff) {
- framing::Buffer in(buff->bytes(), buff->dataCount());
- framing::ProtocolInitiation protocolInit;
- size_t decoded = 0;
- if (protocolInit.decode(in)) {
- decoded = in.getPosition();
- QPID_LOG(debug, "Rdma: RECV [" << identifier << "] INIT(" << protocolInit << ")");
-
- codec = factory->create(protocolInit.getVersion(), *this, identifier, SecuritySettings());
-
- // If we failed to create the codec then we don't understand the offered protocol version
- if (!codec) {
- // send valid version header & close connection.
- write(framing::ProtocolInitiation(framing::highestProtocolVersion));
- readError = true;
- close();
- }
- }
-}
-
-class RdmaIOProtocolFactory : public ProtocolFactory {
- auto_ptr<Rdma::Listener> listener;
- const uint16_t listeningPort;
-
- public:
- RdmaIOProtocolFactory(int16_t port, int backlog);
- void accept(Poller::shared_ptr, ConnectionCodec::Factory*);
- void connect(Poller::shared_ptr, const string& host, int16_t port, ConnectionCodec::Factory*, ConnectFailedCallback);
-
- uint16_t getPort() const;
- string getHost() const;
-
- private:
- bool request(Rdma::Connection::intrusive_ptr, const Rdma::ConnectionParams&, ConnectionCodec::Factory*);
- void established(Poller::shared_ptr, Rdma::Connection::intrusive_ptr);
- void connected(Poller::shared_ptr, Rdma::Connection::intrusive_ptr, const Rdma::ConnectionParams&, ConnectionCodec::Factory*);
- void connectionError(Rdma::Connection::intrusive_ptr, Rdma::ErrorType);
- void disconnected(Rdma::Connection::intrusive_ptr);
- void rejected(Rdma::Connection::intrusive_ptr, const Rdma::ConnectionParams&, ConnectFailedCallback);
-};
-
-// Static instance to initialise plugin
-static class RdmaIOPlugin : public Plugin {
- void earlyInitialize(Target&) {
- }
-
- void initialize(Target& target) {
- // Check whether we actually have any rdma devices
- if ( Rdma::deviceCount() == 0 ) {
- QPID_LOG(info, "Rdma: Disabled: no rdma devices found");
- return;
- }
-
- broker::Broker* broker = dynamic_cast<broker::Broker*>(&target);
- // Only provide to a Broker
- if (broker) {
- const broker::Broker::Options& opts = broker->getOptions();
- ProtocolFactory::shared_ptr protocol(new RdmaIOProtocolFactory(opts.port, opts.connectionBacklog));
- QPID_LOG(notice, "Rdma: Listening on RDMA port " << protocol->getPort());
- broker->registerProtocolFactory("rdma", protocol);
- }
- }
-} rdmaPlugin;
-
-RdmaIOProtocolFactory::RdmaIOProtocolFactory(int16_t port, int /*backlog*/) :
- listeningPort(port)
-{}
-
-void RdmaIOProtocolFactory::established(Poller::shared_ptr poller, Rdma::Connection::intrusive_ptr ci) {
- RdmaIOHandler* async = ci->getContext<RdmaIOHandler>();
- async->start(poller);
-}
-
-bool RdmaIOProtocolFactory::request(Rdma::Connection::intrusive_ptr ci, const Rdma::ConnectionParams& cp,
- ConnectionCodec::Factory* f) {
- try {
- if (cp.rdmaProtocolVersion == 0) {
- QPID_LOG(warning, "Rdma: connection from protocol version 0 client");
- }
- RdmaIOHandler* async = new RdmaIOHandler(ci, f);
- Rdma::AsynchIO* aio =
- new Rdma::AsynchIO(ci->getQueuePair(),
- cp.rdmaProtocolVersion,
- cp.maxRecvBufferSize, cp.initialXmitCredit, Rdma::DEFAULT_WR_ENTRIES,
- boost::bind(&RdmaIOHandler::readbuff, async, _1, _2),
- boost::bind(&RdmaIOHandler::idle, async, _1),
- 0, // boost::bind(&RdmaIOHandler::full, async, _1),
- boost::bind(&RdmaIOHandler::error, async, _1));
- async->init(aio);
-
- // Record aio so we can get it back from a connection
- ci->addContext(async);
- return true;
- } catch (const Rdma::Exception& e) {
- QPID_LOG(error, "Rdma: Cannot accept new connection (Rdma exception): " << e.what());
- } catch (const std::exception& e) {
- QPID_LOG(error, "Rdma: Cannot accept new connection (unknown exception): " << e.what());
- }
-
- // If we get here we caught an exception so reject connection
- return false;
-}
-
-void RdmaIOProtocolFactory::connectionError(Rdma::Connection::intrusive_ptr, Rdma::ErrorType) {
-}
-
-void RdmaIOProtocolFactory::disconnected(Rdma::Connection::intrusive_ptr ci) {
- // If we've got a connection already tear it down, otherwise ignore
- RdmaIOHandler* async = ci->getContext<RdmaIOHandler>();
- if (async) {
- // Make sure we don't disconnect more than once
- ci->removeContext();
- async->disconnected();
- }
-}
-
-uint16_t RdmaIOProtocolFactory::getPort() const {
- return listeningPort; // Immutable no need for lock.
-}
-
-string RdmaIOProtocolFactory::getHost() const {
- //return listener.getSockname();
- return "";
-}
-
-void RdmaIOProtocolFactory::accept(Poller::shared_ptr poller, ConnectionCodec::Factory* fact) {
- ::sockaddr_in sin;
-
- sin.sin_family = AF_INET;
- sin.sin_port = htons(listeningPort);
- sin.sin_addr.s_addr = INADDR_ANY;
-
- listener.reset(
- new Rdma::Listener(
- Rdma::ConnectionParams(65536, Rdma::DEFAULT_WR_ENTRIES),
- boost::bind(&RdmaIOProtocolFactory::established, this, poller, _1),
- boost::bind(&RdmaIOProtocolFactory::connectionError, this, _1, _2),
- boost::bind(&RdmaIOProtocolFactory::disconnected, this, _1),
- boost::bind(&RdmaIOProtocolFactory::request, this, _1, _2, fact)));
-
- SocketAddress sa("",boost::lexical_cast<std::string>(listeningPort));
- listener->start(poller, sa);
-}
-
-// Only used for outgoing connections (in federation)
-void RdmaIOProtocolFactory::rejected(Rdma::Connection::intrusive_ptr, const Rdma::ConnectionParams&, ConnectFailedCallback failed) {
- failed(-1, "Connection rejected");
-}
-
-// Do the same as connection request and established but mark a client too
-void RdmaIOProtocolFactory::connected(Poller::shared_ptr poller, Rdma::Connection::intrusive_ptr ci, const Rdma::ConnectionParams& cp,
- ConnectionCodec::Factory* f) {
- (void) request(ci, cp, f);
- established(poller, ci);
- RdmaIOHandler* async = ci->getContext<RdmaIOHandler>();
- async->initProtocolOut();
-}
-
-void RdmaIOProtocolFactory::connect(
- Poller::shared_ptr poller,
- const std::string& host, int16_t port,
- ConnectionCodec::Factory* f,
- ConnectFailedCallback failed)
-{
- Rdma::Connector* c =
- new Rdma::Connector(
- Rdma::ConnectionParams(8000, Rdma::DEFAULT_WR_ENTRIES),
- boost::bind(&RdmaIOProtocolFactory::connected, this, poller, _1, _2, f),
- boost::bind(&RdmaIOProtocolFactory::connectionError, this, _1, _2),
- boost::bind(&RdmaIOProtocolFactory::disconnected, this, _1),
- boost::bind(&RdmaIOProtocolFactory::rejected, this, _1, _2, failed));
-
- SocketAddress sa(host, boost::lexical_cast<std::string>(port));
- c->start(poller, sa);
-}
-
-}} // namespace qpid::sys
diff --git a/cpp/src/qpid/sys/Runnable.cpp b/cpp/src/qpid/sys/Runnable.cpp
deleted file mode 100644
index 325d87c91b..0000000000
--- a/cpp/src/qpid/sys/Runnable.cpp
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- *
- * 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/sys/Runnable.h"
-#include <boost/bind.hpp>
-
-namespace qpid {
-namespace sys {
-
-Runnable::~Runnable() {}
-
-Runnable::Functor Runnable::functor()
-{
- return boost::bind(&Runnable::run, this);
-}
-
-}}
diff --git a/cpp/src/qpid/sys/ScopedIncrement.h b/cpp/src/qpid/sys/ScopedIncrement.h
deleted file mode 100644
index 8645ab2484..0000000000
--- a/cpp/src/qpid/sys/ScopedIncrement.h
+++ /dev/null
@@ -1,67 +0,0 @@
-#ifndef _posix_ScopedIncrement_h
-#define _posix_ScopedIncrement_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/noncopyable.hpp>
-#include <boost/function.hpp>
-
-namespace qpid {
-namespace sys {
-
-/**
- * Increment counter in constructor and decrement in destructor.
- * Optionally call a function if the decremented counter value is 0.
- * Note the function must not throw, it is called in the destructor.
- */
-template <class T, class F=boost::function<void()> >
-class ScopedIncrement : boost::noncopyable
-{
- public:
- ScopedIncrement(T& c, F f=0)
- : count(c), callback(f) { ++count; }
- ~ScopedIncrement() { if (--count == 0 && callback) callback(); }
-
- private:
- T& count;
- F callback;
-};
-
-
-/** Decrement counter in constructor and increment in destructor. */
-template <class T>
-class ScopedDecrement : boost::noncopyable
-{
- public:
- ScopedDecrement(T& c) : count(c) { value = --count; }
- ~ScopedDecrement() { ++count; }
-
- /** Return the value after the decrement. */
- operator long() { return value; }
-
- private:
- T& count;
- long value;
-};
-
-
-}}
-
-
-#endif // _posix_ScopedIncrement_h
diff --git a/cpp/src/qpid/sys/SecurityLayer.h b/cpp/src/qpid/sys/SecurityLayer.h
deleted file mode 100644
index 52bc40e352..0000000000
--- a/cpp/src/qpid/sys/SecurityLayer.h
+++ /dev/null
@@ -1,42 +0,0 @@
-#ifndef QPID_SYS_SECURITYLAYER_H
-#define QPID_SYS_SECURITYLAYER_H
-
-/*
- *
- * 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/sys/Codec.h"
-
-namespace qpid {
-namespace sys {
-
-/**
- * Defines interface to a SASL negotiated Security Layer (for
- * encryption/integrity)
- */
-class SecurityLayer : public Codec
-{
- public:
- virtual void init(Codec*) = 0;
- virtual ~SecurityLayer() {}
-};
-
-}} // namespace qpid::sys
-
-#endif /*!QPID_SYS_SECURITYLAYER_H*/
diff --git a/cpp/src/qpid/sys/SecuritySettings.h b/cpp/src/qpid/sys/SecuritySettings.h
deleted file mode 100644
index bfcd08fd0f..0000000000
--- a/cpp/src/qpid/sys/SecuritySettings.h
+++ /dev/null
@@ -1,58 +0,0 @@
-#ifndef QPID_SYS_SECURITYSETTINGS_H
-#define QPID_SYS_SECURITYSETTINGS_H
-
-/*
- *
- * 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.
- *
- */
-namespace qpid {
-namespace sys {
-
-/**
- * Conveys security information from a given transport to the upper
- * layers.
- */
-struct SecuritySettings
-{
- /**
- * Security Strength Factor (SSF). Possible values are:
- *
- * @li 0 No security
- * @li 1 Integrity checking only
- * @li >1 Integrity and confidentiality with the number
- * giving the encryption key length.
- */
- unsigned int ssf;
- /**
- * An authorisation id
- */
- std::string authid;
-
- /**
- * Disables SASL mechanisms that are vulnerable to passive
- * dictionary-based password attacks
- */
- bool nodict;
-
- SecuritySettings() : ssf(0), nodict(false) {}
-};
-
-}} // namespace qpid::sys
-
-#endif /*!QPID_SYS_SECURITYSETTINGS_H*/
diff --git a/cpp/src/qpid/sys/Semaphore.h b/cpp/src/qpid/sys/Semaphore.h
deleted file mode 100644
index 9d70f89aeb..0000000000
--- a/cpp/src/qpid/sys/Semaphore.h
+++ /dev/null
@@ -1,79 +0,0 @@
-#ifndef _sys_Semaphore_h
-#define _sys_Semaphore_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/sys/Monitor.h"
-
-namespace qpid {
-namespace sys {
-
-class Semaphore
-{
-public:
- Semaphore(uint c = 1) : count(c) {}
-
- void lock() { acquire(); }
- void unlock() { release(); }
- bool trylock() { return tryAcquire(); }
-
- bool tryAcquire()
- {
- Monitor::ScopedLock l(monitor);
- if (count) {
- count--;
- return true;
- } else {
- return false;
- }
- }
-
- void acquire()
- {
- Monitor::ScopedLock l(monitor);
- while (count == 0) monitor.wait();
- count--;
- }
-
- void release(uint n)
- {
- Monitor::ScopedLock l(monitor);
- if (count==0) monitor.notifyAll();
- count+=n;
- }
-
- void release()
- {
- release(1);
- }
-
- void forceLock()
- {
- Monitor::ScopedLock l(monitor);
- count = 0;
- }
-
-private:
- Monitor monitor;
- uint count;
-};
-
-}}
-
-#endif /*!_sys_Semaphore_h*/
diff --git a/cpp/src/qpid/sys/Shlib.cpp b/cpp/src/qpid/sys/Shlib.cpp
deleted file mode 100644
index 342d726876..0000000000
--- a/cpp/src/qpid/sys/Shlib.cpp
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * 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/sys/Shlib.h"
-
-#include "qpid/log/Statement.h"
-
-namespace qpid {
-namespace sys {
-
-AutoShlib::~AutoShlib() throw() {
- try {
- unload();
- } catch(const std::exception& e) {
- QPID_LOG(error, "Unloading shared library: " << e.what());
- }
-}
-
-// Note: Other functions are defined in apr/Shlib.cpp or posix/Shlib.cpp.
-
-}} // namespace qpid::sys
diff --git a/cpp/src/qpid/sys/Shlib.h b/cpp/src/qpid/sys/Shlib.h
deleted file mode 100644
index 7f66cfec14..0000000000
--- a/cpp/src/qpid/sys/Shlib.h
+++ /dev/null
@@ -1,76 +0,0 @@
-#ifndef QPID_SYS_SHLIB_H
-#define QPID_SYS_SHLIB_H
-
-/*
- *
- * 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/CommonImportExport.h"
-#include <boost/noncopyable.hpp>
-#include <iostream>
-
-namespace qpid {
-namespace sys {
-
-/** Encapsulates a shared library handle.
- *@see AutoShlib
- */
-class Shlib {
- public:
- /** Load a shared library */
- Shlib(const char* libname) { load(libname); }
-
- /** Load a shared library */
- Shlib(const std::string& libname) { load(libname.c_str()); }
-
- /** Unload shared library. */
- QPID_COMMON_EXTERN void unload();
-
- /** Look up symbol. */
- QPID_COMMON_EXTERN void* getSymbol(const char* symbol);
-
- /** Look up symbol in shared library, cast it to the desired
- * pointer type, void* by default.
- */
- template <class T>
- T getSymbol(const char* symbol) {
- // Double cast avoids warning about casting object to function pointer
- return reinterpret_cast<T>(reinterpret_cast<intptr_t>(
- this->getSymbol(symbol)));
- }
-
- private:
- void* handle;
- QPID_COMMON_EXTERN void load(const char* libname);
-};
-
-/** A shared library handle that unloads the shlib in it's dtor */
-class AutoShlib : public Shlib {
- public:
- /** Load shared library */
- AutoShlib(const std::string& libname) : Shlib(libname) {}
- /** Calls unload() */
- QPID_COMMON_EXTERN ~AutoShlib() throw();
-};
-
-
-}} // namespace qpid::sys
-
-#endif /*!QPID_SYS_SHLIB_H*/
diff --git a/cpp/src/qpid/sys/ShutdownHandler.h b/cpp/src/qpid/sys/ShutdownHandler.h
deleted file mode 100644
index 88baecb5b6..0000000000
--- a/cpp/src/qpid/sys/ShutdownHandler.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- *
- * 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.
- *
- */
-#ifndef _ShutdownHandler_
-#define _ShutdownHandler_
-
-namespace qpid {
-namespace sys {
-
- class ShutdownHandler
- {
- public:
- virtual void shutdown() = 0;
- virtual ~ShutdownHandler(){}
- };
-
-}
-}
-
-#endif
diff --git a/cpp/src/qpid/sys/Socket.h b/cpp/src/qpid/sys/Socket.h
deleted file mode 100644
index b1cded1aa1..0000000000
--- a/cpp/src/qpid/sys/Socket.h
+++ /dev/null
@@ -1,118 +0,0 @@
-#ifndef _sys_Socket_h
-#define _sys_Socket_h
-
-/*
- *
- * 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/sys/IOHandle.h"
-#include "qpid/sys/IntegerTypes.h"
-#include "qpid/CommonImportExport.h"
-#include <string>
-
-namespace qpid {
-namespace sys {
-
-class Duration;
-class SocketAddress;
-
-class QPID_COMMON_CLASS_EXTERN Socket : public IOHandle
-{
-public:
- /** Create a socket wrapper for descriptor. */
- QPID_COMMON_EXTERN Socket();
-
- /** Set timeout for read and write */
- void setTimeout(const Duration& interval) const;
-
- /** Set socket non blocking */
- void setNonblocking() const;
-
- QPID_COMMON_EXTERN void setTcpNoDelay() const;
-
- QPID_COMMON_EXTERN void connect(const std::string& host, uint16_t port) const;
- QPID_COMMON_EXTERN void connect(const SocketAddress&) const;
-
- QPID_COMMON_EXTERN void close() const;
-
- /** 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.
- */
- QPID_COMMON_EXTERN int listen(uint16_t port = 0, int backlog = 10) const;
- QPID_COMMON_EXTERN int listen(const SocketAddress&, int backlog = 10) const;
-
- /** Returns the "socket name" ie the address bound to
- * the near end of the socket
- */
- QPID_COMMON_EXTERN std::string getSockname() const;
-
- /** Returns the "peer name" ie the address bound to
- * the remote end of the socket
- */
- std::string getPeername() const;
-
- /**
- * Returns an address (host and port) for the remote end of the
- * socket
- */
- QPID_COMMON_EXTERN std::string getPeerAddress() const;
- /**
- * Returns an address (host and port) for the local end of the
- * socket
- */
- QPID_COMMON_EXTERN std::string getLocalAddress() const;
-
- /**
- * Returns the full address of the connection: local and remote host and port.
- */
- QPID_COMMON_INLINE_EXTERN std::string getFullAddress() const { return getLocalAddress()+"-"+getPeerAddress(); }
-
- QPID_COMMON_EXTERN uint16_t getLocalPort() const;
- uint16_t getRemotePort() const;
-
- /**
- * Returns the error code stored in the socket. This may be used
- * to determine the result of a non-blocking connect.
- */
- int getError() const;
-
- /** Accept a connection from a socket that is already listening
- * and has an incoming connection
- */
- QPID_COMMON_EXTERN Socket* accept() const;
-
- // TODO The following are raw operations, maybe they need better wrapping?
- QPID_COMMON_EXTERN int read(void *buf, size_t count) const;
- QPID_COMMON_EXTERN int write(const void *buf, size_t count) const;
-
-private:
- /** Create socket */
- void createSocket(const SocketAddress&) const;
-
- Socket(IOHandlePrivate*);
- mutable std::string connectname;
- mutable bool nonblocking;
- mutable bool nodelay;
-};
-
-}}
-#endif /*!_sys_Socket_h*/
diff --git a/cpp/src/qpid/sys/SocketAddress.h b/cpp/src/qpid/sys/SocketAddress.h
deleted file mode 100644
index 27b9642f2c..0000000000
--- a/cpp/src/qpid/sys/SocketAddress.h
+++ /dev/null
@@ -1,53 +0,0 @@
-#ifndef _sys_SocketAddress_h
-#define _sys_SocketAddress_h
-
-/*
- *
- * 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/sys/IntegerTypes.h"
-#include "qpid/CommonImportExport.h"
-#include <string>
-
-struct addrinfo;
-
-namespace qpid {
-namespace sys {
-
-class SocketAddress {
- friend const ::addrinfo& getAddrInfo(const SocketAddress&);
-
-public:
- /** Create a SocketAddress from hostname and port*/
- QPID_COMMON_EXTERN SocketAddress(const std::string& host, const std::string& port);
- QPID_COMMON_EXTERN SocketAddress(const SocketAddress&);
- QPID_COMMON_EXTERN SocketAddress& operator=(const SocketAddress&);
- QPID_COMMON_EXTERN ~SocketAddress();
-
- std::string asString() const;
-
-private:
- std::string host;
- std::string port;
- mutable ::addrinfo* addrInfo;
-};
-
-}}
-#endif /*!_sys_SocketAddress_h*/
diff --git a/cpp/src/qpid/sys/SslPlugin.cpp b/cpp/src/qpid/sys/SslPlugin.cpp
deleted file mode 100644
index 0ec051caab..0000000000
--- a/cpp/src/qpid/sys/SslPlugin.cpp
+++ /dev/null
@@ -1,191 +0,0 @@
-/*
- *
- * 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/sys/ProtocolFactory.h"
-
-#include "qpid/Plugin.h"
-#include "qpid/sys/ssl/check.h"
-#include "qpid/sys/ssl/util.h"
-#include "qpid/sys/ssl/SslHandler.h"
-#include "qpid/sys/ssl/SslIo.h"
-#include "qpid/sys/ssl/SslSocket.h"
-#include "qpid/broker/Broker.h"
-#include "qpid/log/Statement.h"
-
-#include <boost/bind.hpp>
-#include <memory>
-
-
-namespace qpid {
-namespace sys {
-
-struct SslServerOptions : ssl::SslOptions
-{
- uint16_t port;
- bool clientAuth;
- bool nodict;
-
- SslServerOptions() : port(5671),
- clientAuth(false),
- nodict(false)
- {
- addOptions()
- ("ssl-port", optValue(port, "PORT"), "Port on which to listen for SSL connections")
- ("ssl-require-client-authentication", optValue(clientAuth),
- "Forces clients to authenticate in order to establish an SSL connection")
- ("ssl-sasl-no-dict", optValue(nodict),
- "Disables SASL mechanisms that are vulnerable to passive dictionary-based password attacks");
- }
-};
-
-class SslProtocolFactory : public ProtocolFactory {
- const bool tcpNoDelay;
- qpid::sys::ssl::SslSocket listener;
- const uint16_t listeningPort;
- std::auto_ptr<qpid::sys::ssl::SslAcceptor> acceptor;
- bool nodict;
-
- public:
- SslProtocolFactory(const SslServerOptions&, int backlog, bool nodelay);
- void accept(Poller::shared_ptr, ConnectionCodec::Factory*);
- void connect(Poller::shared_ptr, const std::string& host, int16_t port,
- ConnectionCodec::Factory*,
- boost::function2<void, int, std::string> failed);
-
- uint16_t getPort() const;
- std::string getHost() const;
- bool supports(const std::string& capability);
-
- private:
- void established(Poller::shared_ptr, const qpid::sys::ssl::SslSocket&, ConnectionCodec::Factory*,
- bool isClient);
-};
-
-// Static instance to initialise plugin
-static struct SslPlugin : public Plugin {
- SslServerOptions options;
-
- Options* getOptions() { return &options; }
-
- ~SslPlugin() { ssl::shutdownNSS(); }
-
- void earlyInitialize(Target&) {
- }
-
- void initialize(Target& target) {
- broker::Broker* broker = dynamic_cast<broker::Broker*>(&target);
- // Only provide to a Broker
- if (broker) {
- if (options.certDbPath.empty()) {
- QPID_LOG(notice, "SSL plugin not enabled, you must set --ssl-cert-db to enable it.");
- } else {
- try {
- ssl::initNSS(options, true);
-
- const broker::Broker::Options& opts = broker->getOptions();
- ProtocolFactory::shared_ptr protocol(new SslProtocolFactory(options,
- opts.connectionBacklog,
- opts.tcpNoDelay));
- QPID_LOG(notice, "Listening for SSL connections on TCP port " << protocol->getPort());
- broker->registerProtocolFactory("ssl", protocol);
- } catch (const std::exception& e) {
- QPID_LOG(error, "Failed to initialise SSL plugin: " << e.what());
- }
- }
- }
- }
-} sslPlugin;
-
-SslProtocolFactory::SslProtocolFactory(const SslServerOptions& options, int backlog, bool nodelay) :
- tcpNoDelay(nodelay), listeningPort(listener.listen(options.port, backlog, options.certName, options.clientAuth)),
- nodict(options.nodict)
-{}
-
-void SslProtocolFactory::established(Poller::shared_ptr poller, const qpid::sys::ssl::SslSocket& s,
- ConnectionCodec::Factory* f, bool isClient) {
- qpid::sys::ssl::SslHandler* async = new qpid::sys::ssl::SslHandler(s.getFullAddress(), f, nodict);
-
- if (tcpNoDelay) {
- s.setTcpNoDelay(tcpNoDelay);
- QPID_LOG(info, "Set TCP_NODELAY on connection to " << s.getPeerAddress());
- }
-
- if (isClient)
- async->setClient();
- qpid::sys::ssl::SslIO* aio = new qpid::sys::ssl::SslIO(s,
- boost::bind(&qpid::sys::ssl::SslHandler::readbuff, async, _1, _2),
- boost::bind(&qpid::sys::ssl::SslHandler::eof, async, _1),
- boost::bind(&qpid::sys::ssl::SslHandler::disconnect, async, _1),
- boost::bind(&qpid::sys::ssl::SslHandler::closedSocket, async, _1, _2),
- boost::bind(&qpid::sys::ssl::SslHandler::nobuffs, async, _1),
- boost::bind(&qpid::sys::ssl::SslHandler::idle, async, _1));
-
- async->init(aio, 4);
- aio->start(poller);
-}
-
-uint16_t SslProtocolFactory::getPort() const {
- return listeningPort; // Immutable no need for lock.
-}
-
-std::string SslProtocolFactory::getHost() const {
- return listener.getSockname();
-}
-
-void SslProtocolFactory::accept(Poller::shared_ptr poller,
- ConnectionCodec::Factory* fact) {
- acceptor.reset(
- new qpid::sys::ssl::SslAcceptor(listener,
- boost::bind(&SslProtocolFactory::established, this, poller, _1, fact, false)));
- acceptor->start(poller);
-}
-
-void SslProtocolFactory::connect(
- Poller::shared_ptr poller,
- const std::string& host, int16_t port,
- ConnectionCodec::Factory* fact,
- ConnectFailedCallback failed)
-{
- // Note that the following logic does not cause a memory leak.
- // The allocated Socket is freed either by the SslConnector
- // upon connection failure or by the SslIoHandle upon connection
- // shutdown. The allocated SslConnector frees itself when it
- // is no longer needed.
-
- qpid::sys::ssl::SslSocket* socket = new qpid::sys::ssl::SslSocket();
- new qpid::sys::ssl::SslConnector (*socket, poller, host, port,
- boost::bind(&SslProtocolFactory::established, this, poller, _1, fact, true),
- failed);
-}
-
-namespace
-{
-const std::string SSL = "ssl";
-}
-
-bool SslProtocolFactory::supports(const std::string& capability)
-{
- std::string s = capability;
- transform(s.begin(), s.end(), s.begin(), tolower);
- return s == SSL;
-}
-
-}} // namespace qpid::sys
diff --git a/cpp/src/qpid/sys/StateMonitor.h b/cpp/src/qpid/sys/StateMonitor.h
deleted file mode 100644
index eac37a8543..0000000000
--- a/cpp/src/qpid/sys/StateMonitor.h
+++ /dev/null
@@ -1,78 +0,0 @@
-#ifndef QPID_SYS_STATEMONITOR_H
-#define QPID_SYS_STATEMONITOR_H
-
-/*
- *
- * 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/sys/Waitable.h"
-
-#include <bitset>
-
-namespace qpid {
-namespace sys {
-
-/**
- * A monitor with an enum state value.
- *
- *@param Enum: enum type to use for states.
- *@param EnumMax: Highest enum value.
- */
-template <class Enum, size_t MaxEnum>
-class StateMonitor : public Waitable
-{
- public:
- struct Set : public std::bitset<MaxEnum + 1> {
- Set() {}
- Set(Enum s) { set(s); }
- Set(Enum s, Enum t) { std::bitset<MaxEnum + 1>::set(s).set(t); }
- Set(Enum s, Enum t, Enum u) { std::bitset<MaxEnum + 1>::set(s).set(t).set(u); }
- Set(Enum s, Enum t, Enum u, Enum v) { std::bitset<MaxEnum + 1>::set(s).set(t).set(u).set(v); }
- };
-
-
- StateMonitor(Enum initial) { state=initial; }
-
- /** @pre Caller holds a ScopedLock. */
- void set(Enum s) { state=s; notifyAll(); }
- /** @pre Caller holds a ScopedLock. */
- StateMonitor& operator=(Enum s) { set(s); return *this; }
-
- /** @pre Caller holds a ScopedLock. */
- Enum get() const { return state; }
- /** @pre Caller holds a ScopedLock. */
- operator Enum() const { return state; }
-
- /** @pre Caller holds a ScopedLock */
- void waitFor(Enum s) { ScopedWait w(*this); while (s != state) wait(); }
- /** @pre Caller holds a ScopedLock */
- void waitFor(Set s) { ScopedWait w(*this); while (!s.test(state)) wait(); }
- /** @pre Caller holds a ScopedLock */
- void waitNot(Enum s) { ScopedWait w(*this); while (s == state) wait(); }
- /** @pre Caller holds a ScopedLock */
- void waitNot(Set s) { ScopedWait w(*this); while (s.test(state)) wait(); }
-
- private:
- Enum state;
-};
-
-}}
-
-
-#endif /*!QPID_SYS_STATEMONITOR_H*/
diff --git a/cpp/src/qpid/sys/TCPIOPlugin.cpp b/cpp/src/qpid/sys/TCPIOPlugin.cpp
deleted file mode 100644
index a6528f9ad9..0000000000
--- a/cpp/src/qpid/sys/TCPIOPlugin.cpp
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- *
- * 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/sys/ProtocolFactory.h"
-#include "qpid/sys/AsynchIOHandler.h"
-#include "qpid/sys/AsynchIO.h"
-
-#include "qpid/Plugin.h"
-#include "qpid/sys/Socket.h"
-#include "qpid/sys/Poller.h"
-#include "qpid/broker/Broker.h"
-#include "qpid/log/Statement.h"
-
-#include <boost/bind.hpp>
-#include <memory>
-
-namespace qpid {
-namespace sys {
-
-class AsynchIOProtocolFactory : public ProtocolFactory {
- const bool tcpNoDelay;
- Socket listener;
- const uint16_t listeningPort;
- std::auto_ptr<AsynchAcceptor> acceptor;
-
- public:
- AsynchIOProtocolFactory(int16_t port, int backlog, bool nodelay);
- void accept(Poller::shared_ptr, ConnectionCodec::Factory*);
- void connect(Poller::shared_ptr, const std::string& host, int16_t port,
- ConnectionCodec::Factory*,
- ConnectFailedCallback);
-
- uint16_t getPort() const;
- std::string getHost() const;
-
- private:
- void established(Poller::shared_ptr, const Socket&, ConnectionCodec::Factory*,
- bool isClient);
- void connectFailed(const Socket&, int, const std::string&, ConnectFailedCallback);
-};
-
-// Static instance to initialise plugin
-static class TCPIOPlugin : public Plugin {
- void earlyInitialize(Target&) {
- }
-
- void initialize(Target& target) {
- broker::Broker* broker = dynamic_cast<broker::Broker*>(&target);
- // Only provide to a Broker
- if (broker) {
- const broker::Broker::Options& opts = broker->getOptions();
- ProtocolFactory::shared_ptr protocol(new AsynchIOProtocolFactory(opts.port, opts.connectionBacklog,
- opts.tcpNoDelay));
- QPID_LOG(notice, "Listening on TCP port " << protocol->getPort());
- broker->registerProtocolFactory("tcp", protocol);
- }
- }
-} tcpPlugin;
-
-AsynchIOProtocolFactory::AsynchIOProtocolFactory(int16_t port, int backlog, bool nodelay) :
- tcpNoDelay(nodelay), listeningPort(listener.listen(port, backlog))
-{}
-
-void AsynchIOProtocolFactory::established(Poller::shared_ptr poller, const Socket& s,
- ConnectionCodec::Factory* f, bool isClient) {
- AsynchIOHandler* async = new AsynchIOHandler(s.getFullAddress(), f);
-
- if (tcpNoDelay) {
- s.setTcpNoDelay();
- QPID_LOG(info, "Set TCP_NODELAY on connection to " << s.getPeerAddress());
- }
-
- if (isClient)
- async->setClient();
- AsynchIO* aio = AsynchIO::create
- (s,
- boost::bind(&AsynchIOHandler::readbuff, async, _1, _2),
- boost::bind(&AsynchIOHandler::eof, async, _1),
- boost::bind(&AsynchIOHandler::disconnect, async, _1),
- boost::bind(&AsynchIOHandler::closedSocket, async, _1, _2),
- boost::bind(&AsynchIOHandler::nobuffs, async, _1),
- boost::bind(&AsynchIOHandler::idle, async, _1));
-
- async->init(aio, 4);
- aio->start(poller);
-}
-
-uint16_t AsynchIOProtocolFactory::getPort() const {
- return listeningPort; // Immutable no need for lock.
-}
-
-std::string AsynchIOProtocolFactory::getHost() const {
- return listener.getSockname();
-}
-
-void AsynchIOProtocolFactory::accept(Poller::shared_ptr poller,
- ConnectionCodec::Factory* fact) {
- acceptor.reset(
- AsynchAcceptor::create(listener,
- boost::bind(&AsynchIOProtocolFactory::established, this, poller, _1, fact, false)));
- acceptor->start(poller);
-}
-
-void AsynchIOProtocolFactory::connectFailed(
- const Socket& s, int ec, const std::string& emsg,
- ConnectFailedCallback failedCb)
-{
- failedCb(ec, emsg);
- s.close();
- delete &s;
-}
-
-void AsynchIOProtocolFactory::connect(
- Poller::shared_ptr poller,
- const std::string& host, int16_t port,
- ConnectionCodec::Factory* fact,
- ConnectFailedCallback failed)
-{
- // Note that the following logic does not cause a memory leak.
- // The allocated Socket is freed either by the AsynchConnector
- // upon connection failure or by the AsynchIO upon connection
- // shutdown. The allocated AsynchConnector frees itself when it
- // is no longer needed.
-
- Socket* socket = new Socket();
- AsynchConnector* c = AsynchConnector::create(
- *socket,
- host,
- port,
- boost::bind(&AsynchIOProtocolFactory::established,
- this, poller, _1, fact, true),
- boost::bind(&AsynchIOProtocolFactory::connectFailed,
- this, _1, _2, _3, failed));
- c->start(poller);
-}
-
-}} // namespace qpid::sys
diff --git a/cpp/src/qpid/sys/TimeoutHandler.h b/cpp/src/qpid/sys/TimeoutHandler.h
deleted file mode 100644
index 0c10709bbf..0000000000
--- a/cpp/src/qpid/sys/TimeoutHandler.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- *
- * 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.
- *
- */
-#ifndef _TimeoutHandler_
-#define _TimeoutHandler_
-
-namespace qpid {
-namespace sys {
-
- class TimeoutHandler
- {
- public:
- virtual void idleOut() = 0;
- virtual void idleIn() = 0;
- virtual ~TimeoutHandler(){}
- };
-
-}
-}
-
-
-#endif
diff --git a/cpp/src/qpid/sys/Timer.cpp b/cpp/src/qpid/sys/Timer.cpp
deleted file mode 100644
index fdb2e8c6bb..0000000000
--- a/cpp/src/qpid/sys/Timer.cpp
+++ /dev/null
@@ -1,205 +0,0 @@
-/*
- *
- * 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/sys/Timer.h"
-#include "qpid/sys/Mutex.h"
-#include "qpid/log/Statement.h"
-
-#include <numeric>
-
-using boost::intrusive_ptr;
-using std::max;
-
-namespace qpid {
-namespace sys {
-
-TimerTask::TimerTask(Duration timeout, const std::string& n) :
- name(n),
- sortTime(AbsTime::FarFuture()),
- period(timeout),
- nextFireTime(AbsTime::now(), timeout),
- cancelled(false)
-{}
-
-TimerTask::TimerTask(AbsTime time, const std::string& n) :
- name(n),
- sortTime(AbsTime::FarFuture()),
- period(0),
- nextFireTime(time),
- cancelled(false)
-{}
-
-TimerTask::~TimerTask() {}
-
-bool TimerTask::readyToFire() const {
- return !(nextFireTime > AbsTime::now());
-}
-
-void TimerTask::fireTask() {
- cancelled = true;
- fire();
-}
-
-// This can only be used to setup the next fire time. After the Timer has already fired
-void TimerTask::setupNextFire() {
- if (period && readyToFire()) {
- nextFireTime = max(AbsTime::now(), AbsTime(nextFireTime, period));
- cancelled = false;
- } else {
- QPID_LOG(error, name << " couldn't setup next timer firing: " << Duration(nextFireTime, AbsTime::now()) << "[" << period << "]");
- }
-}
-
-// Only allow tasks to be delayed
-void TimerTask::restart() { nextFireTime = max(nextFireTime, AbsTime(AbsTime::now(), period)); }
-
-void TimerTask::cancel() {
- ScopedLock<Mutex> l(callbackLock);
- cancelled = true;
-}
-
-Timer::Timer() :
- active(false),
- late(50 * TIME_MSEC),
- overran(2 * TIME_MSEC),
- lateCancel(500 * TIME_MSEC),
- warn(5 * TIME_SEC)
-{
- start();
-}
-
-Timer::~Timer()
-{
- stop();
-}
-
-// TODO AStitcher 21/08/09 The threshholds for emitting warnings are a little arbitrary
-void Timer::run()
-{
- Monitor::ScopedLock l(monitor);
- while (active) {
- if (tasks.empty()) {
- monitor.wait();
- } else {
- intrusive_ptr<TimerTask> t = tasks.top();
- tasks.pop();
- assert(!(t->nextFireTime < t->sortTime));
-
- // warn on extreme lateness
- AbsTime start(AbsTime::now());
- Duration delay(t->sortTime, start);
- {
- ScopedLock<Mutex> l(t->callbackLock);
- if (t->cancelled) {
- {
- Monitor::ScopedUnlock u(monitor);
- drop(t);
- }
- if (delay > lateCancel) {
- QPID_LOG(debug, t->name << " cancelled timer woken up " <<
- delay / TIME_MSEC << "ms late");
- }
- continue;
- } else if(Duration(t->nextFireTime, start) >= 0) {
- {
- Monitor::ScopedUnlock u(monitor);
- fire(t);
- }
- // Warn if callback overran next timer's start.
- AbsTime end(AbsTime::now());
- Duration overrun (0);
- if (!tasks.empty()) {
- overrun = Duration(tasks.top()->nextFireTime, end);
- }
- bool warningsEnabled;
- QPID_LOG_TEST(warning, warningsEnabled);
- if (warningsEnabled) {
- if (overrun > overran) {
- if (delay > overran) // if delay is significant to an overrun.
- warn.lateAndOverran(t->name, delay, overrun, Duration(start, end));
- else
- warn.overran(t->name, overrun, Duration(start, end));
- }
- else if (delay > late)
- warn.late(t->name, delay);
- }
- continue;
- } else {
- // If the timer was adjusted into the future it might no longer
- // be the next event, so push and then get top to make sure
- // You can only push events into the future
- t->sortTime = t->nextFireTime;
- tasks.push(t);
- }
- }
- assert(!tasks.empty());
- monitor.wait(tasks.top()->sortTime);
- }
- }
-}
-
-void Timer::add(intrusive_ptr<TimerTask> task)
-{
- Monitor::ScopedLock l(monitor);
- task->sortTime = task->nextFireTime;
- tasks.push(task);
- monitor.notify();
-}
-
-void Timer::start()
-{
- Monitor::ScopedLock l(monitor);
- if (!active) {
- active = true;
- runner = Thread(this);
- }
-}
-
-void Timer::stop()
-{
- {
- Monitor::ScopedLock l(monitor);
- if (!active) return;
- active = false;
- monitor.notifyAll();
- }
- runner.join();
-}
-
-// Allow subclasses to override behavior when firing a task.
-void Timer::fire(boost::intrusive_ptr<TimerTask> t) {
- try {
- t->fireTask();
- } catch (const std::exception& e) {
- QPID_LOG(error, "Exception thrown by timer task " << t->getName() << ": " << e.what());
- }
-}
-
-// Provided for subclasses: called when a task is droped.
-void Timer::drop(boost::intrusive_ptr<TimerTask>) {}
-
-bool operator<(const intrusive_ptr<TimerTask>& a,
- const intrusive_ptr<TimerTask>& b)
-{
- // Lower priority if time is later
- return a.get() && b.get() && a->sortTime > b->sortTime;
-}
-
-}}
diff --git a/cpp/src/qpid/sys/Timer.h b/cpp/src/qpid/sys/Timer.h
deleted file mode 100644
index 98ba39ce38..0000000000
--- a/cpp/src/qpid/sys/Timer.h
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- *
- * 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.
- *
- */
-#ifndef sys_Timer
-#define sys_Timer
-
-#include "qpid/sys/TimerWarnings.h"
-#include "qpid/sys/Monitor.h"
-#include "qpid/sys/Mutex.h"
-#include "qpid/sys/Thread.h"
-#include "qpid/sys/Runnable.h"
-#include "qpid/RefCounted.h"
-#include "qpid/CommonImportExport.h"
-#include <memory>
-#include <queue>
-
-#include <boost/intrusive_ptr.hpp>
-
-namespace qpid {
-namespace sys {
-
-class Timer;
-
-class TimerTask : public RefCounted {
- friend class Timer;
- friend bool operator<(const boost::intrusive_ptr<TimerTask>&,
- const boost::intrusive_ptr<TimerTask>&);
-
- std::string name;
- AbsTime sortTime;
- Duration period;
- AbsTime nextFireTime;
- Mutex callbackLock;
- volatile bool cancelled;
-
- bool readyToFire() const;
- void fireTask();
-
- public:
- QPID_COMMON_EXTERN TimerTask(Duration period, const std::string& name);
- QPID_COMMON_EXTERN TimerTask(AbsTime fireTime, const std::string& name);
- QPID_COMMON_EXTERN virtual ~TimerTask();
-
- QPID_COMMON_EXTERN void setupNextFire();
- QPID_COMMON_EXTERN void restart();
- QPID_COMMON_EXTERN void cancel();
-
- std::string getName() const { return name; }
-
- protected:
- // Must be overridden with callback
- virtual void fire() = 0;
-};
-
-// For the priority_queue order
-bool operator<(const boost::intrusive_ptr<TimerTask>& a,
- const boost::intrusive_ptr<TimerTask>& b);
-
-class Timer : private Runnable {
- qpid::sys::Monitor monitor;
- std::priority_queue<boost::intrusive_ptr<TimerTask> > tasks;
- qpid::sys::Thread runner;
- bool active;
-
- // Runnable interface
- void run();
-
- public:
- QPID_COMMON_EXTERN Timer();
- QPID_COMMON_EXTERN virtual ~Timer();
-
- QPID_COMMON_EXTERN virtual void add(boost::intrusive_ptr<TimerTask> task);
- QPID_COMMON_EXTERN virtual void start();
- QPID_COMMON_EXTERN virtual void stop();
-
- protected:
- QPID_COMMON_EXTERN virtual void fire(boost::intrusive_ptr<TimerTask> task);
- QPID_COMMON_EXTERN virtual void drop(boost::intrusive_ptr<TimerTask> task);
- // Allow derived classes to change the late/overran thresholds.
- Duration late;
- Duration overran;
- Duration lateCancel;
- TimerWarnings warn;
-};
-
-
-}}
-
-
-#endif
diff --git a/cpp/src/qpid/sys/TimerWarnings.cpp b/cpp/src/qpid/sys/TimerWarnings.cpp
deleted file mode 100644
index 87c3169456..0000000000
--- a/cpp/src/qpid/sys/TimerWarnings.cpp
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- *
- * 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 "TimerWarnings.h"
-#include "qpid/log/Statement.h"
-
-namespace qpid {
-namespace sys {
-
-TimerWarnings::TimerWarnings(Duration reportInterval) :
- interval(reportInterval),
- nextReport(now(), reportInterval)
-{}
-
-void TimerWarnings::late(const std::string& task, Duration delay) {
- taskStats[task].lateDelay.add(delay);
- log();
-}
-
-void TimerWarnings::overran(const std::string& task, Duration overrun, Duration time)
-{
- taskStats[task].overranOverrun.add(overrun);
- taskStats[task].overranTime.add(time);
- log();
-}
-
-void TimerWarnings::lateAndOverran(
- const std::string& task, Duration delay, Duration overrun, Duration time)
-{
- taskStats[task].lateAndOverranDelay.add(delay);
- taskStats[task].lateAndOverranOverrun.add(overrun);
- taskStats[task].lateAndOverranTime.add(time);
- log();
-}
-
-void TimerWarnings::log() {
- if (!taskStats.empty() && nextReport < now()) {
- for (TaskStatsMap::iterator i = taskStats.begin(); i != taskStats.end(); ++i) {
- std::string task = i->first;
- TaskStats& stats = i->second;
- if (stats.lateDelay.count)
- QPID_LOG(warning, task << " task late "
- << stats.lateDelay.count << " times by "
- << stats.lateDelay.average()/TIME_MSEC << "ms on average.");
-
- if (stats.overranOverrun.count)
- QPID_LOG(warning, task << " task overran "
- << stats.overranOverrun.count << " times by "
- << stats.overranOverrun.average()/TIME_MSEC << "ms (taking "
- << stats.overranTime.average() << "ns) on average.");
-
- if (stats.lateAndOverranOverrun.count)
- QPID_LOG(warning, task << " task late and overran "
- << stats.lateAndOverranOverrun.count << " times: late "
- << stats.lateAndOverranDelay.average()/TIME_MSEC << "ms, overran "
- << stats.lateAndOverranOverrun.average()/TIME_MSEC << "ms (taking "
- << stats.lateAndOverranTime.average() << "ns) on average.");
-
- }
- nextReport = AbsTime(now(), interval);
- taskStats.clear();
- }
-}
-
-}} // namespace qpid::sys
diff --git a/cpp/src/qpid/sys/TimerWarnings.h b/cpp/src/qpid/sys/TimerWarnings.h
deleted file mode 100644
index 337a434ab5..0000000000
--- a/cpp/src/qpid/sys/TimerWarnings.h
+++ /dev/null
@@ -1,81 +0,0 @@
-#ifndef QPID_SYS_TIMERWARNINGS_H
-#define QPID_SYS_TIMERWARNINGS_H
-
-/*
- *
- * 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/sys/Time.h"
-#include <map>
-#include <string>
-
-namespace qpid {
-namespace sys {
-
-/**
- * The Timer class logs warnings when timer tasks are late and/or overrun.
- *
- * It is too expensive to log a warning for every late/overrun
- * incident, doing so aggravates the problem of tasks over-running and
- * being late.
- *
- * This class collects statistical data about each incident and prints
- * an aggregated report at regular intervals.
- */
-class TimerWarnings
-{
- public:
- TimerWarnings(Duration reportInterval);
-
- void late(const std::string& task, Duration delay);
-
- void overran(const std::string& task, Duration overrun, Duration time);
-
- void lateAndOverran(const std::string& task,
- Duration delay, Duration overrun, Duration time);
-
- private:
- struct Statistic {
- Statistic() : total(0), count(0) {}
- void add(int64_t value) { total += value; ++count; }
- int64_t average() const { return count ? total/count : 0; }
- int64_t total;
- int64_t count;
- };
-
- // Keep statistics for 3 classes of incident: late, overrun and both.
- struct TaskStats {
- Statistic lateDelay; // Just late
- Statistic overranOverrun, overranTime; // Just overrun
- // Both
- Statistic lateAndOverranDelay, lateAndOverranOverrun, lateAndOverranTime;
- };
-
- typedef std::map<std::string, TaskStats> TaskStatsMap;
-
- void log();
-
- Duration interval;
- AbsTime nextReport;
- TaskStatsMap taskStats;
-};
-}} // namespace qpid::sys
-
-#endif /*!QPID_SYS_TIMERWARNINGS_H*/
diff --git a/cpp/src/qpid/sys/Waitable.h b/cpp/src/qpid/sys/Waitable.h
deleted file mode 100644
index 8f6bd17049..0000000000
--- a/cpp/src/qpid/sys/Waitable.h
+++ /dev/null
@@ -1,117 +0,0 @@
-#ifndef QPID_SYS_WAITABLE_H
-#define QPID_SYS_WAITABLE_H
-
-/*
- * 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/sys/Monitor.h"
-#include "qpid/sys/ExceptionHolder.h"
-#include <assert.h>
-
-namespace qpid {
-namespace sys {
-
-/**
- * A monitor that keeps track of waiting threads. Threads declare a
- * ScopedWait around wait() inside a ScopedLock to be considered
- * waiters.
- *
- * Allows waiting threads to be interrupted by an exception.
- */
-class Waitable : public Monitor {
- public:
- Waitable() : waiters(0) {}
-
- ~Waitable() { assert(waiters == 0); }
-
- /** Use this inside a scoped lock around the
- * call to wait() to be counted as a waiter.
- */
- struct ScopedWait {
- Waitable& w;
- ScopedWait(Waitable& w_) : w(w_) { ++w.waiters; }
- ~ScopedWait() { if (--w.waiters==0) w.notifyAll(); }
- };
-
- /** Block till there are no more waiters in ScopedWaits.
- * waitWaiters() does not raise an exception even if waiters
- * were interrupted by one.
- *@pre Must be called inside a ScopedLock but NOT a ScopedWait.
- */
- void waitWaiters() {
- while (waiters != 0)
- Monitor::wait();
- }
-
- /** Returns the number of outstanding ScopedWaits.
- * Must be called with the lock held.
- */
- size_t hasWaiters() const {
- return waiters;
- }
-
- /** Set an execption to interrupt waiters in ScopedWait.
- * Must be called with the lock held.
- */
- void setException(const ExceptionHolder& e) {
- exception = e;
- notifyAll();
-
- }
-
- /** True if the waitable has an exception */
- bool hasException() const { return exception; }
-
- /** Throws if the waitable has an exception */
- void checkException() const { exception.raise(); }
-
- /** Clear the exception if any */
- void resetException() { exception.reset(); }
-
- /** Throws an exception if one is set before or during the wait. */
- void wait() {
- ExCheck e(exception);
- Monitor::wait();
- }
-
- /** Throws an exception if one is set before or during the wait. */
- bool wait(const AbsTime& absoluteTime) {
- ExCheck e(exception);
- return Monitor::wait(absoluteTime);
- }
-
- private:
- struct ExCheck {
- const ExceptionHolder& exception;
- ExCheck(const ExceptionHolder& e) : exception(e) { e.raise(); }
- ~ExCheck() { exception.raise(); }
- };
-
- size_t waiters;
- ExceptionHolder exception;
-
- friend struct ScopedWait;
-};
-
-}} // namespace qpid::sys
-
-
-
-#endif /*!QPID_SYS_WAITABLE_H*/
diff --git a/cpp/src/qpid/sys/alloca.h b/cpp/src/qpid/sys/alloca.h
deleted file mode 100644
index 0f58920908..0000000000
--- a/cpp/src/qpid/sys/alloca.h
+++ /dev/null
@@ -1,42 +0,0 @@
-#ifndef QPID_SYS_ALLOCA_H
-#define QPID_SYS_ALLOCA_H
-
-/*
- * 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.
- *
- */
-
-#if (defined(_WINDOWS) || defined (WIN32))
-# include <malloc.h>
-
-# if defined(_MSC_VER)
-# ifdef alloc
-# undef alloc
-# endif
-# define alloc _alloc
-# ifdef alloca
-# undef alloca
-# endif
-# define alloca _alloca
-# endif
-# if !defined _WINDOWS && !defined WIN32
-# include <alloca.h>
-# endif
-#endif
-
-#endif /*!QPID_SYS_ALLOCA_H*/
diff --git a/cpp/src/qpid/sys/apr/APRBase.cpp b/cpp/src/qpid/sys/apr/APRBase.cpp
deleted file mode 100644
index 8bdba66bdc..0000000000
--- a/cpp/src/qpid/sys/apr/APRBase.cpp
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- *
- * 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 <iostream>
-#include "qpid/log/Statement.h"
-#include "qpid/sys/apr/APRBase.h"
-
-using namespace qpid::sys;
-
-APRBase* APRBase::instance = 0;
-
-APRBase* APRBase::getInstance(){
- if(instance == 0){
- instance = new APRBase();
- }
- return instance;
-}
-
-
-APRBase::APRBase() : count(0){
- apr_initialize();
- CHECK_APR_SUCCESS(apr_pool_create(&pool, 0));
- CHECK_APR_SUCCESS(apr_thread_mutex_create(&mutex, APR_THREAD_MUTEX_NESTED, pool));
-}
-
-APRBase::~APRBase(){
- CHECK_APR_SUCCESS(apr_thread_mutex_destroy(mutex));
- apr_pool_destroy(pool);
- apr_terminate();
-}
-
-bool APRBase::_increment(){
- bool deleted(false);
- CHECK_APR_SUCCESS(apr_thread_mutex_lock(mutex));
- if(this == instance){
- count++;
- }else{
- deleted = true;
- }
- CHECK_APR_SUCCESS(apr_thread_mutex_unlock(mutex));
- return !deleted;
-}
-
-void APRBase::_decrement(){
- APRBase* copy = 0;
- CHECK_APR_SUCCESS(apr_thread_mutex_lock(mutex));
- if(--count == 0){
- copy = instance;
- instance = 0;
- }
- CHECK_APR_SUCCESS(apr_thread_mutex_unlock(mutex));
- if(copy != 0){
- delete copy;
- }
-}
-
-void APRBase::increment(){
- int count = 0;
- while(count++ < 2 && !getInstance()->_increment())
- QPID_LOG(warning, "APR initialization triggered concurrently with termination.");
-}
-
-void APRBase::decrement(){
- getInstance()->_decrement();
-}
-
-std::string qpid::sys::get_desc(apr_status_t status){
- const int size = 50;
- char tmp[size];
- return std::string(apr_strerror(status, tmp, size));
-}
-
diff --git a/cpp/src/qpid/sys/apr/APRBase.h b/cpp/src/qpid/sys/apr/APRBase.h
deleted file mode 100644
index 7b5644a129..0000000000
--- a/cpp/src/qpid/sys/apr/APRBase.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- *
- * 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.
- *
- */
-#ifndef _APRBase_
-#define _APRBase_
-
-#include <string>
-#include <apr_thread_mutex.h>
-#include <apr_errno.h>
-
-namespace qpid {
-namespace sys {
-
- /**
- * Use of APR libraries necessitates explicit init and terminate
- * calls. Any class using APR libs should obtain the reference to
- * this singleton and increment on construction, decrement on
- * destruction. This class can then correctly initialise apr
- * before the first use and terminate after the last use.
- */
- class APRBase{
- static APRBase* instance;
- apr_pool_t* pool;
- apr_thread_mutex_t* mutex;
- int count;
-
- APRBase();
- ~APRBase();
- static APRBase* getInstance();
- bool _increment();
- void _decrement();
- public:
- static void increment();
- static void decrement();
- };
-
- //this is also a convenient place for a helper function for error checking:
- void check(apr_status_t status, const char* file, const int line);
- std::string get_desc(apr_status_t status);
-
-#define CHECK_APR_SUCCESS(A) qpid::sys::check(A, __FILE__, __LINE__);
-
-}
-}
-
-// Inlined as it is called *a lot*
-void inline qpid::sys::check(apr_status_t status, const char* file, const int line){
- if (status != APR_SUCCESS){
- char tmp[256];
- throw Exception(QPID_MSG(apr_strerror(status, tmp, size)))
- }
-}
-
-
-
-
-#endif
diff --git a/cpp/src/qpid/sys/apr/APRPool.cpp b/cpp/src/qpid/sys/apr/APRPool.cpp
deleted file mode 100644
index e221bfc2f1..0000000000
--- a/cpp/src/qpid/sys/apr/APRPool.cpp
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- *
- * 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/sys/apr/APRPool.h"
-#include "qpid/sys/apr/APRBase.h"
-#include <boost/pool/detail/singleton.hpp>
-
-using namespace qpid::sys;
-
-APRPool::APRPool(){
- APRBase::increment();
- CHECK_APR_SUCCESS(apr_pool_create(&pool, NULL));
-}
-
-APRPool::~APRPool(){
- apr_pool_destroy(pool);
- APRBase::decrement();
-}
-
-apr_pool_t* APRPool::get() {
- return boost::details::pool::singleton_default<APRPool>::instance().pool;
-}
-
diff --git a/cpp/src/qpid/sys/apr/APRPool.h b/cpp/src/qpid/sys/apr/APRPool.h
deleted file mode 100644
index da7661fcfa..0000000000
--- a/cpp/src/qpid/sys/apr/APRPool.h
+++ /dev/null
@@ -1,50 +0,0 @@
-#ifndef _APRPool_
-#define _APRPool_
-
-/*
- *
- * 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 <boost/noncopyable.hpp>
-#include <apr_pools.h>
-
-namespace qpid {
-namespace sys {
-/**
- * Singleton APR memory pool.
- */
-class APRPool : private boost::noncopyable {
- public:
- APRPool();
- ~APRPool();
-
- /** Get singleton instance */
- static apr_pool_t* get();
-
- private:
- apr_pool_t* pool;
-};
-
-}}
-
-
-
-
-
-#endif /*!_APRPool_*/
diff --git a/cpp/src/qpid/sys/apr/Condition.h b/cpp/src/qpid/sys/apr/Condition.h
deleted file mode 100644
index 66d465ca75..0000000000
--- a/cpp/src/qpid/sys/apr/Condition.h
+++ /dev/null
@@ -1,84 +0,0 @@
-#ifndef _sys_apr_Condition_h
-#define _sys_apr_Condition_h
-
-/*
- *
- * 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/sys/apr/APRPool.h"
-#include "qpid/sys/Mutex.h"
-#include "qpid/sys/Time.h"
-
-#include <sys/errno.h>
-#include <boost/noncopyable.hpp>
-#include <apr_thread_cond.h>
-
-namespace qpid {
-namespace sys {
-
-/**
- * A condition variable for thread synchronization.
- */
-class Condition
-{
- public:
- inline Condition();
- inline ~Condition();
- inline void wait(Mutex&);
- inline bool wait(Mutex&, const AbsTime& absoluteTime);
- inline void notify();
- inline void notifyAll();
-
- private:
- apr_thread_cond_t* condition;
-};
-
-
-Condition::Condition() {
- CHECK_APR_SUCCESS(apr_thread_cond_create(&condition, APRPool::get()));
-}
-
-Condition::~Condition() {
- CHECK_APR_SUCCESS(apr_thread_cond_destroy(condition));
-}
-
-void Condition::wait(Mutex& mutex) {
- CHECK_APR_SUCCESS(apr_thread_cond_wait(condition, mutex.mutex));
-}
-
-bool Condition::wait(Mutex& mutex, const AbsTime& absoluteTime){
- // APR uses microseconds.
- apr_status_t status =
- apr_thread_cond_timedwait(
- condition, mutex.mutex, Duration(now(), absoluteTime)/TIME_USEC);
- if(status != APR_TIMEUP) CHECK_APR_SUCCESS(status);
- return status == 0;
-}
-
-void Condition::notify(){
- CHECK_APR_SUCCESS(apr_thread_cond_signal(condition));
-}
-
-void Condition::notifyAll(){
- CHECK_APR_SUCCESS(apr_thread_cond_broadcast(condition));
-}
-
-}}
-#endif /*!_sys_apr_Condition_h*/
diff --git a/cpp/src/qpid/sys/apr/Mutex.h b/cpp/src/qpid/sys/apr/Mutex.h
deleted file mode 100644
index cb75f5b339..0000000000
--- a/cpp/src/qpid/sys/apr/Mutex.h
+++ /dev/null
@@ -1,124 +0,0 @@
-#ifndef _sys_apr_Mutex_h
-#define _sys_apr_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.
- *
- */
-
-#include "qpid/sys/apr/APRBase.h"
-#include "qpid/sys/apr/APRPool.h"
-
-#include <boost/noncopyable.hpp>
-#include <apr_thread_mutex.h>
-
-namespace qpid {
-namespace sys {
-
-class Condition;
-
-/**
- * Mutex lock.
- */
-class Mutex : private boost::noncopyable {
- public:
- typedef ScopedLock<Mutex> ScopedLock;
- typedef ScopedUnlock<Mutex> ScopedUnlock;
-
- inline Mutex();
- inline ~Mutex();
- inline void lock();
- inline void unlock();
- inline bool trylock();
-
- protected:
- apr_thread_mutex_t* mutex;
- friend class Condition;
-};
-
-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));
-}
-
-bool Mutex::trylock() {
- return apr_thread_mutex_trylock(mutex) == 0;
-}
-
-
-/**
- * RW lock.
- */
-class RWlock : private boost::noncopyable {
- friend class Condition;
-
-public:
- typedef ScopedRlock<RWlock> ScopedRlock;
- typedef ScopedWlock<RWlock> ScopedWlock;
-
- inline RWlock();
- inline ~RWlock();
- inline void wlock(); // will write-lock
- inline void rlock(); // will read-lock
- inline void unlock();
- inline bool trywlock(); // will write-try
- inline bool tryrlock(); // will read-try
-
- protected:
- apr_thread_mutex_t* mutex;
-};
-
-RWlock::RWlock() {
- CHECK_APR_SUCCESS(apr_thread_mutex_create(&mutex, APR_THREAD_MUTEX_NESTED, APRPool::get()));
-}
-
-RWlock::~RWlock(){
- CHECK_APR_SUCCESS(apr_thread_mutex_destroy(mutex));
-}
-
-void RWlock::wlock() {
- CHECK_APR_SUCCESS(apr_thread_mutex_lock(mutex));
-}
-
-void RWlock::rlock() {
- CHECK_APR_SUCCESS(apr_thread_mutex_lock(mutex));
-}
-
-void RWlock::unlock() {
- CHECK_APR_SUCCESS(apr_thread_mutex_unlock(mutex));
-}
-
-bool RWlock::trywlock() {
- return apr_thread_mutex_trylock(mutex) == 0;
-}
-
-bool RWlock::tryrlock() {
- return apr_thread_mutex_trylock(mutex) == 0;
-}
-
-
-}}
-#endif /*!_sys_apr_Mutex_h*/
diff --git a/cpp/src/qpid/sys/apr/Shlib.cpp b/cpp/src/qpid/sys/apr/Shlib.cpp
deleted file mode 100644
index b7ee13a03b..0000000000
--- a/cpp/src/qpid/sys/apr/Shlib.cpp
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * 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/sys/Shlib.h"
-#include "qpid/sys/apr/APRBase.h"
-#include "qpid/sys/apr/APRPool.h"
-#include <apr_dso.h>
-
-namespace qpid {
-namespace sys {
-
-void Shlib::load(const char* libname) {
- apr_dso_handle_t* aprHandle;
- CHECK_APR_SUCCESS(
- apr_dso_load(&aprHandle, libname, APRPool::get()));
- handle=aprHandle;
-}
-
-void Shlib::unload() {
- CHECK_APR_SUCCESS(
- apr_dso_unload(static_cast<apr_dso_handle_t*>(handle)));
-}
-
-void* Shlib::getSymbol(const char* name) {
- apr_dso_handle_sym_t symbol;
- CHECK_APR_SUCCESS(apr_dso_sym(&symbol,
- static_cast<apr_dso_handle_t*>(handle),
- name));
- return (void*) symbol;
-}
-
-}} // namespace qpid::sys
diff --git a/cpp/src/qpid/sys/apr/Socket.cpp b/cpp/src/qpid/sys/apr/Socket.cpp
deleted file mode 100644
index d9024d11c1..0000000000
--- a/cpp/src/qpid/sys/apr/Socket.cpp
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- *
- * 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/sys/Socket.h"
-
-#include "qpid/sys/apr/APRBase.h"
-#include "qpid/sys/apr/APRPool.h"
-
-#include <apr_network_io.h>
-
-namespace qpid {
-namespace sys {
-
-class SocketPrivate {
-public:
- SocketPrivate(apr_socket_t* s = 0) :
- socket(s)
- {}
-
- apr_socket_t* socket;
-};
-
-Socket::Socket() :
- impl(new SocketPrivate)
-{
- createTcp();
-}
-
-Socket::Socket(SocketPrivate* sp) :
- impl(sp)
-{}
-
-Socket::~Socket() {
- delete impl;
-}
-
-void Socket::createTcp() const {
- apr_socket_t*& socket = impl->socket;
- apr_socket_t* s;
- CHECK_APR_SUCCESS(
- apr_socket_create(
- &s, APR_INET, SOCK_STREAM, APR_PROTO_TCP,
- APRPool::get()));
- socket = s;
-}
-
-void Socket::setTimeout(const Duration& interval) const {
- apr_socket_t*& socket = impl->socket;
- apr_socket_timeout_set(socket, interval/TIME_USEC);
-}
-
-void Socket::connect(const std::string& host, int port) const {
- apr_socket_t*& socket = impl->socket;
- apr_sockaddr_t* address;
- CHECK_APR_SUCCESS(
- apr_sockaddr_info_get(
- &address, host.c_str(), APR_UNSPEC, port, APR_IPV4_ADDR_OK,
- APRPool::get()));
- CHECK_APR_SUCCESS(apr_socket_connect(socket, address));
-}
-
-void Socket::close() const {
- apr_socket_t*& socket = impl->socket;
- if (socket == 0) return;
- CHECK_APR_SUCCESS(apr_socket_close(socket));
- socket = 0;
-}
-
-ssize_t Socket::send(const void* data, size_t size) const
-{
- apr_socket_t*& socket = impl->socket;
- apr_size_t sent = size;
- 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(void* data, size_t size) const
-{
- apr_socket_t*& socket = impl->socket;
- apr_size_t received = size;
- apr_status_t status =
- apr_socket_recv(socket, reinterpret_cast<char*>(data), &received);
- if (APR_STATUS_IS_TIMEUP(status))
- return SOCKET_TIMEOUT;
- if (APR_STATUS_IS_EOF(status))
- return SOCKET_EOF;
- CHECK_APR_SUCCESS(status);
- return received;
-}
-
-}} // namespace qpid::sys
diff --git a/cpp/src/qpid/sys/apr/Thread.cpp b/cpp/src/qpid/sys/apr/Thread.cpp
deleted file mode 100644
index b52d0e6ace..0000000000
--- a/cpp/src/qpid/sys/apr/Thread.cpp
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- *
- * 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/sys/apr/Thread.h"
-#include "qpid/sys/Runnable.h"
-
-using namespace qpid::sys;
-using qpid::sys::Runnable;
-
-void* APR_THREAD_FUNC Thread::runRunnable(apr_thread_t* thread, void *data) {
- reinterpret_cast<Runnable*>(data)->run();
- CHECK_APR_SUCCESS(apr_thread_exit(thread, APR_SUCCESS));
- return NULL;
-}
-
-
diff --git a/cpp/src/qpid/sys/apr/Thread.h b/cpp/src/qpid/sys/apr/Thread.h
deleted file mode 100644
index 6cc63db5c9..0000000000
--- a/cpp/src/qpid/sys/apr/Thread.h
+++ /dev/null
@@ -1,106 +0,0 @@
-#ifndef _sys_apr_Thread_h
-#define _sys_apr_Thread_h
-
-/*
- *
- * 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/sys/apr/APRPool.h"
-#include "qpid/sys/apr/APRBase.h"
-
-#include <apr_thread_proc.h>
-#include <apr_portable.h>
-
-namespace qpid {
-namespace sys {
-
-class Runnable;
-
-class Thread
-{
- public:
- inline static Thread current();
-
- /** ID of current thread for logging.
- * Workaround for broken Thread::current() in APR
- */
- inline static long logId();
-
- inline static void yield();
-
- inline Thread();
- inline explicit Thread(qpid::sys::Runnable*);
- inline explicit Thread(qpid::sys::Runnable&);
-
- inline void join();
-
- inline long id();
-
- private:
- static void* APR_THREAD_FUNC runRunnable(apr_thread_t* thread, void *data);
- inline Thread(apr_thread_t* t);
- apr_thread_t* thread;
-};
-
-Thread::Thread() : thread(0) {}
-
-Thread::Thread(Runnable* runnable) {
- CHECK_APR_SUCCESS(
- 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);
-}
-
-/** ID of current thread for logging.
- * Workaround for broken Thread::current() in APR
- */
-long Thread::logId() {
- return static_cast<long>(apr_os_thread_current());
-}
-
-Thread::Thread(apr_thread_t* t) : thread(t) {}
-
-Thread Thread::current(){
- apr_thread_t* thr;
- apr_os_thread_t osthr = apr_os_thread_current();
- CHECK_APR_SUCCESS(apr_os_thread_put(&thr, &osthr, APRPool::get()));
- return Thread(thr);
-}
-
-void Thread::yield()
-{
- apr_thread_yield();
-}
-
-}}
-#endif /*!_sys_apr_Thread_h*/
diff --git a/cpp/src/qpid/sys/apr/Time.cpp b/cpp/src/qpid/sys/apr/Time.cpp
deleted file mode 100644
index 34e740b144..0000000000
--- a/cpp/src/qpid/sys/apr/Time.cpp
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- *
- * 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/sys/Time.h"
-
-#include <apr_time.h>
-
-namespace qpid {
-namespace sys {
-
-AbsTime AbsTime::now() {
- AbsTime time_now;
- time_now.time_ns = apr_time_now() * TIME_USEC;
- return time_now;
-}
-
-}}
-
diff --git a/cpp/src/qpid/sys/cyrus/CyrusSecurityLayer.cpp b/cpp/src/qpid/sys/cyrus/CyrusSecurityLayer.cpp
deleted file mode 100644
index 3d868da64b..0000000000
--- a/cpp/src/qpid/sys/cyrus/CyrusSecurityLayer.cpp
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- *
- * 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/sys/cyrus/CyrusSecurityLayer.h"
-#include <algorithm>
-#include "qpid/framing/reply_exceptions.h"
-#include "qpid/log/Statement.h"
-#include <string.h>
-
-namespace qpid {
-namespace sys {
-namespace cyrus {
-
-CyrusSecurityLayer::CyrusSecurityLayer(sasl_conn_t* c, uint16_t maxFrameSize) :
- conn(c), decrypted(0), decryptedSize(0), encrypted(0), encryptedSize(0), codec(0), maxInputSize(0),
- decodeBuffer(maxFrameSize), encodeBuffer(maxFrameSize), encoded(0)
-{
- const void* value(0);
- int result = sasl_getprop(conn, SASL_MAXOUTBUF, &value);
- if (result != SASL_OK) {
- throw framing::InternalErrorException(QPID_MSG("SASL encode error: " << sasl_errdetail(conn)));
- }
- maxInputSize = *(reinterpret_cast<const unsigned*>(value));
-}
-
-size_t CyrusSecurityLayer::decode(const char* input, size_t size)
-{
- size_t inStart = 0;
- do {
- size_t inSize = std::min(size - inStart, maxInputSize);
- int result = sasl_decode(conn, input + inStart, inSize, &decrypted, &decryptedSize);
- if (result != SASL_OK) {
- throw framing::InternalErrorException(QPID_MSG("SASL decode error: " << sasl_errdetail(conn)));
- }
- inStart += inSize;
- size_t copied = 0;
- do {
- size_t count = std::min(decryptedSize - copied, decodeBuffer.size - decodeBuffer.position);
- ::memcpy(decodeBuffer.data + decodeBuffer.position, decrypted + copied, count);
- copied += count;
- decodeBuffer.position += count;
- size_t decodedSize = codec->decode(decodeBuffer.data, decodeBuffer.position);
- if (decodedSize < decodeBuffer.position) {
- ::memmove(decodeBuffer.data, decodeBuffer.data + decodedSize, decodeBuffer.position - decodedSize);
- }
- decodeBuffer.position -= decodedSize;
- } while (copied < decryptedSize);
- } while (inStart < size);
- return size;
-}
-
-size_t CyrusSecurityLayer::encode(const char* buffer, size_t size)
-{
- size_t processed = 0;//records how many bytes have been written to buffer
- do {
- if (!encrypted) {
- if (!encoded) {
- encodeBuffer.position = 0;
- encoded = codec->encode(encodeBuffer.data, encodeBuffer.size);
- if (!encoded) break;//nothing more to do
- }
-
- size_t encryptable = std::min(encoded, maxInputSize);
- int result = sasl_encode(conn, encodeBuffer.data + encodeBuffer.position, encryptable, &encrypted, &encryptedSize);
- if (result != SASL_OK) {
- throw framing::InternalErrorException(QPID_MSG("SASL encode error: " << sasl_errdetail(conn)));
- }
- encodeBuffer.position += encryptable;
- encoded -= encryptable;
- }
- size_t remaining = size - processed;
- if (remaining < encryptedSize) {
- //can't fit all encrypted data in the buffer we've
- //been given, copy in what we can and hold on to the
- //rest until the next call
- ::memcpy(const_cast<char*>(buffer + processed), encrypted, remaining);
- processed += remaining;
- encrypted += remaining;
- encryptedSize -= remaining;
- } else {
- ::memcpy(const_cast<char*>(buffer + processed), encrypted, encryptedSize);
- processed += encryptedSize;
- encrypted = 0;
- encryptedSize = 0;
- }
- } while (processed < size);
- return processed;
-}
-
-bool CyrusSecurityLayer::canEncode()
-{
- return codec && (encrypted || codec->canEncode());
-}
-
-void CyrusSecurityLayer::init(qpid::sys::Codec* c)
-{
- codec = c;
-}
-
-CyrusSecurityLayer::DataBuffer::DataBuffer(size_t s) : position(0), size(s)
-{
- data = new char[size];
-}
-
-CyrusSecurityLayer::DataBuffer::~DataBuffer()
-{
- delete[] data;
-}
-
-}}} // namespace qpid::sys::cyrus
diff --git a/cpp/src/qpid/sys/cyrus/CyrusSecurityLayer.h b/cpp/src/qpid/sys/cyrus/CyrusSecurityLayer.h
deleted file mode 100644
index 1645cf1a58..0000000000
--- a/cpp/src/qpid/sys/cyrus/CyrusSecurityLayer.h
+++ /dev/null
@@ -1,68 +0,0 @@
-#ifndef QPID_SYS_CYRUS_CYRUSSECURITYLAYER_H
-#define QPID_SYS_CYRUS_CYRUSSECURITYLAYER_H
-
-/*
- *
- * 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/sys/IntegerTypes.h"
-#include "qpid/sys/SecurityLayer.h"
-#include <sasl/sasl.h>
-
-namespace qpid {
-namespace sys {
-namespace cyrus {
-
-
-/**
- * Implementation of SASL security layer using cyrus-sasl library
- */
-class CyrusSecurityLayer : public qpid::sys::SecurityLayer
-{
- public:
- CyrusSecurityLayer(sasl_conn_t*, uint16_t maxFrameSize);
- size_t decode(const char* buffer, size_t size);
- size_t encode(const char* buffer, size_t size);
- bool canEncode();
- void init(qpid::sys::Codec*);
- private:
- struct DataBuffer
- {
- char* data;
- size_t position;
- const size_t size;
- DataBuffer(size_t);
- ~DataBuffer();
- };
-
- sasl_conn_t* conn;
- const char* decrypted;
- unsigned decryptedSize;
- const char* encrypted;
- unsigned encryptedSize;
- qpid::sys::Codec* codec;
- size_t maxInputSize;
- DataBuffer decodeBuffer;
- DataBuffer encodeBuffer;
- size_t encoded;
-};
-}}} // namespace qpid::sys::cyrus
-
-#endif /*!QPID_SYS_CYRUS_CYRUSSECURITYLAYER_H*/
diff --git a/cpp/src/qpid/sys/epoll/EpollPoller.cpp b/cpp/src/qpid/sys/epoll/EpollPoller.cpp
deleted file mode 100644
index 9ad05c71a3..0000000000
--- a/cpp/src/qpid/sys/epoll/EpollPoller.cpp
+++ /dev/null
@@ -1,674 +0,0 @@
-/*
- *
- * 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/sys/Poller.h"
-#include "qpid/sys/IOHandle.h"
-#include "qpid/sys/Mutex.h"
-#include "qpid/sys/AtomicCount.h"
-#include "qpid/sys/DeletionManager.h"
-#include "qpid/sys/posix/check.h"
-#include "qpid/sys/posix/PrivatePosix.h"
-#include "qpid/log/Statement.h"
-
-#include <sys/epoll.h>
-#include <errno.h>
-#include <signal.h>
-
-#include <assert.h>
-#include <queue>
-#include <set>
-#include <exception>
-
-namespace qpid {
-namespace sys {
-
-// Deletion manager to handle deferring deletion of PollerHandles to when they definitely aren't being used
-DeletionManager<PollerHandlePrivate> PollerHandleDeletionManager;
-
-// Instantiate (and define) class static for DeletionManager
-template <>
-DeletionManager<PollerHandlePrivate>::AllThreadsStatuses DeletionManager<PollerHandlePrivate>::allThreadsStatuses(0);
-
-class PollerHandlePrivate {
- friend class Poller;
- friend class PollerPrivate;
- friend class PollerHandle;
-
- enum FDStat {
- ABSENT,
- MONITORED,
- INACTIVE,
- HUNGUP,
- MONITORED_HUNGUP,
- INTERRUPTED,
- INTERRUPTED_HUNGUP,
- DELETED
- };
-
- ::__uint32_t events;
- const IOHandlePrivate* ioHandle;
- PollerHandle* pollerHandle;
- FDStat stat;
- Mutex lock;
-
- PollerHandlePrivate(const IOHandlePrivate* h, PollerHandle* p) :
- events(0),
- ioHandle(h),
- pollerHandle(p),
- stat(ABSENT) {
- }
-
- int fd() const {
- return toFd(ioHandle);
- }
-
- bool isActive() const {
- return stat == MONITORED || stat == MONITORED_HUNGUP;
- }
-
- void setActive() {
- stat = (stat == HUNGUP || stat == INTERRUPTED_HUNGUP)
- ? MONITORED_HUNGUP
- : MONITORED;
- }
-
- bool isInactive() const {
- return stat == INACTIVE || stat == HUNGUP;
- }
-
- void setInactive() {
- stat = INACTIVE;
- }
-
- bool isIdle() const {
- return stat == ABSENT;
- }
-
- void setIdle() {
- stat = ABSENT;
- }
-
- bool isHungup() const {
- return
- stat == MONITORED_HUNGUP ||
- stat == HUNGUP ||
- stat == INTERRUPTED_HUNGUP;
- }
-
- void setHungup() {
- assert(stat == MONITORED);
- stat = HUNGUP;
- }
-
- bool isInterrupted() const {
- return stat == INTERRUPTED || stat == INTERRUPTED_HUNGUP;
- }
-
- void setInterrupted() {
- stat = (stat == MONITORED_HUNGUP || stat == HUNGUP)
- ? INTERRUPTED_HUNGUP
- : INTERRUPTED;
- }
-
- bool isDeleted() const {
- return stat == DELETED;
- }
-
- void setDeleted() {
- stat = DELETED;
- }
-};
-
-PollerHandle::PollerHandle(const IOHandle& h) :
- impl(new PollerHandlePrivate(h.impl, this))
-{}
-
-PollerHandle::~PollerHandle() {
- {
- ScopedLock<Mutex> l(impl->lock);
- if (impl->isDeleted()) {
- return;
- }
- impl->pollerHandle = 0;
- if (impl->isInterrupted()) {
- impl->setDeleted();
- return;
- }
- assert(impl->isIdle());
- impl->setDeleted();
- }
- PollerHandleDeletionManager.markForDeletion(impl);
-}
-
-class HandleSet
-{
- Mutex lock;
- std::set<PollerHandle*> handles;
- public:
- void add(PollerHandle*);
- void remove(PollerHandle*);
- void cleanup();
-};
-
-void HandleSet::add(PollerHandle* h)
-{
- ScopedLock<Mutex> l(lock);
- handles.insert(h);
-}
-void HandleSet::remove(PollerHandle* h)
-{
- ScopedLock<Mutex> l(lock);
- handles.erase(h);
-}
-void HandleSet::cleanup()
-{
- // Inform all registered handles of disconnection
- std::set<PollerHandle*> copy;
- handles.swap(copy);
- for (std::set<PollerHandle*>::const_iterator i = copy.begin(); i != copy.end(); ++i) {
- Poller::Event event(*i, Poller::DISCONNECTED);
- event.process();
- }
-}
-
-/**
- * Concrete implementation of Poller to use the Linux specific epoll
- * interface
- */
-class PollerPrivate {
- friend class Poller;
-
- static const int DefaultFds = 256;
-
- struct ReadablePipe {
- int fds[2];
-
- /**
- * This encapsulates an always readable pipe which we can add
- * to the epoll set to force epoll_wait to return
- */
- ReadablePipe() {
- QPID_POSIX_CHECK(::pipe(fds));
- // Just write the pipe's fds to the pipe
- QPID_POSIX_CHECK(::write(fds[1], fds, 2));
- }
-
- ~ReadablePipe() {
- ::close(fds[0]);
- ::close(fds[1]);
- }
-
- int getFD() {
- return fds[0];
- }
- };
-
- static ReadablePipe alwaysReadable;
- static int alwaysReadableFd;
-
- class InterruptHandle: public PollerHandle {
- std::queue<PollerHandle*> handles;
-
- void processEvent(Poller::EventType) {
- PollerHandle* handle = handles.front();
- handles.pop();
- assert(handle);
-
- // Synthesise event
- Poller::Event event(handle, Poller::INTERRUPTED);
-
- // Process synthesised event
- event.process();
- }
-
- public:
- InterruptHandle() :
- PollerHandle(DummyIOHandle)
- {}
-
- void addHandle(PollerHandle& h) {
- handles.push(&h);
- }
-
- PollerHandle* getHandle() {
- PollerHandle* handle = handles.front();
- handles.pop();
- return handle;
- }
-
- bool queuedHandles() {
- return handles.size() > 0;
- }
- };
-
- const int epollFd;
- bool isShutdown;
- InterruptHandle interruptHandle;
- HandleSet registeredHandles;
- AtomicCount threadCount;
-
- static ::__uint32_t directionToEpollEvent(Poller::Direction dir) {
- switch (dir) {
- case Poller::INPUT: return ::EPOLLIN;
- case Poller::OUTPUT: return ::EPOLLOUT;
- case Poller::INOUT: return ::EPOLLIN | ::EPOLLOUT;
- default: return 0;
- }
- }
-
- static Poller::EventType epollToDirection(::__uint32_t events) {
- // POLLOUT & POLLHUP are mutually exclusive really, but at least socketpairs
- // can give you both!
- events = (events & ::EPOLLHUP) ? events & ~::EPOLLOUT : events;
- ::__uint32_t e = events & (::EPOLLIN | ::EPOLLOUT);
- switch (e) {
- case ::EPOLLIN: return Poller::READABLE;
- case ::EPOLLOUT: return Poller::WRITABLE;
- case ::EPOLLIN | ::EPOLLOUT: return Poller::READ_WRITABLE;
- default:
- return (events & (::EPOLLHUP | ::EPOLLERR)) ?
- Poller::DISCONNECTED : Poller::INVALID;
- }
- }
-
- PollerPrivate() :
- epollFd(::epoll_create(DefaultFds)),
- isShutdown(false) {
- QPID_POSIX_CHECK(epollFd);
- // Add always readable fd into our set (but not listening to it yet)
- ::epoll_event epe;
- epe.events = 0;
- epe.data.u64 = 1;
- QPID_POSIX_CHECK(::epoll_ctl(epollFd, EPOLL_CTL_ADD, alwaysReadableFd, &epe));
- }
-
- ~PollerPrivate() {
- // It's probably okay to ignore any errors here as there can't be data loss
- ::close(epollFd);
-
- // Need to put the interruptHandle in idle state to delete it
- static_cast<PollerHandle&>(interruptHandle).impl->setIdle();
- }
-
- void resetMode(PollerHandlePrivate& handle);
-
- void interrupt() {
- ::epoll_event epe;
- // Use EPOLLONESHOT so we only wake a single thread
- epe.events = ::EPOLLIN | ::EPOLLONESHOT;
- epe.data.u64 = 0; // Keep valgrind happy
- epe.data.ptr = &static_cast<PollerHandle&>(interruptHandle);
- QPID_POSIX_CHECK(::epoll_ctl(epollFd, EPOLL_CTL_MOD, alwaysReadableFd, &epe));
- }
-
- void interruptAll() {
- ::epoll_event epe;
- // Not EPOLLONESHOT, so we eventually get all threads
- epe.events = ::EPOLLIN;
- epe.data.u64 = 2; // Keep valgrind happy
- QPID_POSIX_CHECK(::epoll_ctl(epollFd, EPOLL_CTL_MOD, alwaysReadableFd, &epe));
- }
-};
-
-PollerPrivate::ReadablePipe PollerPrivate::alwaysReadable;
-int PollerPrivate::alwaysReadableFd = alwaysReadable.getFD();
-
-void Poller::registerHandle(PollerHandle& handle) {
- PollerHandlePrivate& eh = *handle.impl;
- ScopedLock<Mutex> l(eh.lock);
- assert(eh.isIdle());
-
- ::epoll_event epe;
- epe.events = ::EPOLLONESHOT;
- epe.data.u64 = 0; // Keep valgrind happy
- epe.data.ptr = &eh;
-
- impl->registeredHandles.add(&handle);
- QPID_POSIX_CHECK(::epoll_ctl(impl->epollFd, EPOLL_CTL_ADD, eh.fd(), &epe));
-
- eh.setActive();
-}
-
-void Poller::unregisterHandle(PollerHandle& handle) {
- PollerHandlePrivate& eh = *handle.impl;
- ScopedLock<Mutex> l(eh.lock);
- assert(!eh.isIdle());
-
- impl->registeredHandles.remove(&handle);
- int rc = ::epoll_ctl(impl->epollFd, EPOLL_CTL_DEL, eh.fd(), 0);
- // Ignore EBADF since deleting a nonexistent fd has the overall required result!
- // And allows the case where a sloppy program closes the fd and then does the delFd()
- if (rc == -1 && errno != EBADF) {
- QPID_POSIX_CHECK(rc);
- }
-
- eh.setIdle();
-}
-
-void PollerPrivate::resetMode(PollerHandlePrivate& eh) {
- PollerHandle* ph;
- {
- ScopedLock<Mutex> l(eh.lock);
- assert(!eh.isActive());
-
- if (eh.isIdle() || eh.isDeleted()) {
- return;
- }
-
- if (eh.events==0) {
- eh.setActive();
- return;
- }
-
- if (!eh.isInterrupted()) {
- ::epoll_event epe;
- epe.events = eh.events | ::EPOLLONESHOT;
- epe.data.u64 = 0; // Keep valgrind happy
- epe.data.ptr = &eh;
-
- QPID_POSIX_CHECK(::epoll_ctl(epollFd, EPOLL_CTL_MOD, eh.fd(), &epe));
-
- eh.setActive();
- return;
- }
- ph = eh.pollerHandle;
- }
-
- PollerHandlePrivate& ihp = *static_cast<PollerHandle&>(interruptHandle).impl;
- ScopedLock<Mutex> l(ihp.lock);
- interruptHandle.addHandle(*ph);
- ihp.setActive();
- interrupt();
-}
-
-void Poller::monitorHandle(PollerHandle& handle, Direction dir) {
- PollerHandlePrivate& eh = *handle.impl;
- ScopedLock<Mutex> l(eh.lock);
- assert(!eh.isIdle());
-
- ::__uint32_t oldEvents = eh.events;
- eh.events |= PollerPrivate::directionToEpollEvent(dir);
-
- // If no change nothing more to do - avoid unnecessary system call
- if (oldEvents==eh.events) {
- return;
- }
-
- // If we're not actually listening wait till we are to perform change
- if (!eh.isActive()) {
- return;
- }
-
- ::epoll_event epe;
- epe.events = eh.events | ::EPOLLONESHOT;
- epe.data.u64 = 0; // Keep valgrind happy
- epe.data.ptr = &eh;
-
- QPID_POSIX_CHECK(::epoll_ctl(impl->epollFd, EPOLL_CTL_MOD, eh.fd(), &epe));
-}
-
-void Poller::unmonitorHandle(PollerHandle& handle, Direction dir) {
- PollerHandlePrivate& eh = *handle.impl;
- ScopedLock<Mutex> l(eh.lock);
- assert(!eh.isIdle());
-
- ::__uint32_t oldEvents = eh.events;
- eh.events &= ~PollerPrivate::directionToEpollEvent(dir);
-
- // If no change nothing more to do - avoid unnecessary system call
- if (oldEvents==eh.events) {
- return;
- }
-
- // If we're not actually listening wait till we are to perform change
- if (!eh.isActive()) {
- return;
- }
-
- ::epoll_event epe;
- epe.events = eh.events | ::EPOLLONESHOT;
- epe.data.u64 = 0; // Keep valgrind happy
- epe.data.ptr = &eh;
-
- QPID_POSIX_CHECK(::epoll_ctl(impl->epollFd, EPOLL_CTL_MOD, eh.fd(), &epe));
-}
-
-void Poller::shutdown() {
- // NB: this function must be async-signal safe, it must not
- // call any function that is not async-signal safe.
-
- // Allow sloppy code to shut us down more than once
- if (impl->isShutdown)
- return;
-
- // Don't use any locking here - isShutdown will be visible to all
- // after the epoll_ctl() anyway (it's a memory barrier)
- impl->isShutdown = true;
-
- impl->interruptAll();
-}
-
-bool Poller::interrupt(PollerHandle& handle) {
- {
- PollerHandlePrivate& eh = *handle.impl;
- ScopedLock<Mutex> l(eh.lock);
- if (eh.isIdle() || eh.isDeleted()) {
- return false;
- }
-
- if (eh.isInterrupted()) {
- return true;
- }
-
- // Stop monitoring handle for read or write
- ::epoll_event epe;
- epe.events = 0;
- epe.data.u64 = 0; // Keep valgrind happy
- epe.data.ptr = &eh;
- QPID_POSIX_CHECK(::epoll_ctl(impl->epollFd, EPOLL_CTL_MOD, eh.fd(), &epe));
-
- if (eh.isInactive()) {
- eh.setInterrupted();
- return true;
- }
- eh.setInterrupted();
- }
-
- PollerPrivate::InterruptHandle& ih = impl->interruptHandle;
- PollerHandlePrivate& eh = *static_cast<PollerHandle&>(ih).impl;
- ScopedLock<Mutex> l(eh.lock);
- ih.addHandle(handle);
-
- impl->interrupt();
- eh.setActive();
- return true;
-}
-
-void Poller::run() {
- // Ensure that we exit thread responsibly under all circumstances
- try {
- // Make sure we can't be interrupted by signals at a bad time
- ::sigset_t ss;
- ::sigfillset(&ss);
- ::pthread_sigmask(SIG_SETMASK, &ss, 0);
-
- ++(impl->threadCount);
- do {
- Event event = wait();
-
- // If can read/write then dispatch appropriate callbacks
- if (event.handle) {
- event.process();
- } else {
- // Handle shutdown
- switch (event.type) {
- case SHUTDOWN:
- PollerHandleDeletionManager.destroyThreadState();
- //last thread to respond to shutdown cleans up:
- if (--(impl->threadCount) == 0) impl->registeredHandles.cleanup();
- return;
- default:
- // This should be impossible
- assert(false);
- }
- }
- } while (true);
- } catch (const std::exception& e) {
- QPID_LOG(error, "IO worker thread exiting with unhandled exception: " << e.what());
- }
- PollerHandleDeletionManager.destroyThreadState();
- --(impl->threadCount);
-}
-
-bool Poller::hasShutdown()
-{
- return impl->isShutdown;
-}
-
-Poller::Event Poller::wait(Duration timeout) {
- static __thread PollerHandlePrivate* lastReturnedHandle = 0;
- epoll_event epe;
- int timeoutMs = (timeout == TIME_INFINITE) ? -1 : timeout / TIME_MSEC;
- AbsTime targetTimeout =
- (timeout == TIME_INFINITE) ?
- FAR_FUTURE :
- AbsTime(now(), timeout);
-
- if (lastReturnedHandle) {
- impl->resetMode(*lastReturnedHandle);
- lastReturnedHandle = 0;
- }
-
- // Repeat until we weren't interrupted by signal
- do {
- PollerHandleDeletionManager.markAllUnusedInThisThread();
- int rc = ::epoll_wait(impl->epollFd, &epe, 1, timeoutMs);
- if (rc ==-1 && errno != EINTR) {
- QPID_POSIX_CHECK(rc);
- } else if (rc > 0) {
- assert(rc == 1);
- void* dataPtr = epe.data.ptr;
-
- // Check if this is an interrupt
- PollerPrivate::InterruptHandle& interruptHandle = impl->interruptHandle;
- if (dataPtr == &interruptHandle) {
- // If we are shutting down we need to rearm the shutdown interrupt to
- // ensure everyone still sees it. It's okay that this might be overridden
- // below as we will be back here if it is.
- if (impl->isShutdown) {
- impl->interruptAll();
- }
- PollerHandle* wrappedHandle = 0;
- {
- ScopedLock<Mutex> l(interruptHandle.impl->lock);
- if (interruptHandle.impl->isActive()) {
- wrappedHandle = interruptHandle.getHandle();
- // If there is an interrupt queued behind this one we need to arm it
- // We do it this way so that another thread can pick it up
- if (interruptHandle.queuedHandles()) {
- impl->interrupt();
- interruptHandle.impl->setActive();
- } else {
- interruptHandle.impl->setInactive();
- }
- }
- }
- if (wrappedHandle) {
- PollerHandlePrivate& eh = *wrappedHandle->impl;
- {
- ScopedLock<Mutex> l(eh.lock);
- if (!eh.isDeleted()) {
- if (!eh.isIdle()) {
- eh.setInactive();
- }
- lastReturnedHandle = &eh;
- assert(eh.pollerHandle == wrappedHandle);
- return Event(wrappedHandle, INTERRUPTED);
- }
- }
- PollerHandleDeletionManager.markForDeletion(&eh);
- }
- continue;
- }
-
- // Check for shutdown
- if (impl->isShutdown) {
- PollerHandleDeletionManager.markAllUnusedInThisThread();
- return Event(0, SHUTDOWN);
- }
-
- PollerHandlePrivate& eh = *static_cast<PollerHandlePrivate*>(dataPtr);
- ScopedLock<Mutex> l(eh.lock);
-
- // the handle could have gone inactive since we left the epoll_wait
- if (eh.isActive()) {
- PollerHandle* handle = eh.pollerHandle;
- assert(handle);
-
- // If the connection has been hungup we could still be readable
- // (just not writable), allow us to readable until we get here again
- if (epe.events & ::EPOLLHUP) {
- if (eh.isHungup()) {
- eh.setInactive();
- // Don't set up last Handle so that we don't reset this handle
- // on re-entering Poller::wait. This means that we will never
- // be set active again once we've returned disconnected, and so
- // can never be returned again.
- return Event(handle, DISCONNECTED);
- }
- eh.setHungup();
- } else {
- eh.setInactive();
- }
- lastReturnedHandle = &eh;
- return Event(handle, PollerPrivate::epollToDirection(epe.events));
- }
- }
- // We only get here if one of the following:
- // * epoll_wait was interrupted by a signal
- // * epoll_wait timed out
- // * the state of the handle changed after being returned by epoll_wait
- //
- // The only things we can do here are return a timeout or wait more.
- // Obviously if we timed out we return timeout; if the wait was meant to
- // be indefinite then we should never return with a time out so we go again.
- // If the wait wasn't indefinite, we check whether we are after the target wait
- // time or not
- if (timeoutMs == -1) {
- continue;
- }
- if (rc == 0 && now() > targetTimeout) {
- PollerHandleDeletionManager.markAllUnusedInThisThread();
- return Event(0, TIMEOUT);
- }
- } while (true);
-}
-
-// Concrete constructors
-Poller::Poller() :
- impl(new PollerPrivate())
-{}
-
-Poller::~Poller() {
- delete impl;
-}
-
-}}
diff --git a/cpp/src/qpid/sys/posix/AsynchIO.cpp b/cpp/src/qpid/sys/posix/AsynchIO.cpp
deleted file mode 100644
index 119a6aa8a4..0000000000
--- a/cpp/src/qpid/sys/posix/AsynchIO.cpp
+++ /dev/null
@@ -1,611 +0,0 @@
-/*
- *
- * 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/sys/AsynchIO.h"
-#include "qpid/sys/Socket.h"
-#include "qpid/sys/SocketAddress.h"
-#include "qpid/sys/Poller.h"
-#include "qpid/sys/DispatchHandle.h"
-#include "qpid/sys/Time.h"
-#include "qpid/log/Statement.h"
-
-#include "qpid/sys/posix/check.h"
-
-// TODO The basic algorithm here is not really POSIX specific and with a
-// bit more abstraction could (should) be promoted to be platform portable
-#include <unistd.h>
-#include <sys/socket.h>
-#include <signal.h>
-#include <errno.h>
-#include <string.h>
-
-#include <boost/bind.hpp>
-#include <boost/lexical_cast.hpp>
-
-using namespace qpid::sys;
-
-namespace {
-
-struct StaticInit {
- StaticInit() {
- /**
- * Make *process* not generate SIGPIPE when writing to closed
- * pipe/socket (necessary as default action is to terminate process)
- */
- ::signal(SIGPIPE, SIG_IGN);
- };
-} init;
-
-/*
- * We keep per thread state to avoid locking overhead. The assumption is that
- * on average all the connections are serviced by all the threads so the state
- * recorded in each thread is about the same. If this turns out not to be the
- * case we could rebalance the info occasionally.
- */
-__thread int threadReadTotal = 0;
-__thread int threadMaxRead = 0;
-__thread int threadReadCount = 0;
-__thread int threadWriteTotal = 0;
-__thread int threadWriteCount = 0;
-__thread int64_t threadMaxReadTimeNs = 2 * 1000000; // start at 2ms
-}
-
-/*
- * Asynch Acceptor
- */
-namespace qpid {
-namespace sys {
-namespace posix {
-
-class AsynchAcceptor : public qpid::sys::AsynchAcceptor {
-public:
- AsynchAcceptor(const Socket& s, AsynchAcceptor::Callback callback);
- ~AsynchAcceptor();
- void start(Poller::shared_ptr poller);
-
-private:
- void readable(DispatchHandle& handle);
-
-private:
- AsynchAcceptor::Callback acceptedCallback;
- DispatchHandle handle;
- const Socket& socket;
-
-};
-
-AsynchAcceptor::AsynchAcceptor(const Socket& s,
- AsynchAcceptor::Callback callback) :
- acceptedCallback(callback),
- handle(s, boost::bind(&AsynchAcceptor::readable, this, _1), 0, 0),
- socket(s) {
-
- s.setNonblocking();
-}
-
-AsynchAcceptor::~AsynchAcceptor() {
- handle.stopWatch();
-}
-
-void AsynchAcceptor::start(Poller::shared_ptr poller) {
- handle.startWatch(poller);
-}
-
-/*
- * We keep on accepting as long as there is something to accept
- */
-void AsynchAcceptor::readable(DispatchHandle& h) {
- Socket* s;
- do {
- errno = 0;
- // TODO: Currently we ignore the peers address, perhaps we should
- // log it or use it for connection acceptance.
- try {
- s = socket.accept();
- if (s) {
- acceptedCallback(*s);
- } else {
- break;
- }
- } catch (const std::exception& e) {
- QPID_LOG(error, "Could not accept socket: " << e.what());
- break;
- }
- } while (true);
-
- h.rewatch();
-}
-
-/*
- * POSIX version of AsynchIO TCP socket connector.
- *
- * The class is implemented in terms of DispatchHandle to allow it to be
- * deleted by deleting the contained DispatchHandle.
- */
-class AsynchConnector : public qpid::sys::AsynchConnector,
- private DispatchHandle {
-
-private:
- void connComplete(DispatchHandle& handle);
-
-private:
- ConnectedCallback connCallback;
- FailedCallback failCallback;
- const Socket& socket;
-
-public:
- AsynchConnector(const Socket& socket,
- std::string hostname,
- uint16_t port,
- ConnectedCallback connCb,
- FailedCallback failCb);
- void start(Poller::shared_ptr poller);
- void stop();
-};
-
-AsynchConnector::AsynchConnector(const Socket& s,
- std::string hostname,
- uint16_t port,
- ConnectedCallback connCb,
- FailedCallback failCb) :
- DispatchHandle(s,
- 0,
- boost::bind(&AsynchConnector::connComplete, this, _1),
- boost::bind(&AsynchConnector::connComplete, this, _1)),
- connCallback(connCb),
- failCallback(failCb),
- socket(s)
-{
- socket.setNonblocking();
- SocketAddress sa(hostname, boost::lexical_cast<std::string>(port));
- // Note, not catching any exceptions here, also has effect of destructing
- socket.connect(sa);
-}
-
-void AsynchConnector::start(Poller::shared_ptr poller)
-{
- startWatch(poller);
-}
-
-void AsynchConnector::stop()
-{
- stopWatch();
-}
-
-void AsynchConnector::connComplete(DispatchHandle& h)
-{
- h.stopWatch();
- int errCode = socket.getError();
- if (errCode == 0) {
- connCallback(socket);
- } else {
- failCallback(socket, errCode, strError(errCode));
- }
- DispatchHandle::doDelete();
-}
-
-/*
- * POSIX version of AsynchIO reader/writer
- *
- * The class is implemented in terms of DispatchHandle to allow it to be
- * deleted by deleting the contained DispatchHandle.
- */
-class AsynchIO : public qpid::sys::AsynchIO, private DispatchHandle {
-
-public:
- AsynchIO(const Socket& s,
- ReadCallback rCb,
- EofCallback eofCb,
- DisconnectCallback disCb,
- ClosedCallback cCb = 0,
- BuffersEmptyCallback eCb = 0,
- IdleCallback iCb = 0);
-
- // Methods inherited from qpid::sys::AsynchIO
-
- virtual void queueForDeletion();
-
- virtual void start(Poller::shared_ptr poller);
- virtual void queueReadBuffer(BufferBase* buff);
- virtual void unread(BufferBase* buff);
- virtual void queueWrite(BufferBase* buff);
- virtual void notifyPendingWrite();
- virtual void queueWriteClose();
- virtual bool writeQueueEmpty();
- virtual void startReading();
- virtual void stopReading();
- virtual void requestCallback(RequestCallback);
- virtual BufferBase* getQueuedBuffer();
-
-private:
- ~AsynchIO();
-
- // Methods that are callback targets from Dispatcher.
- void readable(DispatchHandle& handle);
- void writeable(DispatchHandle& handle);
- void disconnected(DispatchHandle& handle);
- void requestedCall(RequestCallback);
- void close(DispatchHandle& handle);
-
-private:
- ReadCallback readCallback;
- EofCallback eofCallback;
- DisconnectCallback disCallback;
- ClosedCallback closedCallback;
- BuffersEmptyCallback emptyCallback;
- IdleCallback idleCallback;
- const Socket& socket;
- std::deque<BufferBase*> bufferQueue;
- std::deque<BufferBase*> writeQueue;
- bool queuedClose;
- /**
- * This flag is used to detect and handle concurrency between
- * calls to notifyPendingWrite() (which can be made from any thread) and
- * the execution of the writeable() method (which is always on the
- * thread processing this handle.
- */
- volatile bool writePending;
- /**
- * This records whether we've been reading is flow controlled:
- * it's safe as a simple boolean as the only way to be stopped
- * is in calls only allowed in the callback context, the only calls
- * checking it are also in calls only allowed in callback context.
- */
- volatile bool readingStopped;
-};
-
-AsynchIO::AsynchIO(const Socket& s,
- ReadCallback rCb, EofCallback eofCb, DisconnectCallback disCb,
- ClosedCallback cCb, BuffersEmptyCallback eCb, IdleCallback iCb) :
-
- DispatchHandle(s,
- boost::bind(&AsynchIO::readable, this, _1),
- boost::bind(&AsynchIO::writeable, this, _1),
- boost::bind(&AsynchIO::disconnected, this, _1)),
- readCallback(rCb),
- eofCallback(eofCb),
- disCallback(disCb),
- closedCallback(cCb),
- emptyCallback(eCb),
- idleCallback(iCb),
- socket(s),
- queuedClose(false),
- writePending(false),
- readingStopped(false) {
-
- s.setNonblocking();
-}
-
-struct deleter
-{
- template <typename T>
- void operator()(T *ptr){ delete ptr;}
-};
-
-AsynchIO::~AsynchIO() {
- std::for_each( bufferQueue.begin(), bufferQueue.end(), deleter());
- std::for_each( writeQueue.begin(), writeQueue.end(), deleter());
-}
-
-void AsynchIO::queueForDeletion() {
- DispatchHandle::doDelete();
-}
-
-void AsynchIO::start(Poller::shared_ptr poller) {
- DispatchHandle::startWatch(poller);
-}
-
-void AsynchIO::queueReadBuffer(BufferBase* buff) {
- assert(buff);
- buff->dataStart = 0;
- buff->dataCount = 0;
-
- bool queueWasEmpty = bufferQueue.empty();
- bufferQueue.push_back(buff);
- if (queueWasEmpty && !readingStopped)
- DispatchHandle::rewatchRead();
-}
-
-void AsynchIO::unread(BufferBase* buff) {
- assert(buff);
- buff->squish();
-
- bool queueWasEmpty = bufferQueue.empty();
- bufferQueue.push_front(buff);
- if (queueWasEmpty && !readingStopped)
- DispatchHandle::rewatchRead();
-}
-
-void AsynchIO::queueWrite(BufferBase* buff) {
- assert(buff);
- // If we've already closed the socket then throw the write away
- if (queuedClose) {
- queueReadBuffer(buff);
- return;
- } else {
- writeQueue.push_front(buff);
- }
- writePending = false;
- DispatchHandle::rewatchWrite();
-}
-
-// This can happen outside the callback context
-void AsynchIO::notifyPendingWrite() {
- writePending = true;
- DispatchHandle::rewatchWrite();
-}
-
-void AsynchIO::queueWriteClose() {
- queuedClose = true;
- DispatchHandle::rewatchWrite();
-}
-
-bool AsynchIO::writeQueueEmpty() {
- return writeQueue.empty();
-}
-
-// This can happen outside the callback context
-void AsynchIO::startReading() {
- readingStopped = false;
- DispatchHandle::rewatchRead();
-}
-
-void AsynchIO::stopReading() {
- readingStopped = true;
- DispatchHandle::unwatchRead();
-}
-
-void AsynchIO::requestCallback(RequestCallback callback) {
- // TODO creating a function object every time isn't all that
- // efficient - if this becomes heavily used do something better (what?)
- assert(callback);
- DispatchHandle::call(boost::bind(&AsynchIO::requestedCall, this, callback));
-}
-
-void AsynchIO::requestedCall(RequestCallback callback) {
- assert(callback);
- callback(*this);
-}
-
-/** Return a queued buffer if there are enough
- * to spare
- */
-AsynchIO::BufferBase* AsynchIO::getQueuedBuffer() {
- // Always keep at least one buffer (it might have data that was "unread" in it)
- if (bufferQueue.size()<=1)
- return 0;
- BufferBase* buff = bufferQueue.back();
- assert(buff);
- buff->dataStart = 0;
- buff->dataCount = 0;
- bufferQueue.pop_back();
- return buff;
-}
-
-/*
- * We keep on reading as long as we have something to read, a buffer
- * to put it in and reading is not stopped by flow control.
- */
-void AsynchIO::readable(DispatchHandle& h) {
- if (readingStopped) {
- // We have been flow controlled.
- return;
- }
- int readTotal = 0;
- AbsTime readStartTime = AbsTime::now();
- do {
- // (Try to) get a buffer
- if (!bufferQueue.empty()) {
- // Read into buffer
- BufferBase* buff = bufferQueue.front();
- assert(buff);
- bufferQueue.pop_front();
- errno = 0;
- int readCount = buff->byteCount-buff->dataCount;
- int rc = socket.read(buff->bytes + buff->dataCount, readCount);
- if (rc > 0) {
- buff->dataCount += rc;
- threadReadTotal += rc;
- readTotal += rc;
-
- readCallback(*this, buff);
- if (readingStopped) {
- // We have been flow controlled.
- break;
- }
-
- if (rc != readCount) {
- // If we didn't fill the read buffer then time to stop reading
- break;
- }
-
- // Stop reading if we've overrun our timeslot
- if (Duration(readStartTime, AbsTime::now()) > threadMaxReadTimeNs) {
- break;
- }
-
- } else {
- // Put buffer back (at front so it doesn't interfere with unread buffers)
- bufferQueue.push_front(buff);
- assert(buff);
-
- // Eof or other side has gone away
- if (rc == 0 || errno == ECONNRESET) {
- eofCallback(*this);
- h.unwatchRead();
- break;
- } else if (errno == EAGAIN) {
- // We have just put a buffer back so we know
- // we can carry on watching for reads
- break;
- } else {
- // Report error then just treat as a socket disconnect
- QPID_LOG(error, "Error reading socket: " << qpid::sys::strError(errno) << "(" << errno << ")" );
- eofCallback(*this);
- h.unwatchRead();
- break;
- }
- }
- } else {
- // Something to read but no buffer
- if (emptyCallback) {
- emptyCallback(*this);
- }
- // If we still have no buffers we can't do anything more
- if (bufferQueue.empty()) {
- h.unwatchRead();
- break;
- }
-
- }
- } while (true);
-
- ++threadReadCount;
- threadMaxRead = std::max(threadMaxRead, readTotal);
- return;
-}
-
-/*
- * We carry on writing whilst we have data to write and we can write
- */
-void AsynchIO::writeable(DispatchHandle& h) {
- int writeTotal = 0;
- do {
- // See if we've got something to write
- if (!writeQueue.empty()) {
- // Write buffer
- BufferBase* buff = writeQueue.back();
- writeQueue.pop_back();
- errno = 0;
- assert(buff->dataStart+buff->dataCount <= buff->byteCount);
- int rc = socket.write(buff->bytes+buff->dataStart, buff->dataCount);
- if (rc >= 0) {
- threadWriteTotal += rc;
- writeTotal += rc;
-
- // If we didn't write full buffer put rest back
- if (rc != buff->dataCount) {
- buff->dataStart += rc;
- buff->dataCount -= rc;
- writeQueue.push_back(buff);
- break;
- }
-
- // Recycle the buffer
- queueReadBuffer(buff);
-
- // If we've already written more than the max for reading then stop
- // (this is to stop writes dominating reads)
- if (writeTotal > threadMaxRead)
- break;
- } else {
- // Put buffer back
- writeQueue.push_back(buff);
- if (errno == ECONNRESET || errno == EPIPE) {
- // Just stop watching for write here - we'll get a
- // disconnect callback soon enough
- h.unwatchWrite();
- break;
- } else if (errno == EAGAIN) {
- // We have just put a buffer back so we know
- // we can carry on watching for writes
- break;
- } else {
- // Report error then just treat as a socket disconnect
- QPID_LOG(error, "Error writing socket: " << qpid::sys::strError(errno) << "(" << errno << ")" );
- h.unwatchWrite();
- break;
- }
- }
- } else {
- // If we're waiting to close the socket then can do it now as there is nothing to write
- if (queuedClose) {
- close(h);
- break;
- }
- // Fd is writable, but nothing to write
- if (idleCallback) {
- writePending = false;
- idleCallback(*this);
- }
- // If we still have no buffers to write we can't do anything more
- if (writeQueue.empty() && !writePending && !queuedClose) {
- h.unwatchWrite();
- // The following handles the case where writePending is
- // set to true after the test above; in this case its
- // possible that the unwatchWrite overwrites the
- // desired rewatchWrite so we correct that here
- if (writePending)
- h.rewatchWrite();
- break;
- }
- }
- } while (true);
-
- ++threadWriteCount;
- return;
-}
-
-void AsynchIO::disconnected(DispatchHandle& h) {
- // If we have not already queued close then call disconnected callback before closing
- if (!queuedClose && disCallback) disCallback(*this);
- close(h);
-}
-
-/*
- * Close the socket and callback to say we've done it
- */
-void AsynchIO::close(DispatchHandle& h) {
- h.stopWatch();
- socket.close();
- if (closedCallback) {
- closedCallback(*this, socket);
- }
-}
-
-} // namespace posix
-
-AsynchAcceptor* AsynchAcceptor::create(const Socket& s,
- Callback callback)
-{
- return new posix::AsynchAcceptor(s, callback);
-}
-
-AsynchConnector* AsynchConnector::create(const Socket& s,
- std::string hostname,
- uint16_t port,
- ConnectedCallback connCb,
- FailedCallback failCb)
-{
- return new posix::AsynchConnector(s, hostname, port, connCb, failCb);
-}
-
-AsynchIO* AsynchIO::create(const Socket& s,
- AsynchIO::ReadCallback rCb,
- AsynchIO::EofCallback eofCb,
- AsynchIO::DisconnectCallback disCb,
- AsynchIO::ClosedCallback cCb,
- AsynchIO::BuffersEmptyCallback eCb,
- AsynchIO::IdleCallback iCb)
-{
- return new posix::AsynchIO(s, rCb, eofCb, disCb, cCb, eCb, iCb);
-}
-
-}} // namespace qpid::sys
diff --git a/cpp/src/qpid/sys/posix/FileSysDir.cpp b/cpp/src/qpid/sys/posix/FileSysDir.cpp
deleted file mode 100755
index 22dc487e74..0000000000
--- a/cpp/src/qpid/sys/posix/FileSysDir.cpp
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- *
- * 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/sys/FileSysDir.h"
-#include "qpid/sys/StrError.h"
-#include "qpid/Exception.h"
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <cerrno>
-#include <unistd.h>
-
-namespace qpid {
-namespace sys {
-
-bool FileSysDir::exists (void) const
-{
- const char *cpath = dirPath.c_str ();
- struct stat s;
- if (::stat(cpath, &s)) {
- if (errno == ENOENT) {
- return false;
- }
- throw qpid::Exception (strError(errno) +
- ": Can't check directory: " + dirPath);
- }
- if (S_ISDIR(s.st_mode))
- return true;
- throw qpid::Exception(dirPath + " is not a directory");
-}
-
-void FileSysDir::mkdir(void)
-{
- if (::mkdir(dirPath.c_str(), 0755))
- throw Exception ("Can't create directory: " + dirPath);
-}
-
-}} // namespace qpid::sys
diff --git a/cpp/src/qpid/sys/posix/Fork.cpp b/cpp/src/qpid/sys/posix/Fork.cpp
deleted file mode 100644
index a0d404a16e..0000000000
--- a/cpp/src/qpid/sys/posix/Fork.cpp
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- *
- * 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/sys/Fork.h"
-#include "qpid/log/Statement.h"
-#include "qpid/Exception.h"
-
-#include <errno.h>
-#include <fcntl.h>
-#include <signal.h>
-#include <string.h>
-#include <sys/stat.h>
-#include <sys/select.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-namespace qpid {
-namespace sys {
-
-using namespace std;
-
-namespace {
-
-void writeStr(int fd, const std::string& str) {
- const char* WRITE_ERR = "Error writing to parent process";
- int size = str.size();
- if (int(sizeof(size)) > ::write(fd, &size, sizeof(size))) throw ErrnoException(WRITE_ERR);
- if (size > ::write(fd, str.data(), size)) throw ErrnoException(WRITE_ERR);
-}
-
-string readStr(int fd) {
- string value;
- const char* READ_ERR = "Error reading from forked process";
- int size;
- if (int(sizeof(size)) > ::read(fd, &size, sizeof(size))) throw ErrnoException(READ_ERR);
- if (size > 0) { // Read string message
- value.resize(size);
- if (size > ::read(fd, const_cast<char*>(value.data()), size)) throw ErrnoException(READ_ERR);
- }
- return value;
-}
-
-} // namespace
-
-Fork::Fork() {}
-Fork::~Fork() {}
-
-void Fork::fork() {
- pid_t pid = ::fork();
- if (pid < 0) throw ErrnoException("Failed to fork the process");
- if (pid == 0) child();
- else parent(pid);
-}
-
-ForkWithMessage::ForkWithMessage() {
- pipeFds[0] = pipeFds[1] = -1;
-}
-
-struct AutoCloseFd {
- int fd;
- AutoCloseFd(int d) : fd(d) {}
- ~AutoCloseFd() { ::close(fd); }
-};
-
-void ForkWithMessage::fork() {
- if(::pipe(pipeFds) < 0) throw ErrnoException("Can't create pipe");
- pid_t pid = ::fork();
- if(pid < 0) throw ErrnoException("Fork fork failed");
- if (pid == 0) { // Child
- AutoCloseFd ac(pipeFds[1]); // Write side.
- ::close(pipeFds[0]); // Read side
- try {
- child();
- }
- catch (const std::exception& e) {
- QPID_LOG(error, "Error in forked child: " << e.what());
- std::string msg = e.what();
- if (msg.empty()) msg = " "; // Make sure we send a non-empty error string.
- writeStr(pipeFds[1], msg);
- }
- }
- else { // Parent
- close(pipeFds[1]); // Write side.
- AutoCloseFd ac(pipeFds[0]); // Read side
- parent(pid);
- }
-}
-
-string ForkWithMessage::wait(int timeout) { // parent waits for child.
- errno = 0;
- struct timeval tv;
- tv.tv_sec = timeout;
- tv.tv_usec = 0;
-
- fd_set fds;
- FD_ZERO(&fds);
- FD_SET(pipeFds[0], &fds);
- int n=select(FD_SETSIZE, &fds, 0, 0, &tv);
- if(n<0) throw ErrnoException("Error waiting for fork");
- if (n==0) throw Exception("Timed out waiting for fork");
-
- string error = readStr(pipeFds[0]);
- if (error.empty()) return readStr(pipeFds[0]);
- else throw Exception("Error in forked process: " + error);
-}
-
-// Write empty error string followed by value string to pipe.
-void ForkWithMessage::ready(const string& value) { // child
- // Write empty string for error followed by value.
- writeStr(pipeFds[1], string()); // No error
- writeStr(pipeFds[1], value);
-}
-
-
-}} // namespace qpid::sys
diff --git a/cpp/src/qpid/sys/posix/Fork.h b/cpp/src/qpid/sys/posix/Fork.h
deleted file mode 100644
index 698c61ed30..0000000000
--- a/cpp/src/qpid/sys/posix/Fork.h
+++ /dev/null
@@ -1,82 +0,0 @@
-#ifndef QPID_SYS_POSIX_FORK_H
-#define QPID_SYS_POSIX_FORK_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 <string>
-#include <sys/types.h>
-
-namespace qpid {
-namespace sys {
-
-/**
- * Fork the process. Call parent() in parent and child() in child.
- */
-class Fork {
- public:
- Fork();
- virtual ~Fork();
-
- /**
- * Fork the process.
- * Calls parent() in the parent process, child() in the child.
- */
- virtual void fork();
-
- protected:
-
- /** Called in parent process.
- *@child pid of child process
- */
- virtual void parent(pid_t child) = 0;
-
- /** Called in child process */
- virtual void child() = 0;
-};
-
-/**
- * Like Fork but also allows the child to send a string message
- * or throw an exception to the parent.
- */
-class ForkWithMessage : public Fork {
- public:
- ForkWithMessage();
- void fork();
-
- protected:
- /** Call from parent(): wait for child to send a value or throw exception.
- * @timeout in seconds to wait for response.
- * @return value passed by child to ready().
- */
- std::string wait(int timeout);
-
- /** Call from child(): Send a value to the parent.
- *@param value returned by parent call to wait().
- */
- void ready(const std::string& value);
-
- private:
- int pipeFds[2];
-};
-
-}} // namespace qpid::sys
-
-
-
-#endif /*!QPID_SYS_POSIX_FORK_H*/
diff --git a/cpp/src/qpid/sys/posix/IOHandle.cpp b/cpp/src/qpid/sys/posix/IOHandle.cpp
deleted file mode 100644
index 9c049ee1de..0000000000
--- a/cpp/src/qpid/sys/posix/IOHandle.cpp
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- *
- * 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/sys/IOHandle.h"
-
-#include "qpid/sys/posix/PrivatePosix.h"
-
-namespace qpid {
-namespace sys {
-
-int toFd(const IOHandlePrivate* h)
-{
- return h->fd;
-}
-
-NullIOHandle DummyIOHandle;
-
-IOHandle::IOHandle(IOHandlePrivate* h) :
- impl(h)
-{}
-
-IOHandle::~IOHandle() {
- delete impl;
-}
-
-}} // namespace qpid::sys
diff --git a/cpp/src/qpid/sys/posix/LockFile.cpp b/cpp/src/qpid/sys/posix/LockFile.cpp
deleted file mode 100755
index 1862ff6ac9..0000000000
--- a/cpp/src/qpid/sys/posix/LockFile.cpp
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- *
- * Copyright (c) 2008 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/sys/LockFile.h"
-#include "qpid/sys/posix/PidFile.h"
-
-#include <string>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-
-#include "qpid/sys/posix/check.h"
-
-namespace qpid {
-namespace sys {
-
-class LockFilePrivate {
- friend class LockFile;
- friend class PidFile;
-
- int fd;
-
-public:
- LockFilePrivate(int f) : fd(f) {}
-};
-
-LockFile::LockFile(const std::string& path_, bool create)
- : path(path_), created(create) {
-
- errno = 0;
- int flags=create ? O_WRONLY|O_CREAT|O_NOFOLLOW : O_RDWR;
- int fd = ::open(path.c_str(), flags, 0644);
- if (fd < 0) throw ErrnoException("Cannot open " + path, errno);
- if (::lockf(fd, F_TLOCK, 0) < 0) {
- ::close(fd);
- throw ErrnoException("Cannot lock " + path, errno);
- }
- impl.reset(new LockFilePrivate(fd));
-}
-
-LockFile::~LockFile() {
- if (impl) {
- int f = impl->fd;
- if (f >= 0) {
- int unused_ret;
- unused_ret = ::lockf(f, F_ULOCK, 0); // Suppress warnings about ignoring return value.
- ::close(f);
- impl->fd = -1;
- }
- }
-}
-
-int LockFile::read(void* bytes, size_t len) const {
- if (!impl)
- throw Exception("Lock file not open: " + path);
-
- ssize_t rc = ::read(impl->fd, bytes, len);
- if ((ssize_t)len > rc) {
- throw Exception("Cannot read lock file: " + path);
- }
- return rc;
-}
-
-int LockFile::write(void* bytes, size_t len) const {
- if (!impl)
- throw Exception("Lock file not open: " + path);
-
- ssize_t rc = ::write(impl->fd, bytes, len);
- if ((ssize_t)len > rc) {
- throw Exception("Cannot write lock file: " + path);
- }
- return rc;
-}
-
-PidFile::PidFile(const std::string& path_, bool create):
- LockFile(path_, create)
-{}
-
-pid_t PidFile::readPid(void) const {
- pid_t pid;
- int desired_read = sizeof(pid_t);
- read(&pid, desired_read);
- return pid;
-}
-
-void PidFile::writePid(void) {
- pid_t pid = getpid();
- int desired_write = sizeof(pid_t);
- write(&pid, desired_write);
-}
-
-}} /* namespace qpid::sys */
diff --git a/cpp/src/qpid/sys/posix/Mutex.cpp b/cpp/src/qpid/sys/posix/Mutex.cpp
deleted file mode 100644
index 0e1f0d30c2..0000000000
--- a/cpp/src/qpid/sys/posix/Mutex.cpp
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- *
- * 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/sys/Mutex.h"
-
-namespace qpid {
-namespace sys {
-
-/**
- * Initialise a recursive mutex attr for use in creating mutexes later
- * (we use pthread_once to make sure it is initialised exactly once)
- */
-
-namespace {
-pthread_once_t onceControl = PTHREAD_ONCE_INIT;
-pthread_mutexattr_t mutexattr;
-
-void initMutexattr() {
- pthread_mutexattr_init(&mutexattr);
- pthread_mutexattr_settype(&mutexattr, PTHREAD_MUTEX_RECURSIVE);
-}
-}
-
-const pthread_mutexattr_t* Mutex::getAttribute() {
- pthread_once(&onceControl, initMutexattr);
- return &mutexattr;
-}
-
-}} // namespace qpid::sys
diff --git a/cpp/src/qpid/sys/posix/PidFile.h b/cpp/src/qpid/sys/posix/PidFile.h
deleted file mode 100644
index fb19d407f4..0000000000
--- a/cpp/src/qpid/sys/posix/PidFile.h
+++ /dev/null
@@ -1,62 +0,0 @@
-#ifndef _sys_PidFile_h
-#define _sys_PidFile_h
-
-/*
- *
- * Copyright (c) 2008 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/sys/LockFile.h"
-
-#include "qpid/CommonImportExport.h"
-#include "qpid/sys/IntegerTypes.h"
-
-#include <boost/noncopyable.hpp>
-#include <boost/shared_ptr.hpp>
-#include <string>
-
-namespace qpid {
-namespace sys {
-
-class PidFile : public LockFile
-{
-public:
- QPID_COMMON_EXTERN PidFile(const std::string& path_, bool create);
-
- /**
- * Read the process ID from the lock file. This method assumes that
- * if there is a process ID in the file, it was written there by
- * writePid(); thus, it's at the start of the file.
- *
- * Throws an exception if there is an error reading the file.
- *
- * @returns The stored process ID. No validity check is done on it.
- */
- QPID_COMMON_EXTERN pid_t readPid(void) const;
-
- /**
- * Write the current process's ID to the lock file. It's written at
- * the start of the file and will overwrite any other content that
- * may be in the file.
- *
- * Throws an exception if the write fails.
- */
- QPID_COMMON_EXTERN void writePid(void);
-};
-
-}} /* namespace qpid::sys */
-
-#endif /*!_sys_PidFile_h*/
diff --git a/cpp/src/qpid/sys/posix/PipeHandle.cpp b/cpp/src/qpid/sys/posix/PipeHandle.cpp
deleted file mode 100755
index 4b19783338..0000000000
--- a/cpp/src/qpid/sys/posix/PipeHandle.cpp
+++ /dev/null
@@ -1,64 +0,0 @@
-//
-// 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/sys/PipeHandle.h"
-#include "qpid/sys/posix/check.h"
-#include <unistd.h>
-#include <fcntl.h>
-#include <sys/socket.h>
-
-namespace qpid {
-namespace sys {
-
-PipeHandle::PipeHandle(bool nonBlocking) {
-
- int pair[2];
- pair[0] = pair[1] = -1;
-
- if (socketpair(PF_UNIX, SOCK_STREAM, 0, pair) == -1)
- throw qpid::Exception(QPID_MSG("Creation of pipe failed"));
-
- writeFd = pair[0];
- readFd = pair[1];
-
- // Set the socket to non-blocking
- if (nonBlocking) {
- int flags = fcntl(readFd, F_GETFL);
- fcntl(readFd, F_SETFL, flags | O_NONBLOCK);
- }
-}
-
-PipeHandle::~PipeHandle() {
- close(readFd);
- close(writeFd);
-}
-
-int PipeHandle::read(void* buf, size_t bufSize) {
- return ::read(readFd,buf,bufSize);
-}
-
-int PipeHandle::write(const void* buf, size_t bufSize) {
- return ::write(writeFd,buf,bufSize);
-}
-
-int PipeHandle::getReadHandle() {
- return readFd;
-}
-
-}} // namespace qpid::sys
diff --git a/cpp/src/qpid/sys/posix/PollableCondition.cpp b/cpp/src/qpid/sys/posix/PollableCondition.cpp
deleted file mode 100644
index b22a615a54..0000000000
--- a/cpp/src/qpid/sys/posix/PollableCondition.cpp
+++ /dev/null
@@ -1,124 +0,0 @@
-#ifndef QPID_SYS_LINUX_POLLABLECONDITION_CPP
-#define QPID_SYS_LINUX_POLLABLECONDITION_CPP
-
-/*
- *
- * 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/sys/PollableCondition.h"
-#include "qpid/sys/DispatchHandle.h"
-#include "qpid/sys/IOHandle.h"
-#include "qpid/sys/posix/PrivatePosix.h"
-#include "qpid/Exception.h"
-
-#include <boost/bind.hpp>
-
-#include <unistd.h>
-#include <fcntl.h>
-
-namespace qpid {
-namespace sys {
-
-class PollableConditionPrivate : public sys::IOHandle {
- friend class PollableCondition;
-
-private:
- PollableConditionPrivate(const sys::PollableCondition::Callback& cb,
- sys::PollableCondition& parent,
- const boost::shared_ptr<sys::Poller>& poller);
- ~PollableConditionPrivate();
-
- void dispatch(sys::DispatchHandle& h);
- void set();
- void clear();
-
-private:
- PollableCondition::Callback cb;
- PollableCondition& parent;
- boost::shared_ptr<sys::Poller> poller;
- int writeFd;
- std::auto_ptr<DispatchHandleRef> handle;
-};
-
-PollableConditionPrivate::PollableConditionPrivate(
- const sys::PollableCondition::Callback& cb,
- sys::PollableCondition& parent,
- const boost::shared_ptr<sys::Poller>& poller
-) : IOHandle(new sys::IOHandlePrivate), cb(cb), parent(parent)
-{
- int fds[2];
- if (::pipe(fds) == -1)
- throw ErrnoException(QPID_MSG("Can't create PollableCondition"));
- impl->fd = fds[0];
- writeFd = fds[1];
- if (::fcntl(impl->fd, F_SETFL, O_NONBLOCK) == -1)
- throw ErrnoException(QPID_MSG("Can't create PollableCondition"));
- if (::fcntl(writeFd, F_SETFL, O_NONBLOCK) == -1)
- throw ErrnoException(QPID_MSG("Can't create PollableCondition"));
- handle.reset (new DispatchHandleRef(
- *this,
- boost::bind(&sys::PollableConditionPrivate::dispatch, this, _1),
- 0, 0));
- handle->startWatch(poller);
- handle->unwatch();
-
- // Make the read FD readable
- static const char dummy=0;
- ssize_t n = ::write(writeFd, &dummy, 1);
- if (n == -1 && errno != EAGAIN)
- throw ErrnoException("Error setting PollableCondition");
-}
-
-PollableConditionPrivate::~PollableConditionPrivate() {
- handle->stopWatch();
- close(writeFd);
-}
-
-void PollableConditionPrivate::dispatch(sys::DispatchHandle&) {
- cb(parent);
-}
-
-void PollableConditionPrivate::set() {
- handle->rewatch();
-}
-
-void PollableConditionPrivate::clear() {
- handle->unwatch();
-}
-
-
-PollableCondition::PollableCondition(const Callback& cb,
- const boost::shared_ptr<sys::Poller>& poller
-) : impl(new PollableConditionPrivate(cb, *this, poller))
-{
-}
-
-PollableCondition::~PollableCondition()
-{
- delete impl;
-}
-
-void PollableCondition::set() { impl->set(); }
-
-void PollableCondition::clear() { impl->clear(); }
-
-}} // namespace qpid::sys
-
-#endif /*!QPID_SYS_LINUX_POLLABLECONDITION_CPP*/
diff --git a/cpp/src/qpid/sys/posix/Shlib.cpp b/cpp/src/qpid/sys/posix/Shlib.cpp
deleted file mode 100644
index 3fb685d5b8..0000000000
--- a/cpp/src/qpid/sys/posix/Shlib.cpp
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * 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/sys/Shlib.h"
-#include "qpid/Exception.h"
-#include "qpid/Msg.h"
-#include <dlfcn.h>
-
-
-namespace qpid {
-namespace sys {
-
-void Shlib::load(const char* name) {
- ::dlerror();
- handle = ::dlopen(name, RTLD_NOW);
- const char* error = ::dlerror();
- if (error) {
- throw Exception(QPID_MSG(error << ": " << name));
- }
-}
-
-void Shlib::unload() {
- if (handle) {
- ::dlerror();
- ::dlclose(handle);
- const char* error = ::dlerror();
- if (error) {
- throw Exception(QPID_MSG(error));
- }
- handle = 0;
- }
-}
-
-void* Shlib::getSymbol(const char* name) {
- ::dlerror();
- void* sym = ::dlsym(handle, name);
- const char* error = ::dlerror();
- if (error)
- throw Exception(QPID_MSG(error << ": " << name));
- return sym;
-}
-
-}} // namespace qpid::sys
diff --git a/cpp/src/qpid/sys/posix/Socket.cpp b/cpp/src/qpid/sys/posix/Socket.cpp
deleted file mode 100644
index 3449a753e3..0000000000
--- a/cpp/src/qpid/sys/posix/Socket.cpp
+++ /dev/null
@@ -1,294 +0,0 @@
-/*
- *
- * 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/sys/Socket.h"
-
-#include "qpid/sys/SocketAddress.h"
-#include "qpid/sys/posix/check.h"
-#include "qpid/sys/posix/PrivatePosix.h"
-
-#include <fcntl.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/errno.h>
-#include <netinet/in.h>
-#include <netinet/tcp.h>
-#include <netdb.h>
-#include <cstdlib>
-#include <string.h>
-#include <iostream>
-
-#include <boost/format.hpp>
-#include <boost/lexical_cast.hpp>
-
-namespace qpid {
-namespace sys {
-
-namespace {
-std::string getName(int fd, bool local, bool includeService = false)
-{
- ::sockaddr_storage name; // big enough for any socket address
- ::socklen_t namelen = sizeof(name);
-
- int result = -1;
- if (local) {
- result = ::getsockname(fd, (::sockaddr*)&name, &namelen);
- } else {
- result = ::getpeername(fd, (::sockaddr*)&name, &namelen);
- }
-
- QPID_POSIX_CHECK(result);
-
- char servName[NI_MAXSERV];
- char dispName[NI_MAXHOST];
- if (includeService) {
- if (int rc=::getnameinfo((::sockaddr*)&name, namelen, dispName, sizeof(dispName),
- servName, sizeof(servName),
- NI_NUMERICHOST | NI_NUMERICSERV) != 0)
- throw QPID_POSIX_ERROR(rc);
- return std::string(dispName) + ":" + std::string(servName);
-
- } else {
- if (int rc=::getnameinfo((::sockaddr*)&name, namelen, dispName, sizeof(dispName), 0, 0, NI_NUMERICHOST) != 0)
- throw QPID_POSIX_ERROR(rc);
- return dispName;
- }
-}
-
-std::string getService(int fd, bool local)
-{
- ::sockaddr_storage name; // big enough for any socket address
- ::socklen_t namelen = sizeof(name);
-
- int result = -1;
- if (local) {
- result = ::getsockname(fd, (::sockaddr*)&name, &namelen);
- } else {
- result = ::getpeername(fd, (::sockaddr*)&name, &namelen);
- }
-
- QPID_POSIX_CHECK(result);
-
- char servName[NI_MAXSERV];
- if (int rc=::getnameinfo((::sockaddr*)&name, namelen, 0, 0,
- servName, sizeof(servName),
- NI_NUMERICHOST | NI_NUMERICSERV) != 0)
- throw QPID_POSIX_ERROR(rc);
- return servName;
-}
-}
-
-Socket::Socket() :
- IOHandle(new IOHandlePrivate),
- nonblocking(false),
- nodelay(false)
-{}
-
-Socket::Socket(IOHandlePrivate* h) :
- IOHandle(h),
- nonblocking(false),
- nodelay(false)
-{}
-
-void Socket::createSocket(const SocketAddress& sa) const
-{
- int& socket = impl->fd;
- if (socket != -1) Socket::close();
- int s = ::socket(getAddrInfo(sa).ai_family, getAddrInfo(sa).ai_socktype, 0);
- if (s < 0) throw QPID_POSIX_ERROR(errno);
- socket = s;
-
- try {
- if (nonblocking) setNonblocking();
- if (nodelay) setTcpNoDelay();
- } catch (std::exception&) {
- ::close(s);
- socket = -1;
- throw;
- }
-}
-
-void Socket::setTimeout(const Duration& interval) const
-{
- const int& socket = impl->fd;
- struct timeval tv;
- toTimeval(tv, interval);
- setsockopt(socket, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv));
- setsockopt(socket, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
-}
-
-void Socket::setNonblocking() const {
- int& socket = impl->fd;
- nonblocking = true;
- if (socket != -1) {
- QPID_POSIX_CHECK(::fcntl(socket, F_SETFL, O_NONBLOCK));
- }
-}
-
-void Socket::setTcpNoDelay() const
-{
- int& socket = impl->fd;
- nodelay = true;
- if (socket != -1) {
- int flag = 1;
- int result = setsockopt(impl->fd, IPPROTO_TCP, TCP_NODELAY, (char *)&flag, sizeof(flag));
- QPID_POSIX_CHECK(result);
- }
-}
-
-void Socket::connect(const std::string& host, uint16_t port) const
-{
- SocketAddress sa(host, boost::lexical_cast<std::string>(port));
- connect(sa);
-}
-
-void Socket::connect(const SocketAddress& addr) const
-{
- connectname = addr.asString();
-
- createSocket(addr);
-
- const int& socket = impl->fd;
- // TODO the correct thing to do here is loop on failure until you've used all the returned addresses
- if ((::connect(socket, getAddrInfo(addr).ai_addr, getAddrInfo(addr).ai_addrlen) < 0) &&
- (errno != EINPROGRESS)) {
- throw Exception(QPID_MSG(strError(errno) << ": " << connectname));
- }
- // When connecting to a port on the same host which no longer has
- // a process associated with it, the OS occasionally chooses the
- // remote port (which is unoccupied) as the port to bind the local
- // end of the socket, resulting in a "circular" connection.
- //
- // This seems like something the OS should prevent but I have
- // confirmed that sporadic hangs in
- // cluster_tests.LongTests.test_failover on RHEL5 are caused by
- // such a circular connection.
- //
- // Raise an error if we see such a connection, since we know there is
- // no listener on the peer address.
- //
- if (getLocalAddress() == getPeerAddress()) {
- close();
- throw Exception(QPID_MSG("Connection refused: " << connectname));
- }
-}
-
-void
-Socket::close() const
-{
- int& socket = impl->fd;
- if (socket == -1) return;
- if (::close(socket) < 0) throw QPID_POSIX_ERROR(errno);
- socket = -1;
-}
-
-int Socket::listen(uint16_t port, int backlog) const
-{
- SocketAddress sa("", boost::lexical_cast<std::string>(port));
- return listen(sa, backlog);
-}
-
-int Socket::listen(const SocketAddress& sa, int backlog) const
-{
- createSocket(sa);
-
- const int& socket = impl->fd;
- int yes=1;
- QPID_POSIX_CHECK(setsockopt(socket,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(yes)));
-
- if (::bind(socket, getAddrInfo(sa).ai_addr, getAddrInfo(sa).ai_addrlen) < 0)
- throw Exception(QPID_MSG("Can't bind to port " << sa.asString() << ": " << strError(errno)));
- if (::listen(socket, backlog) < 0)
- throw Exception(QPID_MSG("Can't listen on port " << sa.asString() << ": " << strError(errno)));
-
- struct sockaddr_in name;
- socklen_t namelen = sizeof(name);
- if (::getsockname(socket, (struct sockaddr*)&name, &namelen) < 0)
- throw QPID_POSIX_ERROR(errno);
-
- return ntohs(name.sin_port);
-}
-
-Socket* Socket::accept() const
-{
- int afd = ::accept(impl->fd, 0, 0);
- if ( afd >= 0)
- return new Socket(new IOHandlePrivate(afd));
- else if (errno == EAGAIN)
- return 0;
- else throw QPID_POSIX_ERROR(errno);
-}
-
-int Socket::read(void *buf, size_t count) const
-{
- return ::read(impl->fd, buf, count);
-}
-
-int Socket::write(const void *buf, size_t count) const
-{
- return ::write(impl->fd, buf, count);
-}
-
-std::string Socket::getSockname() const
-{
- return getName(impl->fd, true);
-}
-
-std::string Socket::getPeername() const
-{
- return getName(impl->fd, false);
-}
-
-std::string Socket::getPeerAddress() const
-{
- if (connectname.empty()) {
- connectname = getName(impl->fd, false, true);
- }
- return connectname;
-}
-
-std::string Socket::getLocalAddress() const
-{
- return getName(impl->fd, true, true);
-}
-
-uint16_t Socket::getLocalPort() const
-{
- return std::atoi(getService(impl->fd, true).c_str());
-}
-
-uint16_t Socket::getRemotePort() const
-{
- return std::atoi(getService(impl->fd, true).c_str());
-}
-
-int Socket::getError() const
-{
- int result;
- socklen_t rSize = sizeof (result);
-
- if (::getsockopt(impl->fd, SOL_SOCKET, SO_ERROR, &result, &rSize) < 0)
- throw QPID_POSIX_ERROR(errno);
-
- return result;
-}
-
-}} // namespace qpid::sys
diff --git a/cpp/src/qpid/sys/posix/SocketAddress.cpp b/cpp/src/qpid/sys/posix/SocketAddress.cpp
deleted file mode 100644
index 8f5f29d793..0000000000
--- a/cpp/src/qpid/sys/posix/SocketAddress.cpp
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- *
- * 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/sys/SocketAddress.h"
-
-#include "qpid/sys/posix/check.h"
-
-#include <sys/socket.h>
-#include <string.h>
-#include <netdb.h>
-
-namespace qpid {
-namespace sys {
-
-SocketAddress::SocketAddress(const std::string& host0, const std::string& port0) :
- host(host0),
- port(port0),
- addrInfo(0)
-{
-}
-
-SocketAddress::SocketAddress(const SocketAddress& sa) :
- host(sa.host),
- port(sa.port),
- addrInfo(0)
-{
-}
-
-SocketAddress& SocketAddress::operator=(const SocketAddress& sa)
-{
- if (&sa != this) {
- host = sa.host;
- port = sa.port;
-
- if (addrInfo) {
- ::freeaddrinfo(addrInfo);
- addrInfo = 0;
- }
- }
- return *this;
-}
-
-SocketAddress::~SocketAddress()
-{
- if (addrInfo) {
- ::freeaddrinfo(addrInfo);
- }
-}
-
-std::string SocketAddress::asString() const
-{
- return host + ":" + port;
-}
-
-const ::addrinfo& getAddrInfo(const SocketAddress& sa)
-{
- if (!sa.addrInfo) {
- ::addrinfo hints;
- ::memset(&hints, 0, sizeof(hints));
- hints.ai_family = AF_INET; // Change this to support IPv6
- hints.ai_socktype = SOCK_STREAM;
-
- const char* node = 0;
- if (sa.host.empty()) {
- hints.ai_flags |= AI_PASSIVE;
- } else {
- node = sa.host.c_str();
- }
- const char* service = sa.port.empty() ? "0" : sa.port.c_str();
-
- int n = ::getaddrinfo(node, service, &hints, &sa.addrInfo);
- if (n != 0)
- throw Exception(QPID_MSG("Cannot resolve " << sa.host << ": " << ::gai_strerror(n)));
- }
-
- return *sa.addrInfo;
-}
-
-}}
diff --git a/cpp/src/qpid/sys/posix/StrError.cpp b/cpp/src/qpid/sys/posix/StrError.cpp
deleted file mode 100644
index 633e20213c..0000000000
--- a/cpp/src/qpid/sys/posix/StrError.cpp
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- *
- * 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/sys/StrError.h"
-
-#include <string.h>
-
-namespace qpid {
-namespace sys {
-
-std::string strError(int err) {
- char buf[512] = "Unknown error";
-#ifdef _GNU_SOURCE
- // GNU strerror_r returns the message
- return ::strerror_r(err, buf, sizeof(buf));
-#else
- // POSIX strerror_r doesn't return the buffer
- ::strerror_r(err, buf, sizeof(buf));
- return std::string(buf);
-#endif
-}
-
-}}
diff --git a/cpp/src/qpid/sys/posix/SystemInfo.cpp b/cpp/src/qpid/sys/posix/SystemInfo.cpp
deleted file mode 100755
index a19ab6885c..0000000000
--- a/cpp/src/qpid/sys/posix/SystemInfo.cpp
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- * 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/sys/SystemInfo.h"
-
-#include "qpid/sys/posix/check.h"
-
-#include <sys/ioctl.h>
-#include <sys/utsname.h>
-#include <sys/types.h> // For FreeBSD
-#include <sys/socket.h> // For FreeBSD
-#include <netinet/in.h> // For FreeBSD
-#include <ifaddrs.h>
-#include <iostream>
-#include <fstream>
-#include <sstream>
-#include <netdb.h>
-
-#ifndef HOST_NAME_MAX
-# define HOST_NAME_MAX 256
-#endif
-
-using namespace std;
-
-namespace qpid {
-namespace sys {
-
-long SystemInfo::concurrency() {
-#ifdef _SC_NPROCESSORS_ONLN // Linux specific.
- return sysconf(_SC_NPROCESSORS_ONLN);
-#else
- return -1;
-#endif
-}
-
-bool SystemInfo::getLocalHostname (Address &address) {
- char name[HOST_NAME_MAX];
- if (::gethostname(name, sizeof(name)) != 0)
- return false;
- address.host = name;
- return true;
-}
-
-static const string LOCALHOST("127.0.0.1");
-static const string TCP("tcp");
-
-void SystemInfo::getLocalIpAddresses (uint16_t port,
- std::vector<Address> &addrList) {
- ::ifaddrs* ifaddr = 0;
- QPID_POSIX_CHECK(::getifaddrs(&ifaddr));
- for (::ifaddrs* ifap = ifaddr; ifap != 0; ifap = ifap->ifa_next) {
- if (ifap->ifa_addr == 0) continue;
-
- int family = ifap->ifa_addr->sa_family;
- switch (family) {
- case AF_INET: {
- char dispName[NI_MAXHOST];
- int rc = ::getnameinfo(
- ifap->ifa_addr,
- (family == AF_INET)
- ? sizeof(struct sockaddr_in)
- : sizeof(struct sockaddr_in6),
- dispName, sizeof(dispName),
- 0, 0, NI_NUMERICHOST);
- if (rc != 0) {
- throw QPID_POSIX_ERROR(rc);
- }
- string addr(dispName);
- if (addr != LOCALHOST) {
- addrList.push_back(Address(TCP, addr, port));
- }
- break;
- }
- // TODO: Url parsing currently can't cope with IPv6 addresses so don't return them
- // when it can cope move this line to above "case AF_INET:"
- case AF_INET6:
- default:
- continue;
- }
- }
- freeifaddrs(ifaddr);
-
- if (addrList.empty()) {
- addrList.push_back(Address(TCP, LOCALHOST, port));
- }
-}
-
-void SystemInfo::getSystemId (std::string &osName,
- std::string &nodeName,
- std::string &release,
- std::string &version,
- std::string &machine)
-{
- struct utsname _uname;
- if (uname (&_uname) == 0)
- {
- osName = _uname.sysname;
- nodeName = _uname.nodename;
- release = _uname.release;
- version = _uname.version;
- machine = _uname.machine;
- }
-}
-
-uint32_t SystemInfo::getProcessId()
-{
- return (uint32_t) ::getpid();
-}
-
-uint32_t SystemInfo::getParentProcessId()
-{
- return (uint32_t) ::getppid();
-}
-
-// Linux specific (Solaris has quite different stuff in /proc)
-string SystemInfo::getProcessName()
-{
- string value;
-
- ifstream input("/proc/self/status");
- if (input.good()) {
- while (!input.eof()) {
- string key;
- input >> key;
- if (key == "Name:") {
- input >> value;
- break;
- }
- }
- input.close();
- }
-
- return value;
-}
-
-}} // namespace qpid::sys
diff --git a/cpp/src/qpid/sys/posix/Thread.cpp b/cpp/src/qpid/sys/posix/Thread.cpp
deleted file mode 100644
index a1d6396763..0000000000
--- a/cpp/src/qpid/sys/posix/Thread.cpp
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- *
- * 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/sys/Thread.h"
-
-#include "qpid/sys/Runnable.h"
-#include "qpid/sys/posix/check.h"
-
-#include <pthread.h>
-
-namespace qpid {
-namespace sys {
-
-namespace {
-void* runRunnable(void* p)
-{
- static_cast<Runnable*>(p)->run();
- return 0;
-}
-}
-
-class ThreadPrivate {
-public:
- pthread_t thread;
-
- ThreadPrivate(Runnable* runnable) {
- QPID_POSIX_ASSERT_THROW_IF(::pthread_create(&thread, NULL, runRunnable, runnable));
- }
-
- ThreadPrivate() : thread(::pthread_self()) {}
-};
-
-Thread::Thread() {}
-
-Thread::Thread(Runnable* runnable) : impl(new ThreadPrivate(runnable)) {}
-
-Thread::Thread(Runnable& runnable) : impl(new ThreadPrivate(&runnable)) {}
-
-Thread::operator bool() {
- return impl;
-}
-
-bool Thread::operator==(const Thread& t) const {
- return ::pthread_equal(impl->thread, t.impl->thread) != 0;
-}
-
-bool Thread::operator!=(const Thread& t) const {
- return !(*this==t);
-}
-
-void Thread::join(){
- if (impl) {
- QPID_POSIX_ASSERT_THROW_IF(::pthread_join(impl->thread, 0));
- }
-}
-
-unsigned long Thread::logId() {
- // This does need to be the C cast operator as
- // pthread_t could be either a pointer or an integer
- // and so we can't know static_cast<> or reinterpret_cast<>
- return (unsigned long) ::pthread_self();
-}
-
-Thread Thread::current() {
- Thread t;
- t.impl.reset(new ThreadPrivate());
- return t;
-}
-
-}}
diff --git a/cpp/src/qpid/sys/posix/Time.cpp b/cpp/src/qpid/sys/posix/Time.cpp
deleted file mode 100644
index 9661f0c5e8..0000000000
--- a/cpp/src/qpid/sys/posix/Time.cpp
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- *
- * 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/sys/posix/PrivatePosix.h"
-
-#include "qpid/sys/Time.h"
-#include <ostream>
-#include <time.h>
-#include <stdio.h>
-#include <sys/time.h>
-#include <unistd.h>
-#include <iomanip>
-
-namespace {
-int64_t max_abstime() { return std::numeric_limits<int64_t>::max(); }
-}
-
-namespace qpid {
-namespace sys {
-
-AbsTime::AbsTime(const AbsTime& t, const Duration& d) :
- timepoint(d == Duration::max() ? max_abstime() : t.timepoint+d.nanosecs)
-{}
-
-AbsTime AbsTime::Epoch() {
- AbsTime epoch; epoch.timepoint = 0;
- return epoch;
-}
-
-AbsTime AbsTime::FarFuture() {
- AbsTime ff; ff.timepoint = max_abstime(); return ff;
-}
-
-AbsTime AbsTime::now() {
- struct timespec ts;
- ::clock_gettime(CLOCK_REALTIME, &ts);
- AbsTime time_now;
- time_now.timepoint = toTime(ts).nanosecs;
- return time_now;
-}
-
-Duration::Duration(const AbsTime& start, const AbsTime& finish) :
- nanosecs(finish.timepoint - start.timepoint)
-{}
-
-struct timespec& toTimespec(struct timespec& ts, const Duration& t) {
- ts.tv_sec = t / TIME_SEC;
- ts.tv_nsec = t % TIME_SEC;
- return ts;
-}
-
-struct timeval& toTimeval(struct timeval& tv, const Duration& t) {
- tv.tv_sec = t/TIME_SEC;
- tv.tv_usec = (t%TIME_SEC)/TIME_USEC;
- return tv;
-}
-
-Duration toTime(const struct timespec& ts) {
- return ts.tv_sec*TIME_SEC + ts.tv_nsec;
-}
-
-std::ostream& operator<<(std::ostream& o, const Duration& d) {
- return o << int64_t(d) << "ns";
-}
-
-namespace {
-inline std::ostream& outputFormattedTime(std::ostream& o, const ::time_t* time) {
- ::tm timeinfo;
- char time_string[100];
- ::strftime(time_string, 100,
- "%Y-%m-%d %H:%M:%S",
- localtime_r(time, &timeinfo));
- return o << time_string;
-}
-}
-
-std::ostream& operator<<(std::ostream& o, const AbsTime& t) {
- ::time_t rawtime(t.timepoint/TIME_SEC);
- return outputFormattedTime(o, &rawtime);
-}
-
-void outputFormattedNow(std::ostream& o) {
- ::time_t rawtime;
- ::time(&rawtime);
- outputFormattedTime(o, &rawtime);
- o << " ";
-}
-
-void outputHiresNow(std::ostream& o) {
- ::timespec time;
- ::clock_gettime(CLOCK_REALTIME, &time);
- o << time.tv_sec << "." << std::setw(9) << std::setfill('0') << time.tv_nsec << "s ";
-}
-
-void sleep(int secs) {
- ::sleep(secs);
-}
-
-void usleep(uint64_t usecs) {
- ::usleep(usecs);
-}
-
-}}
diff --git a/cpp/src/qpid/sys/rdma/RdmaClient.cpp b/cpp/src/qpid/sys/rdma/RdmaClient.cpp
deleted file mode 100644
index 38e9b59541..0000000000
--- a/cpp/src/qpid/sys/rdma/RdmaClient.cpp
+++ /dev/null
@@ -1,247 +0,0 @@
-/*
- *
- * 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/sys/rdma/RdmaIO.h"
-#include "qpid/sys/rdma/rdma_exception.h"
-#include "qpid/sys/Time.h"
-#include "qpid/sys/Thread.h"
-
-#include <netdb.h>
-#include <arpa/inet.h>
-
-#include <vector>
-#include <string>
-#include <iostream>
-#include <algorithm>
-#include <cmath>
-#include <boost/bind.hpp>
-
-using std::vector;
-using std::string;
-using std::cout;
-using std::cerr;
-using std::copy;
-using std::rand;
-
-using qpid::sys::Thread;
-using qpid::sys::Poller;
-using qpid::sys::Dispatcher;
-using qpid::sys::SocketAddress;
-using qpid::sys::AbsTime;
-using qpid::sys::Duration;
-using qpid::sys::TIME_SEC;
-using qpid::sys::TIME_INFINITE;
-
-namespace qpid {
-namespace tests {
-
-// count of messages
-int64_t smsgs = 0;
-int64_t sbytes = 0;
-int64_t rmsgs = 0;
-int64_t rbytes = 0;
-
-int target = 1000000;
-int msgsize = 200;
-AbsTime startTime;
-Duration sendingDuration(TIME_INFINITE);
-Duration fullTestDuration(TIME_INFINITE);
-
-// Random generator
-// This is an RNG designed by George Marsaglia see http://en.wikipedia.org/wiki/Xorshift
-class Xor128Generator {
- uint32_t x;
- uint32_t y;
- uint32_t z;
- uint32_t w;
-
-public:
- Xor128Generator() :
- x(123456789),y(362436069),z(521288629),w(88675123)
- {++(*this);}
-
- Xor128Generator& operator++() {
- uint32_t t = x ^ (x << 11);
- x = y; y = z; z = w;
- w = w ^ (w >> 19) ^ t ^ (t >> 8);
- return *this;
- }
-
- uint32_t operator*() {
- return w;
- }
-};
-
-Xor128Generator output;
-Xor128Generator input;
-
-void write(Rdma::AsynchIO& aio) {
- while (aio.writable() && smsgs < target) {
- Rdma::Buffer* b = aio.getSendBuffer();
- if (!b) break;
- b->dataCount(msgsize);
- uint32_t* ip = reinterpret_cast<uint32_t*>(b->bytes());
- uint32_t* lip = ip + b->dataCount() / sizeof(uint32_t);
- while (ip != lip) {*ip++ = *output; ++output;}
- aio.queueWrite(b);
- ++smsgs;
- sbytes += msgsize;
- }
-}
-
-void dataError(Rdma::AsynchIO&) {
- cout << "Data error:\n";
-}
-
-void data(Poller::shared_ptr p, Rdma::AsynchIO& aio, Rdma::Buffer* b) {
- ++rmsgs;
- rbytes += b->dataCount();
-
- // Check message is unaltered
- bool match = true;
- uint32_t* ip = reinterpret_cast<uint32_t*>(b->bytes());
- uint32_t* lip = ip + b->dataCount() / sizeof(uint32_t);
- while (ip != lip) { if (*ip++ != *input) {match = false; break;} ++input;}
- if (!match) {
- cout << "Data doesn't match: at msg " << rmsgs << " byte " << rbytes-b->dataCount() << " (ish)\n";
- exit(1);
- }
-
- // When all messages have been recvd stop
- if (rmsgs < target) {
- write(aio);
- } else {
- fullTestDuration = std::min(fullTestDuration, Duration(startTime, AbsTime::now()));
- if (aio.incompletedWrites() == 0)
- p->shutdown();
- }
-}
-
-void full(Rdma::AsynchIO& a, Rdma::Buffer* b) {
- // Warn as we shouldn't get here anymore
- cerr << "!";
-
- // Don't need to keep buffer just adjust the counts
- --smsgs;
- sbytes -= b->dataCount();
-
- // Give buffer back
- a.returnSendBuffer(b);
-}
-
-void idle(Poller::shared_ptr p, Rdma::AsynchIO& aio) {
- if (smsgs < target) {
- write(aio);
- } else {
- sendingDuration = std::min(sendingDuration, Duration(startTime, AbsTime::now()));
- if (rmsgs >= target && aio.incompletedWrites() == 0)
- p->shutdown();
- }
-}
-
-void drained(Rdma::AsynchIO&) {
- cout << "Drained:\n";
-}
-
-void connected(Poller::shared_ptr poller, Rdma::Connection::intrusive_ptr& ci, const Rdma::ConnectionParams& cp) {
- cout << "Connected\n";
- Rdma::QueuePair::intrusive_ptr q = ci->getQueuePair();
-
- Rdma::AsynchIO* aio = new Rdma::AsynchIO(ci->getQueuePair(),
- cp.rdmaProtocolVersion,
- cp.maxRecvBufferSize, cp.initialXmitCredit , Rdma::DEFAULT_WR_ENTRIES,
- boost::bind(&data, poller, _1, _2),
- boost::bind(&idle, poller, _1),
- &full,
- dataError);
-
- startTime = AbsTime::now();
- write(*aio);
-
- aio->start(poller);
-}
-
-void disconnected(boost::shared_ptr<Poller> p, Rdma::Connection::intrusive_ptr&) {
- cout << "Disconnected\n";
- p->shutdown();
-}
-
-void connectionError(boost::shared_ptr<Poller> p, Rdma::Connection::intrusive_ptr&, const Rdma::ErrorType) {
- cout << "Connection error\n";
- p->shutdown();
-}
-
-void rejected(boost::shared_ptr<Poller> p, Rdma::Connection::intrusive_ptr&, const Rdma::ConnectionParams&) {
- cout << "Connection rejected\n";
- p->shutdown();
-}
-
-}} // namespace qpid::tests
-
-using namespace qpid::tests;
-
-int main(int argc, char* argv[]) {
- vector<string> args(&argv[0], &argv[argc]);
-
- string host = args[1];
- string port = (args.size() < 3) ? "20079" : args[2];
-
- if (args.size() > 3)
- msgsize = atoi(args[3].c_str());
- cout << "Message size: " << msgsize << "\n";
-
- try {
- boost::shared_ptr<Poller> p(new Poller());
-
- Rdma::Connector c(
- Rdma::ConnectionParams(msgsize, Rdma::DEFAULT_WR_ENTRIES),
- boost::bind(&connected, p, _1, _2),
- boost::bind(&connectionError, p, _1, _2),
- boost::bind(&disconnected, p, _1),
- boost::bind(&rejected, p, _1, _2));
-
- SocketAddress sa(host, port);
- cout << "Connecting to: " << sa.asString() <<"\n";
- c.start(p, sa);
-
- // The poller loop blocks all signals so run in its own thread
- Thread t(*p);
- t.join();
- } catch (Rdma::Exception& e) {
- int err = e.getError();
- cerr << "Error: " << e.what() << "(" << err << ")\n";
- }
-
- cout
- << "Sent: " << smsgs
- << "msgs (" << sbytes
- << "bytes) in: " << double(sendingDuration)/TIME_SEC
- << "s: " << double(smsgs)*TIME_SEC/sendingDuration
- << "msgs/s(" << double(sbytes)*TIME_SEC/sendingDuration
- << "bytes/s)\n";
- cout
- << "Recd: " << rmsgs
- << "msgs (" << rbytes
- << "bytes) in: " << double(fullTestDuration)/TIME_SEC
- << "s: " << double(rmsgs)*TIME_SEC/fullTestDuration
- << "msgs/s(" << double(rbytes)*TIME_SEC/fullTestDuration
- << "bytes/s)\n";
-
-}
diff --git a/cpp/src/qpid/sys/rdma/RdmaIO.cpp b/cpp/src/qpid/sys/rdma/RdmaIO.cpp
deleted file mode 100644
index 78bcdec68e..0000000000
--- a/cpp/src/qpid/sys/rdma/RdmaIO.cpp
+++ /dev/null
@@ -1,720 +0,0 @@
-/*
- *
- * 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/sys/rdma/RdmaIO.h"
-
-#include "qpid/log/Statement.h"
-
-#include <string>
-#include <boost/bind.hpp>
-
-using qpid::sys::SocketAddress;
-using qpid::sys::DispatchHandle;
-using qpid::sys::Poller;
-using qpid::sys::ScopedLock;
-using qpid::sys::Mutex;
-
-namespace Rdma {
- // Set packing as these are 'on the wire' structures
-# pragma pack(push, 1)
-
- // Header structure for each transmitted frame
- struct FrameHeader {
- const static uint32_t FlagsMask = 0xf0000000;
- uint32_t data; // written in network order
-
- FrameHeader() {}
- FrameHeader(uint32_t credit, uint32_t flags = 0) {
- data = htonl((credit & ~FlagsMask) | (flags & FlagsMask));
- }
-
- uint32_t credit() const {
- return ntohl(data) & ~FlagsMask;
- }
-
- uint32_t flags() const {
- return ntohl(data) & FlagsMask;
- }
- };
-
- const size_t FrameHeaderSize = sizeof(FrameHeader);
-
- // Structure for Connection Parameters on the network
- //
- // The original version (now called 0) of these parameters had a couple of mistakes:
- // * No way to version the protocol (need to introduce a new protocol for iWarp)
- // * Used host order int32 (but only deployed on LE archs as far as we know)
- // so effectively was LE on the wire which is the opposite of network order.
- //
- // Fortunately the values sent were sufficiently restricted that a 16 bit short could
- // be carved out to indicate the protocol version as these bits were always sent as 0.
- //
- // So the current version of parameters uses the last 2 bytes to indicate the protocol
- // version, if this is 0 then we interpret the rest of the struct without byte swapping
- // to remain compatible with the previous protocol.
- struct NConnectionParams {
- uint32_t maxRecvBufferSize;
- uint16_t initialXmitCredit;
- uint16_t rdmaProtocolVersion;
-
- NConnectionParams(const ConnectionParams& c) :
- maxRecvBufferSize(c.rdmaProtocolVersion ? htonl(c.maxRecvBufferSize) : c.maxRecvBufferSize),
- initialXmitCredit(c.rdmaProtocolVersion ? htons(c.initialXmitCredit) : c.initialXmitCredit),
- // 0 is the same with/without byteswapping!
- rdmaProtocolVersion(htons(c.rdmaProtocolVersion))
- {}
-
- operator ConnectionParams() const {
- return
- ConnectionParams(
- rdmaProtocolVersion ? ntohl(maxRecvBufferSize) : maxRecvBufferSize,
- rdmaProtocolVersion ? ntohs(initialXmitCredit) : initialXmitCredit,
- ntohs(rdmaProtocolVersion));
- }
- };
-# pragma pack(pop)
-
- class IOException : public std::exception {
- std::string s;
-
- public:
- IOException(std::string s0): s(s0) {}
- ~IOException() throw() {}
-
- const char* what() const throw() {
- return s.c_str();
- }
- };
-
- AsynchIO::AsynchIO(
- QueuePair::intrusive_ptr q,
- int version,
- int size,
- int xCredit,
- int rCount,
- ReadCallback rc,
- IdleCallback ic,
- FullCallback fc,
- ErrorCallback ec
- ) :
- protocolVersion(version),
- bufferSize(size),
- recvCredit(0),
- xmitCredit(xCredit),
- recvBufferCount(rCount),
- xmitBufferCount(xCredit),
- outstandingWrites(0),
- draining(false),
- state(IDLE),
- qp(q),
- dataHandle(*qp, boost::bind(&AsynchIO::dataEvent, this), 0, 0),
- readCallback(rc),
- idleCallback(ic),
- fullCallback(fc),
- errorCallback(ec),
- pendingWriteAction(boost::bind(&AsynchIO::writeEvent, this))
- {
- if (protocolVersion > maxSupportedProtocolVersion)
- throw IOException("Unsupported Rdma Protocol");
- qp->nonblocking();
- qp->notifyRecv();
- qp->notifySend();
-
- // Prepost recv buffers before we go any further
- qp->allocateRecvBuffers(recvBufferCount, bufferSize+FrameHeaderSize);
-
- // Create xmit buffers, reserve space for frame header.
- qp->createSendBuffers(xmitBufferCount, bufferSize, FrameHeaderSize);
- }
-
- AsynchIO::~AsynchIO() {
- // Warn if we are deleting whilst there are still unreclaimed write buffers
- if ( outstandingWrites>0 )
- QPID_LOG(error, "RDMA: qp=" << qp << ": Deleting queue before all write buffers finished");
-
- // Turn off callbacks if necessary (before doing the deletes)
- if (state != STOPPED) {
- QPID_LOG(error, "RDMA: qp=" << qp << ": Deleting queue whilst not shutdown");
- dataHandle.stopWatch();
- }
- // TODO: It might turn out to be more efficient in high connection loads to reuse the
- // buffers rather than having to reregister them all the time (this would be straightforward if all
- // connections haver the same buffer size and harder otherwise)
- }
-
- void AsynchIO::start(Poller::shared_ptr poller) {
- dataHandle.startWatch(poller);
- }
-
- // State constraints
- // On entry: None
- // On exit: STOPPED
- // Mark for deletion/Delete this object when we have no outstanding writes
- void AsynchIO::stop(NotifyCallback nc) {
- ScopedLock<Mutex> l(stateLock);
- state = STOPPED;
- notifyCallback = nc;
- dataHandle.call(boost::bind(&AsynchIO::doStoppedCallback, this));
- }
-
- namespace {
- void requestedCall(AsynchIO* aio, AsynchIO::RequestCallback callback) {
- assert(callback);
- callback(*aio);
- }
- }
-
- void AsynchIO::requestCallback(RequestCallback callback) {
- // TODO creating a function object every time isn't all that
- // efficient - if this becomes heavily used do something better (what?)
- assert(callback);
- dataHandle.call(boost::bind(&requestedCall, this, callback));
- }
-
- // Mark writing closed (so we don't accept any more writes or make any idle callbacks)
- void AsynchIO::drainWriteQueue(NotifyCallback nc) {
- draining = true;
- notifyCallback = nc;
- }
-
- void AsynchIO::queueBuffer(Buffer* buff, int credit) {
- switch (protocolVersion) {
- case 0:
- if (!buff) {
- Buffer* ob = getSendBuffer();
- // Have to send something as adapters hate it when you try to transfer 0 bytes
- *reinterpret_cast< uint32_t* >(ob->bytes()) = htonl(credit);
- ob->dataCount(sizeof(uint32_t));
- qp->postSend(credit | IgnoreData, ob);
- } else if (credit > 0) {
- qp->postSend(credit, buff);
- } else {
- qp->postSend(buff);
- }
- break;
- case 1:
- if (!buff)
- buff = getSendBuffer();
- // Add FrameHeader after frame data
- FrameHeader header(credit);
- assert(buff->dataCount() <= buff->byteCount()); // ensure app data doesn't impinge on reserved space.
- ::memcpy(buff->bytes()+buff->dataCount(), &header, FrameHeaderSize);
- buff->dataCount(buff->dataCount()+FrameHeaderSize);
- qp->postSend(buff);
- break;
- }
- }
-
- Buffer* AsynchIO::extractBuffer(const QueuePairEvent& e) {
- Buffer* b = e.getBuffer();
- switch (protocolVersion) {
- case 0: {
- bool dataPresent = true;
- // Get our xmitCredit if it was sent
- if (e.immPresent() ) {
- assert(xmitCredit>=0);
- xmitCredit += (e.getImm() & ~FlagsMask);
- dataPresent = ((e.getImm() & IgnoreData) == 0);
- assert(xmitCredit>0);
- }
- if (!dataPresent) {
- b->dataCount(0);
- }
- break;
- }
- case 1:
- b->dataCount(b->dataCount()-FrameHeaderSize);
- FrameHeader header;
- ::memcpy(&header, b->bytes()+b->dataCount(), FrameHeaderSize);
- assert(xmitCredit>=0);
- xmitCredit += header.credit();
- assert(xmitCredit>=0);
- break;
- }
-
- return b;
- }
-
- void AsynchIO::queueWrite(Buffer* buff) {
- // Make sure we don't overrun our available buffers
- // either at our end or the known available at the peers end
- if (writable()) {
- // TODO: We might want to batch up sending credit
- int creditSent = recvCredit & ~FlagsMask;
- queueBuffer(buff, creditSent);
- recvCredit -= creditSent;
- ++outstandingWrites;
- --xmitCredit;
- assert(xmitCredit>=0);
- } else {
- if (fullCallback) {
- fullCallback(*this, buff);
- } else {
- QPID_LOG(error, "RDMA: qp=" << qp << ": Write queue full, but no callback, throwing buffer away");
- returnSendBuffer(buff);
- }
- }
- }
-
- // State constraints
- // On entry: None
- // On exit: NOTIFY_PENDING || STOPPED
- void AsynchIO::notifyPendingWrite() {
- ScopedLock<Mutex> l(stateLock);
- switch (state) {
- case IDLE:
- dataHandle.call(pendingWriteAction);
- // Fall Thru
- case NOTIFY:
- state = NOTIFY_PENDING;
- break;
- case NOTIFY_PENDING:
- case STOPPED:
- break;
- }
- }
-
- // State constraints
- // On entry: IDLE || STOPPED
- // On exit: IDLE || STOPPED
- void AsynchIO::dataEvent() {
- {
- ScopedLock<Mutex> l(stateLock);
-
- if (state == STOPPED) return;
-
- state = NOTIFY_PENDING;
- }
- processCompletions();
-
- writeEvent();
- }
-
- // State constraints
- // On entry: NOTIFY_PENDING || STOPPED
- // On exit: IDLE || STOPPED
- void AsynchIO::writeEvent() {
- State newState;
- do {
- {
- ScopedLock<Mutex> l(stateLock);
-
- switch (state) {
- case STOPPED:
- return;
- default:
- state = NOTIFY;
- }
- }
-
- doWriteCallback();
-
- {
- ScopedLock<Mutex> l(stateLock);
-
- newState = state;
- switch (newState) {
- case NOTIFY_PENDING:
- case STOPPED:
- break;
- default:
- state = IDLE;
- }
- }
- } while (newState == NOTIFY_PENDING);
- }
-
- void AsynchIO::processCompletions() {
- QueuePair::intrusive_ptr q = qp->getNextChannelEvent();
-
- // Re-enable notification for queue:
- // This needs to happen before we could do anything that could generate more work completion
- // events (ie the callbacks etc. in the following).
- // This can't make us reenter this code as the handle attached to the completion queue will still be
- // disabled by the poller until we leave this code
- qp->notifyRecv();
- qp->notifySend();
-
- int recvEvents = 0;
- int sendEvents = 0;
-
- // If no event do nothing
- if (!q)
- return;
-
- assert(q == qp);
-
- // Repeat until no more events
- do {
- QueuePairEvent e(qp->getNextEvent());
- if (!e)
- break;
-
- ::ibv_wc_status status = e.getEventStatus();
- if (status != IBV_WC_SUCCESS) {
- // Need special check for IBV_WC_WR_FLUSH_ERR here
- // we will get this for every send/recv queue entry that was pending
- // when disconnected, these aren't real errors and mostly need to be ignored
- if (status == IBV_WC_WR_FLUSH_ERR) {
- QueueDirection dir = e.getDirection();
- if (dir == SEND) {
- Buffer* b = e.getBuffer();
- ++sendEvents;
- returnSendBuffer(b);
- --outstandingWrites;
- } else {
- ++recvEvents;
- }
- continue;
- }
- errorCallback(*this);
- // TODO: Probably need to flush queues at this point
- return;
- }
-
- // Test if recv (or recv with imm)
- //::ibv_wc_opcode eventType = e.getEventType();
- QueueDirection dir = e.getDirection();
- if (dir == RECV) {
- ++recvEvents;
-
- Buffer* b = extractBuffer(e);
-
- // if there was no data sent then the message was only to update our credit
- if ( b->dataCount() > 0 ) {
- readCallback(*this, b);
- }
-
- // At this point the buffer has been consumed so put it back on the recv queue
- // TODO: Is this safe to do if the connection is disconnected already?
- qp->postRecv(b);
-
- // Received another message
- ++recvCredit;
-
- // Send recvCredit if it is large enough (it will have got this large because we've not sent anything recently)
- if (recvCredit > recvBufferCount/2) {
- // TODO: This should use RDMA write with imm as there might not ever be a buffer to receive this message
- // but this is a little unlikely, as to get in this state we have to have received messages without sending any
- // for a while so its likely we've received an credit update from the far side.
- if (writable()) {
- int creditSent = recvCredit & ~FlagsMask;
- queueBuffer(0, creditSent);
- recvCredit -= creditSent;
- ++outstandingWrites;
- --xmitCredit;
- assert(xmitCredit>=0);
- } else {
- QPID_LOG(warning, "RDMA: qp=" << qp << ": Unable to send unsolicited credit");
- }
- }
- } else {
- Buffer* b = e.getBuffer();
- ++sendEvents;
- returnSendBuffer(b);
- --outstandingWrites;
- }
- } while (true);
-
- // Not sure if this is expected or not
- if (recvEvents == 0 && sendEvents == 0) {
- QPID_LOG(debug, "RDMA: qp=" << qp << ": Got channel event with no recv/send completions");
- }
- }
-
- void AsynchIO::doWriteCallback() {
- // TODO: maybe don't call idle unless we're low on write buffers
- // Keep on calling the idle routine as long as we are writable and we got something to write last call
-
- // Do callback even if there are no available free buffers as the application itself might be
- // holding onto buffers
- while (writable()) {
- int xc = xmitCredit;
- idleCallback(*this);
- // Check whether we actually wrote anything
- if (xmitCredit == xc) {
- QPID_LOG(debug, "RDMA: qp=" << qp << ": Called for data, but got none: xmitCredit=" << xmitCredit);
- return;
- }
- }
-
- checkDrained();
- }
-
- void AsynchIO::checkDrained() {
- // If we've got all the write confirmations and we're draining
- // We might get deleted in the drained callback so return immediately
- if (draining) {
- if (outstandingWrites == 0) {
- draining = false;
- NotifyCallback nc;
- nc.swap(notifyCallback);
- nc(*this);
- }
- return;
- }
- }
-
- void AsynchIO::doStoppedCallback() {
- // Ensure we can't get any more callbacks (except for the stopped callback)
- dataHandle.stopWatch();
-
- NotifyCallback nc;
- nc.swap(notifyCallback);
- nc(*this);
- }
-
- ConnectionManager::ConnectionManager(
- ErrorCallback errc,
- DisconnectedCallback dc
- ) :
- state(IDLE),
- ci(Connection::make()),
- handle(*ci, boost::bind(&ConnectionManager::event, this, _1), 0, 0),
- errorCallback(errc),
- disconnectedCallback(dc)
- {
- QPID_LOG(debug, "RDMA: ci=" << ci << ": Creating ConnectionManager");
- ci->nonblocking();
- }
-
- ConnectionManager::~ConnectionManager()
- {
- QPID_LOG(debug, "RDMA: ci=" << ci << ": Deleting ConnectionManager");
- }
-
- void ConnectionManager::start(Poller::shared_ptr poller, const qpid::sys::SocketAddress& addr) {
- startConnection(ci, addr);
- handle.startWatch(poller);
- }
-
- void ConnectionManager::doStoppedCallback() {
- // Ensure we can't get any more callbacks (except for the stopped callback)
- handle.stopWatch();
-
- NotifyCallback nc;
- nc.swap(notifyCallback);
- nc(*this);
- }
-
- void ConnectionManager::stop(NotifyCallback nc) {
- state = STOPPED;
- notifyCallback = nc;
- handle.call(boost::bind(&ConnectionManager::doStoppedCallback, this));
- }
-
- void ConnectionManager::event(DispatchHandle&) {
- if (state.get() == STOPPED) return;
- connectionEvent(ci);
- }
-
- Listener::Listener(
- const ConnectionParams& cp,
- EstablishedCallback ec,
- ErrorCallback errc,
- DisconnectedCallback dc,
- ConnectionRequestCallback crc
- ) :
- ConnectionManager(errc, dc),
- checkConnectionParams(cp),
- connectionRequestCallback(crc),
- establishedCallback(ec)
- {
- }
-
- void Listener::startConnection(Connection::intrusive_ptr ci, const qpid::sys::SocketAddress& addr) {
- ci->bind(addr);
- ci->listen();
- }
-
- namespace {
- const int64_t PoisonContext = -1;
- }
-
- void Listener::connectionEvent(Connection::intrusive_ptr ci) {
- ConnectionEvent e(ci->getNextEvent());
-
- // If (for whatever reason) there was no event do nothing
- if (!e)
- return;
-
- // Important documentation ommision the new rdma_cm_id
- // you get from CONNECT_REQUEST has the same context info
- // as its parent listening rdma_cm_id
- ::rdma_cm_event_type eventType = e.getEventType();
- ::rdma_conn_param conn_param = e.getConnectionParam();
- Rdma::Connection::intrusive_ptr id = e.getConnection();
-
- // Check for previous disconnection (it appears that you actually can get connection
- // request events after a disconnect event in rare circumstances)
- if (reinterpret_cast<int64_t>(id->getContext<void*>())==PoisonContext)
- return;
-
- switch (eventType) {
- case RDMA_CM_EVENT_CONNECT_REQUEST: {
- // Make sure peer has sent params we can use
- if (!conn_param.private_data || conn_param.private_data_len < sizeof(NConnectionParams)) {
- QPID_LOG(warning, "Rdma: rejecting connection attempt: unusable connection parameters");
- id->reject();
- break;
- }
-
- const NConnectionParams* rcp = static_cast<const NConnectionParams*>(conn_param.private_data);
- ConnectionParams cp = *rcp;
-
- // Reject if requested msg size is bigger than we allow
- if (
- cp.maxRecvBufferSize > checkConnectionParams.maxRecvBufferSize ||
- cp.initialXmitCredit > checkConnectionParams.initialXmitCredit
- ) {
- QPID_LOG(warning, "Rdma: rejecting connection attempt: connection parameters out of range: ("
- << cp.maxRecvBufferSize << ">" << checkConnectionParams.maxRecvBufferSize << " || "
- << cp.initialXmitCredit << ">" << checkConnectionParams.initialXmitCredit
- << ")");
- id->reject(&checkConnectionParams);
- break;
- }
-
- bool accept = true;
- if (connectionRequestCallback)
- accept = connectionRequestCallback(id, cp);
-
- if (accept) {
- // Accept connection
- cp.initialXmitCredit = checkConnectionParams.initialXmitCredit;
- id->accept(conn_param, rcp);
- } else {
- // Reject connection
- QPID_LOG(warning, "Rdma: rejecting connection attempt: application policy");
- id->reject();
- }
- break;
- }
- case RDMA_CM_EVENT_ESTABLISHED:
- establishedCallback(id);
- break;
- case RDMA_CM_EVENT_DISCONNECTED:
- disconnectedCallback(id);
- // Poison the id context so that we do no more callbacks on it
- id->removeContext();
- id->addContext(reinterpret_cast<void*>(PoisonContext));
- break;
- case RDMA_CM_EVENT_CONNECT_ERROR:
- errorCallback(id, CONNECT_ERROR);
- break;
- default:
- // Unexpected response
- errorCallback(id, UNKNOWN);
- //std::cerr << "Warning: unexpected response to listen - " << eventType << "\n";
- }
- }
-
- Connector::Connector(
- const ConnectionParams& cp,
- ConnectedCallback cc,
- ErrorCallback errc,
- DisconnectedCallback dc,
- RejectedCallback rc
- ) :
- ConnectionManager(errc, dc),
- connectionParams(cp),
- rejectedCallback(rc),
- connectedCallback(cc)
- {
- }
-
- void Connector::startConnection(Connection::intrusive_ptr ci, const qpid::sys::SocketAddress& addr) {
- ci->resolve_addr(addr);
- }
-
- void Connector::connectionEvent(Connection::intrusive_ptr ci) {
- ConnectionEvent e(ci->getNextEvent());
-
- // If (for whatever reason) there was no event do nothing
- if (!e)
- return;
-
- ::rdma_cm_event_type eventType = e.getEventType();
- ::rdma_conn_param conn_param = e.getConnectionParam();
- Rdma::Connection::intrusive_ptr id = e.getConnection();
- switch (eventType) {
- case RDMA_CM_EVENT_ADDR_RESOLVED:
- // RESOLVE_ADDR
- ci->resolve_route();
- break;
- case RDMA_CM_EVENT_ADDR_ERROR:
- // RESOLVE_ADDR
- errorCallback(ci, ADDR_ERROR);
- break;
- case RDMA_CM_EVENT_ROUTE_RESOLVED: {
- // RESOLVE_ROUTE:
- NConnectionParams rcp(connectionParams);
- ci->connect(&rcp);
- break;
- }
- case RDMA_CM_EVENT_ROUTE_ERROR:
- // RESOLVE_ROUTE:
- errorCallback(ci, ROUTE_ERROR);
- break;
- case RDMA_CM_EVENT_CONNECT_ERROR:
- // CONNECTING
- errorCallback(ci, CONNECT_ERROR);
- break;
- case RDMA_CM_EVENT_UNREACHABLE:
- // CONNECTING
- errorCallback(ci, UNREACHABLE);
- break;
- case RDMA_CM_EVENT_REJECTED: {
- // CONNECTING
-
- // We can get this event if our peer is not running on the other side
- // in this case we could get nearly anything in the private data:
- // From private_data == 0 && private_data_len == 0 (Chelsio iWarp)
- // to 148 bytes of zeros (Mellanox IB)
- //
- // So assume that if the the private data is absent or not the size of
- // the connection parameters it isn't valid
- ConnectionParams cp(0, 0, 0);
- if (conn_param.private_data && conn_param.private_data_len == sizeof(NConnectionParams)) {
- // Extract private data from event
- const NConnectionParams* rcp = static_cast<const NConnectionParams*>(conn_param.private_data);
- cp = *rcp;
- }
- rejectedCallback(ci, cp);
- break;
- }
- case RDMA_CM_EVENT_ESTABLISHED: {
- // CONNECTING
- // Extract private data from event
- assert(conn_param.private_data && conn_param.private_data_len >= sizeof(NConnectionParams));
- const NConnectionParams* rcp = static_cast<const NConnectionParams*>(conn_param.private_data);
- ConnectionParams cp = *rcp;
- connectedCallback(ci, cp);
- break;
- }
- case RDMA_CM_EVENT_DISCONNECTED:
- // ESTABLISHED
- disconnectedCallback(ci);
- break;
- default:
- QPID_LOG(warning, "RDMA: Unexpected event in connect: " << eventType);
- }
- }
-}
diff --git a/cpp/src/qpid/sys/rdma/RdmaIO.h b/cpp/src/qpid/sys/rdma/RdmaIO.h
deleted file mode 100644
index ec9caaf08d..0000000000
--- a/cpp/src/qpid/sys/rdma/RdmaIO.h
+++ /dev/null
@@ -1,250 +0,0 @@
-/*
- *
- * 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.
- *
- */
-#ifndef Rdma_Acceptor_h
-#define Rdma_Acceptor_h
-
-#include "qpid/sys/rdma/rdma_wrap.h"
-
-#include "qpid/sys/AtomicValue.h"
-#include "qpid/sys/Dispatcher.h"
-#include "qpid/sys/DispatchHandle.h"
-#include "qpid/sys/Mutex.h"
-#include "qpid/sys/SocketAddress.h"
-
-#include <netinet/in.h>
-
-#include <boost/function.hpp>
-
-namespace Rdma {
-
- class Connection;
-
- class AsynchIO
- {
- typedef boost::function1<void, AsynchIO&> ErrorCallback;
- typedef boost::function2<void, AsynchIO&, Buffer*> ReadCallback;
- typedef boost::function1<void, AsynchIO&> IdleCallback;
- typedef boost::function2<void, AsynchIO&, Buffer*> FullCallback;
- typedef boost::function1<void, AsynchIO&> NotifyCallback;
-
- int protocolVersion;
- int bufferSize;
- int recvCredit;
- int xmitCredit;
- int recvBufferCount;
- int xmitBufferCount;
- int outstandingWrites;
- bool draining;
- enum State {IDLE, NOTIFY, NOTIFY_PENDING, STOPPED};
- State state;
- qpid::sys::Mutex stateLock;
- QueuePair::intrusive_ptr qp;
- qpid::sys::DispatchHandleRef dataHandle;
-
- ReadCallback readCallback;
- IdleCallback idleCallback;
- FullCallback fullCallback;
- ErrorCallback errorCallback;
- NotifyCallback notifyCallback;
- qpid::sys::DispatchHandle::Callback pendingWriteAction;
-
- public:
- typedef boost::function1<void, AsynchIO&> RequestCallback;
-
- // TODO: Instead of specifying a buffer size specify the amount of memory the AsynchIO class can use
- // for buffers both read and write (allocate half to each up front) and fail if we cannot allocate that much
- // locked memory
- AsynchIO(
- QueuePair::intrusive_ptr q,
- int version,
- int size,
- int xCredit,
- int rCount,
- ReadCallback rc,
- IdleCallback ic,
- FullCallback fc,
- ErrorCallback ec
- );
- ~AsynchIO();
-
- void start(qpid::sys::Poller::shared_ptr poller);
- bool writable() const;
- void queueWrite(Buffer* buff);
- void notifyPendingWrite();
- void drainWriteQueue(NotifyCallback);
- void stop(NotifyCallback);
- void requestCallback(RequestCallback);
- int incompletedWrites() const;
- Buffer* getSendBuffer();
- void returnSendBuffer(Buffer*);
-
- private:
- const static int maxSupportedProtocolVersion = 1;
-
- // Constants for the peer-peer command messages
- // These are sent in the high bits if the imm data of an rdma message
- // The low bits are used to send the credit
- const static int FlagsMask = 0xF0000000; // Mask for all flag bits - be sure to update this if you add more command bits
- const static int IgnoreData = 0x10000000; // Message contains no application data
-
- void dataEvent();
- void writeEvent();
- void processCompletions();
- void doWriteCallback();
- void checkDrained();
- void doStoppedCallback();
-
- void queueBuffer(Buffer* buff, int credit);
- Buffer* extractBuffer(const QueuePairEvent& e);
- };
-
- // We're only writable if:
- // * not draining write queue
- // * we've got space in the transmit queue
- // * we've got credit to transmit
- // * if there's only 1 transmit credit we must send some credit
- inline bool AsynchIO::writable() const {
- assert(xmitCredit>=0);
- return !draining &&
- outstandingWrites < xmitBufferCount &&
- xmitCredit > 0 &&
- ( xmitCredit > 1 || recvCredit > 0);
- }
-
- inline int AsynchIO::incompletedWrites() const {
- return outstandingWrites;
- }
-
- inline Buffer* AsynchIO::getSendBuffer() {
- return qp->getSendBuffer();
- }
-
- inline void AsynchIO::returnSendBuffer(Buffer* b) {
- qp->returnSendBuffer(b);
- }
-
- // These are the parameters necessary to start the conversation
- // * Each peer HAS to allocate buffers of the size of the maximum receive from its peer
- // * Each peer HAS to know the initial "credit" it has for transmitting to its peer
- struct ConnectionParams {
- uint32_t maxRecvBufferSize;
- uint16_t initialXmitCredit;
- uint16_t rdmaProtocolVersion;
-
- // Default to protocol version 1
- ConnectionParams(uint32_t s, uint16_t c, uint16_t v = 1) :
- maxRecvBufferSize(s),
- initialXmitCredit(c),
- rdmaProtocolVersion(v)
- {}
- };
-
- enum ErrorType {
- ADDR_ERROR,
- ROUTE_ERROR,
- CONNECT_ERROR,
- UNREACHABLE,
- UNKNOWN
- };
-
- typedef boost::function2<void, Rdma::Connection::intrusive_ptr, ErrorType> ErrorCallback;
- typedef boost::function1<void, Rdma::Connection::intrusive_ptr> DisconnectedCallback;
-
- class ConnectionManager {
- typedef boost::function1<void, ConnectionManager&> NotifyCallback;
-
- enum State {IDLE, STOPPED};
- qpid::sys::AtomicValue<State> state;
- Connection::intrusive_ptr ci;
- qpid::sys::DispatchHandleRef handle;
- NotifyCallback notifyCallback;
-
- protected:
- ErrorCallback errorCallback;
- DisconnectedCallback disconnectedCallback;
-
- public:
- ConnectionManager(
- ErrorCallback errc,
- DisconnectedCallback dc
- );
-
- virtual ~ConnectionManager();
-
- void start(qpid::sys::Poller::shared_ptr poller, const qpid::sys::SocketAddress& addr);
- void stop(NotifyCallback);
-
- private:
- void event(qpid::sys::DispatchHandle& handle);
- void doStoppedCallback();
-
- virtual void startConnection(Connection::intrusive_ptr ci, const qpid::sys::SocketAddress& addr) = 0;
- virtual void connectionEvent(Connection::intrusive_ptr ci) = 0;
- };
-
- typedef boost::function2<bool, Rdma::Connection::intrusive_ptr, const ConnectionParams&> ConnectionRequestCallback;
- typedef boost::function1<void, Rdma::Connection::intrusive_ptr> EstablishedCallback;
-
- class Listener : public ConnectionManager
- {
- ConnectionParams checkConnectionParams;
- ConnectionRequestCallback connectionRequestCallback;
- EstablishedCallback establishedCallback;
-
- public:
- Listener(
- const ConnectionParams& cp,
- EstablishedCallback ec,
- ErrorCallback errc,
- DisconnectedCallback dc,
- ConnectionRequestCallback crc = 0
- );
-
- private:
- void startConnection(Connection::intrusive_ptr ci, const qpid::sys::SocketAddress& addr);
- void connectionEvent(Connection::intrusive_ptr ci);
- };
-
- typedef boost::function2<void, Rdma::Connection::intrusive_ptr, const ConnectionParams&> RejectedCallback;
- typedef boost::function2<void, Rdma::Connection::intrusive_ptr, const ConnectionParams&> ConnectedCallback;
-
- class Connector : public ConnectionManager
- {
- ConnectionParams connectionParams;
- RejectedCallback rejectedCallback;
- ConnectedCallback connectedCallback;
-
- public:
- Connector(
- const ConnectionParams& cp,
- ConnectedCallback cc,
- ErrorCallback errc,
- DisconnectedCallback dc,
- RejectedCallback rc = 0
- );
-
- private:
- void startConnection(Connection::intrusive_ptr ci, const qpid::sys::SocketAddress& addr);
- void connectionEvent(Connection::intrusive_ptr ci);
- };
-}
-
-#endif // Rdma_Acceptor_h
diff --git a/cpp/src/qpid/sys/rdma/RdmaServer.cpp b/cpp/src/qpid/sys/rdma/RdmaServer.cpp
deleted file mode 100644
index 9b0710fd8f..0000000000
--- a/cpp/src/qpid/sys/rdma/RdmaServer.cpp
+++ /dev/null
@@ -1,210 +0,0 @@
-/*
- *
- * 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/sys/Thread.h"
-#include "qpid/sys/rdma/RdmaIO.h"
-#include "qpid/sys/rdma/rdma_exception.h"
-
-#include <arpa/inet.h>
-
-#include <vector>
-#include <queue>
-#include <string>
-#include <iostream>
-
-#include <boost/bind.hpp>
-
-using std::vector;
-using std::queue;
-using std::string;
-using std::cout;
-using std::cerr;
-
-using qpid::sys::Thread;
-using qpid::sys::SocketAddress;
-using qpid::sys::Poller;
-
-// All the accepted connections
-namespace qpid {
-namespace tests {
-
-struct Buffer {
- char* bytes() const {return bytes_;}
- int32_t byteCount() const {return size;}
-
- Buffer(const int32_t s):
- bytes_(new char[s]),
- size(s)
- {
- }
-
- ~Buffer() {
- delete [] bytes_;
- }
-private:
- char* bytes_;
- int32_t size;
-};
-
-struct ConRec {
- Rdma::Connection::intrusive_ptr connection;
- Rdma::AsynchIO* data;
- queue<Buffer*> queuedWrites;
-
- ConRec(Rdma::Connection::intrusive_ptr c) :
- connection(c)
- {}
-};
-
-void dataError(Rdma::AsynchIO&) {
- cout << "Data error:\n";
-}
-
-void idle(ConRec* cr, Rdma::AsynchIO& a) {
- // Need to make sure full is not called as it would reorder messages
- while (!cr->queuedWrites.empty() && a.writable()) {
- Rdma::Buffer* rbuf = a.getSendBuffer();
- if (!rbuf) break;
- Buffer* buf = cr->queuedWrites.front();
- cr->queuedWrites.pop();
- std::copy(buf->bytes(), buf->bytes()+buf->byteCount(), rbuf->bytes());
- rbuf->dataCount(buf->byteCount());
- delete buf;
- a.queueWrite(rbuf);
- }
-}
-
-void data(ConRec* cr, Rdma::AsynchIO& a, Rdma::Buffer* b) {
- // Echo data back
- Rdma::Buffer* buf = 0;
- if (cr->queuedWrites.empty() && a.writable()) {
- buf = a.getSendBuffer();
- }
- if (buf) {
- std::copy(b->bytes(), b->bytes()+b->dataCount(), buf->bytes());
- buf->dataCount(b->dataCount());
- a.queueWrite(buf);
- } else {
- Buffer* buf = new Buffer(b->dataCount());
- std::copy(b->bytes(), b->bytes()+b->dataCount(), buf->bytes());
- cr->queuedWrites.push(buf);
- // Try to empty queue
- idle(cr, a);
- }
-}
-
-void full(ConRec*, Rdma::AsynchIO&, Rdma::Buffer*) {
- // Shouldn't ever be called
- cout << "!";
-}
-
-void drained(Rdma::AsynchIO&) {
- cout << "Drained:\n";
-}
-
-void disconnected(Rdma::Connection::intrusive_ptr& ci) {
- ConRec* cr = ci->getContext<ConRec>();
- cr->connection->disconnect();
- cr->data->drainWriteQueue(drained);
- delete cr;
- cout << "Disconnected: " << cr << "\n";
-}
-
-void connectionError(Rdma::Connection::intrusive_ptr& ci, Rdma::ErrorType) {
- ConRec* cr = ci->getContext<ConRec>();
- cr->connection->disconnect();
- if (cr) {
- cr->data->drainWriteQueue(drained);
- delete cr;
- }
- cout << "Connection error: " << cr << "\n";
-}
-
-bool connectionRequest(Rdma::Connection::intrusive_ptr& ci, const Rdma::ConnectionParams& cp) {
- cout << "Incoming connection: ";
-
- // For fun reject alternate connection attempts
- static bool x = false;
- x = true;
-
- // Must create aio here so as to prepost buffers *before* we accept connection
- if (x) {
- ConRec* cr = new ConRec(ci);
- Rdma::AsynchIO* aio =
- new Rdma::AsynchIO(ci->getQueuePair(),
- cp.rdmaProtocolVersion,
- cp.maxRecvBufferSize, cp.initialXmitCredit, Rdma::DEFAULT_WR_ENTRIES,
- boost::bind(data, cr, _1, _2),
- boost::bind(idle, cr, _1),
- boost::bind(full, cr, _1, _2),
- dataError);
- ci->addContext(cr);
- cr->data = aio;
- cout << "Accept=>" << cr << "\n";
- } else {
- cout << "Reject\n";
- }
-
- return x;
-}
-
-void connected(Poller::shared_ptr poller, Rdma::Connection::intrusive_ptr& ci) {
- static int cnt = 0;
- ConRec* cr = ci->getContext<ConRec>();
- cout << "Connected: " << cr << "(" << ++cnt << ")\n";
-
- cr->data->start(poller);
-}
-
-}} // namespace qpid::tests
-
-using namespace qpid::tests;
-
-int main(int argc, char* argv[]) {
- vector<string> args(&argv[0], &argv[argc]);
-
- std::string port = (args.size() < 2) ? "20079" : args[1];
- cout << "Listening on port: " << port << "\n";
-
- try {
- boost::shared_ptr<Poller> p(new Poller());
-
- Rdma::Listener a(
- Rdma::ConnectionParams(16384, Rdma::DEFAULT_WR_ENTRIES),
- boost::bind(connected, p, _1),
- connectionError,
- disconnected,
- connectionRequest);
-
-
- SocketAddress sa("", port);
- a.start(p, sa);
-
- // The poller loop blocks all signals so run in its own thread
- Thread t(*p);
-
- ::pause();
- p->shutdown();
- t.join();
- } catch (Rdma::Exception& e) {
- int err = e.getError();
- cerr << "Error: " << e.what() << "(" << err << ")\n";
- }
-}
diff --git a/cpp/src/qpid/sys/rdma/rdma_exception.h b/cpp/src/qpid/sys/rdma/rdma_exception.h
deleted file mode 100644
index a3a289e38a..0000000000
--- a/cpp/src/qpid/sys/rdma/rdma_exception.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- *
- * 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.
- *
- */
-#ifndef RDMA_EXCEPTION_H
-#define RDMA_EXCEPTION_H
-
-#include <exception>
-
-#include <errno.h>
-#include <string.h>
-
-namespace Rdma {
- static __thread char s[50];
- class Exception : public std::exception {
- int err;
-
- public:
- Exception(int e) : err(e) {}
- int getError() { return err; }
- const char* what() const throw() {
- return ::strerror_r(err, s, 50);
- }
- };
-
- inline void THROW_ERRNO() {
- throw Rdma::Exception(errno);
- }
-
- inline void CHECK(int rc) {
- if (rc != 0)
- throw Rdma::Exception((rc == -1) ? errno : rc >0 ? rc : -rc);
- }
-
- inline int GETERR(int rc) {
- return (rc == -1) ? errno : rc > 0 ? rc : -rc;
- }
-
- inline void CHECK_IBV(int rc) {
- if (rc != 0)
- throw Rdma::Exception(rc);
- }
-
- template <typename T>
- inline
- T* CHECK_NULL(T* rc) {
- if (rc == 0)
- THROW_ERRNO();
- return rc;
- }
-}
-
-#endif // RDMA_EXCEPTION_H
diff --git a/cpp/src/qpid/sys/rdma/rdma_factories.cpp b/cpp/src/qpid/sys/rdma/rdma_factories.cpp
deleted file mode 100644
index a66f5b4035..0000000000
--- a/cpp/src/qpid/sys/rdma/rdma_factories.cpp
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- *
- * 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/sys/rdma/rdma_factories.h"
-
-#include "qpid/sys/rdma/rdma_exception.h"
-
-
-namespace Rdma {
- // Intentionally ignore return values for these functions
- // - we can't do anything about then anyway
- void acker(::rdma_cm_event* e) throw () {
- if (e) (void) ::rdma_ack_cm_event(e);
- }
-
- void destroyEChannel(::rdma_event_channel* c) throw () {
- if (c) (void) ::rdma_destroy_event_channel(c);
- }
-
- void destroyId(::rdma_cm_id* i) throw () {
- if (i) (void) ::rdma_destroy_id(i);
- }
-
- void deallocPd(::ibv_pd* p) throw () {
- if (p) (void) ::ibv_dealloc_pd(p);
- }
-
- void deregMr(::ibv_mr* mr) throw () {
- if (mr) (void) ::ibv_dereg_mr(mr);
- }
-
- void destroyCChannel(::ibv_comp_channel* c) throw () {
- if (c) (void) ::ibv_destroy_comp_channel(c);
- }
-
- void destroyCq(::ibv_cq* cq) throw () {
- if (cq) (void) ::ibv_destroy_cq(cq);
- }
-
- void destroyQp(::ibv_qp* qp) throw () {
- if (qp) (void) ::ibv_destroy_qp(qp);
- }
-
- boost::shared_ptr< ::rdma_cm_id > mkId(::rdma_cm_id* i) {
- return boost::shared_ptr< ::rdma_cm_id >(i, destroyId);
- }
-
- boost::shared_ptr< ::rdma_cm_event > mkEvent(::rdma_cm_event* e) {
- return boost::shared_ptr< ::rdma_cm_event >(e, acker);
- }
-
- boost::shared_ptr< ::ibv_qp > mkQp(::ibv_qp* qp) {
- return boost::shared_ptr< ::ibv_qp > (qp, destroyQp);
- }
-
- boost::shared_ptr< ::rdma_event_channel > mkEChannel() {
- ::rdma_event_channel* c = CHECK_NULL(::rdma_create_event_channel());
- return boost::shared_ptr< ::rdma_event_channel >(c, destroyEChannel);
- }
-
- boost::shared_ptr< ::rdma_cm_id >
- mkId(::rdma_event_channel* ec, void* context, ::rdma_port_space ps) {
- ::rdma_cm_id* i;
- CHECK(::rdma_create_id(ec, &i, context, ps));
- return mkId(i);
- }
-
- boost::shared_ptr< ::ibv_pd > allocPd(::ibv_context* c) {
- ::ibv_pd* pd = CHECK_NULL(::ibv_alloc_pd(c));
- return boost::shared_ptr< ::ibv_pd >(pd, deallocPd);
- }
-
- boost::shared_ptr< ::ibv_mr > regMr(::ibv_pd* pd, void* addr, size_t length, ::ibv_access_flags access) {
- ::ibv_mr* mr = CHECK_NULL(::ibv_reg_mr(pd, addr, length, access));
- return boost::shared_ptr< ::ibv_mr >(mr, deregMr);
- }
-
- boost::shared_ptr< ::ibv_comp_channel > mkCChannel(::ibv_context* c) {
- ::ibv_comp_channel* cc = CHECK_NULL(::ibv_create_comp_channel(c));
- return boost::shared_ptr< ::ibv_comp_channel >(cc, destroyCChannel);
- }
-
- boost::shared_ptr< ::ibv_cq >
- mkCq(::ibv_context* c, int cqe, void* context, ::ibv_comp_channel* cc) {
- ::ibv_cq* cq = CHECK_NULL(::ibv_create_cq(c, cqe, context, cc, 0));
- return boost::shared_ptr< ::ibv_cq >(cq, destroyCq);
- }
-}
diff --git a/cpp/src/qpid/sys/rdma/rdma_factories.h b/cpp/src/qpid/sys/rdma/rdma_factories.h
deleted file mode 100644
index bfca71fc7e..0000000000
--- a/cpp/src/qpid/sys/rdma/rdma_factories.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- *
- * 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.
- *
- */
-#ifndef RDMA_FACTORIES_H
-#define RDMA_FACTORIES_H
-
-#include <rdma/rdma_cma.h>
-
-#include <boost/shared_ptr.hpp>
-
-namespace Rdma {
- boost::shared_ptr< ::rdma_event_channel > mkEChannel();
- boost::shared_ptr< ::rdma_cm_id > mkId(::rdma_event_channel* ec, void* context, ::rdma_port_space ps);
- boost::shared_ptr< ::rdma_cm_id > mkId(::rdma_cm_id* i);
- boost::shared_ptr< ::rdma_cm_event > mkEvent(::rdma_cm_event* e);
- boost::shared_ptr< ::ibv_qp > mkQp(::ibv_qp* qp);
- boost::shared_ptr< ::ibv_pd > allocPd(::ibv_context* c);
- boost::shared_ptr< ::ibv_mr > regMr(::ibv_pd* pd, void* addr, size_t length, ::ibv_access_flags access);
- boost::shared_ptr< ::ibv_comp_channel > mkCChannel(::ibv_context* c);
- boost::shared_ptr< ::ibv_cq > mkCq(::ibv_context* c, int cqe, void* context, ::ibv_comp_channel* cc);
-}
-
-#endif // RDMA_FACTORIES_H
diff --git a/cpp/src/qpid/sys/rdma/rdma_wrap.cpp b/cpp/src/qpid/sys/rdma/rdma_wrap.cpp
deleted file mode 100644
index efe454c5be..0000000000
--- a/cpp/src/qpid/sys/rdma/rdma_wrap.cpp
+++ /dev/null
@@ -1,566 +0,0 @@
-/*
- *
- * 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/sys/rdma/rdma_wrap.h"
-
-#include "qpid/sys/rdma/rdma_factories.h"
-#include "qpid/sys/rdma/rdma_exception.h"
-
-#include "qpid/sys/posix/PrivatePosix.h"
-
-#include <fcntl.h>
-#include <netdb.h>
-
-#include <iostream>
-#include <stdexcept>
-
-namespace Rdma {
- const ::rdma_conn_param DEFAULT_CONNECT_PARAM = {
- 0, // .private_data
- 0, // .private_data_len
- 4, // .responder_resources
- 4, // .initiator_depth
- 0, // .flow_control
- 5, // .retry_count
- 7 // .rnr_retry_count
- };
-
- // This is moderately inefficient so don't use in a critical path
- int deviceCount() {
- int count;
- ::ibv_free_device_list(::ibv_get_device_list(&count));
- return count;
- }
-
- Buffer::Buffer(uint32_t lkey, char* bytes, const int32_t byteCount,
- const int32_t reserve) :
- bufferSize(byteCount + reserve), reserved(reserve)
- {
- sge.addr = (uintptr_t) bytes;
- sge.length = 0;
- sge.lkey = lkey;
- }
-
- QueuePairEvent::QueuePairEvent() :
- dir(NONE)
- {}
-
- QueuePairEvent::QueuePairEvent(
- const ::ibv_wc& w,
- boost::shared_ptr< ::ibv_cq > c,
- QueueDirection d) :
- cq(c),
- wc(w),
- dir(d)
- {
- assert(dir != NONE);
- }
-
- QueuePairEvent::operator bool() const {
- return dir != NONE;
- }
-
- bool QueuePairEvent::immPresent() const {
- return wc.wc_flags & IBV_WC_WITH_IMM;
- }
-
- uint32_t QueuePairEvent::getImm() const {
- return ntohl(wc.imm_data);
- }
-
- QueueDirection QueuePairEvent::getDirection() const {
- return dir;
- }
-
- ::ibv_wc_opcode QueuePairEvent::getEventType() const {
- return wc.opcode;
- }
-
- ::ibv_wc_status QueuePairEvent::getEventStatus() const {
- return wc.status;
- }
-
- Buffer* QueuePairEvent::getBuffer() const {
- Buffer* b = reinterpret_cast<Buffer*>(wc.wr_id);
- b->dataCount(wc.byte_len);
- return b;
- }
-
- QueuePair::QueuePair(boost::shared_ptr< ::rdma_cm_id > i) :
- qpid::sys::IOHandle(new qpid::sys::IOHandlePrivate),
- pd(allocPd(i->verbs)),
- cchannel(mkCChannel(i->verbs)),
- scq(mkCq(i->verbs, DEFAULT_CQ_ENTRIES, 0, cchannel.get())),
- rcq(mkCq(i->verbs, DEFAULT_CQ_ENTRIES, 0, cchannel.get())),
- outstandingSendEvents(0),
- outstandingRecvEvents(0)
- {
- impl->fd = cchannel->fd;
-
- // Set cq context to this QueuePair object so we can find
- // ourselves again
- scq->cq_context = this;
- rcq->cq_context = this;
-
- ::ibv_device_attr dev_attr;
- CHECK(::ibv_query_device(i->verbs, &dev_attr));
-
- ::ibv_qp_init_attr qp_attr = {};
-
- // TODO: make a default struct for this
- qp_attr.cap.max_send_wr = DEFAULT_WR_ENTRIES;
- qp_attr.cap.max_send_sge = 1;
- qp_attr.cap.max_recv_wr = DEFAULT_WR_ENTRIES;
- qp_attr.cap.max_recv_sge = 1;
-
- qp_attr.send_cq = scq.get();
- qp_attr.recv_cq = rcq.get();
- qp_attr.qp_type = IBV_QPT_RC;
-
- CHECK(::rdma_create_qp(i.get(), pd.get(), &qp_attr));
- qp = mkQp(i->qp);
-
- // Set the qp context to this so we can find ourselves again
- qp->qp_context = this;
- }
-
- QueuePair::~QueuePair() {
- // Reset back pointer in case someone else has the qp
- qp->qp_context = 0;
-
- // Dispose queue pair before we ack events
- qp.reset();
-
- if (outstandingSendEvents > 0)
- ::ibv_ack_cq_events(scq.get(), outstandingSendEvents);
- if (outstandingRecvEvents > 0)
- ::ibv_ack_cq_events(rcq.get(), outstandingRecvEvents);
-
- // Deallocate recv buffer memory
- if (rmr) delete [] static_cast<char*>(rmr->addr);
-
- // Deallocate recv buffer memory
- if (smr) delete [] static_cast<char*>(smr->addr);
-
- // The buffers vectors automatically deletes all the buffers we've allocated
- }
-
- // Create buffers to use for writing
- void QueuePair::createSendBuffers(int sendBufferCount, int bufferSize, int reserved)
- {
- assert(!smr);
-
- // Round up buffersize to cacheline (64 bytes)
- int dataLength = (bufferSize+reserved+63) & (~63);
-
- // Allocate memory block for all receive buffers
- char* mem = new char [sendBufferCount * dataLength];
- smr = regMr(pd.get(), mem, sendBufferCount * dataLength, ::IBV_ACCESS_LOCAL_WRITE);
- sendBuffers.reserve(sendBufferCount);
- freeBuffers.reserve(sendBufferCount);
- for (int i = 0; i<sendBufferCount; ++i) {
- // Allocate xmit buffer
- sendBuffers.push_back(Buffer(smr->lkey, &mem[i*dataLength], bufferSize, reserved));
- freeBuffers.push_back(i);
- }
- }
-
- Buffer* QueuePair::getSendBuffer() {
- qpid::sys::ScopedLock<qpid::sys::Mutex> l(bufferLock);
- if (freeBuffers.empty())
- return 0;
- int i = freeBuffers.back();
- freeBuffers.pop_back();
- assert(i >= 0 && i < int(sendBuffers.size()));
- Buffer* b = &sendBuffers[i];
- b->dataCount(0);
- return b;
- }
-
- void QueuePair::returnSendBuffer(Buffer* b) {
- qpid::sys::ScopedLock<qpid::sys::Mutex> l(bufferLock);
- int i = b - &sendBuffers[0];
- assert(i >= 0 && i < int(sendBuffers.size()));
- freeBuffers.push_back(i);
- }
-
- void QueuePair::allocateRecvBuffers(int recvBufferCount, int bufferSize)
- {
- assert(!rmr);
-
- // Round up buffersize to cacheline (64 bytes)
- bufferSize = (bufferSize+63) & (~63);
-
- // Allocate memory block for all receive buffers
- char* mem = new char [recvBufferCount * bufferSize];
- rmr = regMr(pd.get(), mem, recvBufferCount * bufferSize, ::IBV_ACCESS_LOCAL_WRITE);
- recvBuffers.reserve(recvBufferCount);
- for (int i = 0; i<recvBufferCount; ++i) {
- // Allocate recv buffer
- recvBuffers.push_back(Buffer(rmr->lkey, &mem[i*bufferSize], bufferSize));
- postRecv(&recvBuffers[i]);
- }
- }
-
- // Make channel non-blocking by making
- // associated fd nonblocking
- void QueuePair::nonblocking() {
- ::fcntl(cchannel->fd, F_SETFL, O_NONBLOCK);
- }
-
- // If we get EAGAIN because the channel has been set non blocking
- // and we'd have to wait then return an empty event
- QueuePair::intrusive_ptr QueuePair::getNextChannelEvent() {
- // First find out which cq has the event
- ::ibv_cq* cq;
- void* ctx;
- int rc = ::ibv_get_cq_event(cchannel.get(), &cq, &ctx);
- if (rc == -1 && errno == EAGAIN)
- return 0;
- CHECK(rc);
-
- // Batch acknowledge the event
- if (cq == scq.get()) {
- if (++outstandingSendEvents > DEFAULT_CQ_ENTRIES / 2) {
- ::ibv_ack_cq_events(cq, outstandingSendEvents);
- outstandingSendEvents = 0;
- }
- } else if (cq == rcq.get()) {
- if (++outstandingRecvEvents > DEFAULT_CQ_ENTRIES / 2) {
- ::ibv_ack_cq_events(cq, outstandingRecvEvents);
- outstandingRecvEvents = 0;
- }
- }
-
- return static_cast<QueuePair*>(ctx);
- }
-
- QueuePairEvent QueuePair::getNextEvent() {
- ::ibv_wc w;
- if (::ibv_poll_cq(scq.get(), 1, &w) == 1)
- return QueuePairEvent(w, scq, SEND);
- else if (::ibv_poll_cq(rcq.get(), 1, &w) == 1)
- return QueuePairEvent(w, rcq, RECV);
- else
- return QueuePairEvent();
- }
-
- void QueuePair::notifyRecv() {
- CHECK_IBV(ibv_req_notify_cq(rcq.get(), 0));
- }
-
- void QueuePair::notifySend() {
- CHECK_IBV(ibv_req_notify_cq(scq.get(), 0));
- }
-
- void QueuePair::postRecv(Buffer* buf) {
- ::ibv_recv_wr rwr = {};
-
- rwr.wr_id = reinterpret_cast<uint64_t>(buf);
- // We are given the whole buffer
- buf->dataCount(buf->byteCount());
- rwr.sg_list = &buf->sge;
- rwr.num_sge = 1;
-
- ::ibv_recv_wr* badrwr = 0;
- CHECK(::ibv_post_recv(qp.get(), &rwr, &badrwr));
- if (badrwr)
- throw std::logic_error("ibv_post_recv(): Bad rwr");
- }
-
- void QueuePair::postSend(Buffer* buf) {
- ::ibv_send_wr swr = {};
-
- swr.wr_id = reinterpret_cast<uint64_t>(buf);
- swr.opcode = IBV_WR_SEND;
- swr.send_flags = IBV_SEND_SIGNALED;
- swr.sg_list = &buf->sge;
- swr.num_sge = 1;
-
- ::ibv_send_wr* badswr = 0;
- CHECK(::ibv_post_send(qp.get(), &swr, &badswr));
- if (badswr)
- throw std::logic_error("ibv_post_send(): Bad swr");
- }
-
- void QueuePair::postSend(uint32_t imm, Buffer* buf) {
- ::ibv_send_wr swr = {};
-
- swr.wr_id = reinterpret_cast<uint64_t>(buf);
- swr.imm_data = htonl(imm);
- swr.opcode = IBV_WR_SEND_WITH_IMM;
- swr.send_flags = IBV_SEND_SIGNALED;
- swr.sg_list = &buf->sge;
- swr.num_sge = 1;
-
- ::ibv_send_wr* badswr = 0;
- CHECK(::ibv_post_send(qp.get(), &swr, &badswr));
- if (badswr)
- throw std::logic_error("ibv_post_send(): Bad swr");
- }
-
- ConnectionEvent::ConnectionEvent(::rdma_cm_event* e) :
- id((e->event != RDMA_CM_EVENT_CONNECT_REQUEST) ?
- Connection::find(e->id) : new Connection(e->id)),
- listen_id(Connection::find(e->listen_id)),
- event(mkEvent(e))
- {}
-
- ConnectionEvent::operator bool() const {
- return event;
- }
-
- ::rdma_cm_event_type ConnectionEvent::getEventType() const {
- return event->event;
- }
-
- ::rdma_conn_param ConnectionEvent::getConnectionParam() const {
- // It's badly documented, but it seems from the librdma source code that all the following
- // event types have a valid param.conn
- switch (event->event) {
- case RDMA_CM_EVENT_CONNECT_REQUEST:
- case RDMA_CM_EVENT_ESTABLISHED:
- case RDMA_CM_EVENT_REJECTED:
- case RDMA_CM_EVENT_DISCONNECTED:
- case RDMA_CM_EVENT_CONNECT_ERROR:
- return event->param.conn;
- default:
- ::rdma_conn_param p = {};
- return p;
- }
- }
-
- boost::intrusive_ptr<Connection> ConnectionEvent::getConnection () const {
- return id;
- }
-
- boost::intrusive_ptr<Connection> ConnectionEvent::getListenId() const {
- return listen_id;
- }
-
- // Wrap the passed in rdma_cm_id with a Connection
- // this basically happens only on connection request
- Connection::Connection(::rdma_cm_id* i) :
- qpid::sys::IOHandle(new qpid::sys::IOHandlePrivate),
- id(mkId(i)),
- context(0)
- {
- impl->fd = id->channel->fd;
-
- // Just overwrite the previous context as it will
- // have come from the listening connection
- if (i)
- i->context = this;
- }
-
- Connection::Connection() :
- qpid::sys::IOHandle(new qpid::sys::IOHandlePrivate),
- channel(mkEChannel()),
- id(mkId(channel.get(), this, RDMA_PS_TCP)),
- context(0)
- {
- impl->fd = channel->fd;
- }
-
- Connection::~Connection() {
- // Reset the id context in case someone else has it
- id->context = 0;
- }
-
- void Connection::ensureQueuePair() {
- assert(id.get());
-
- // Only allocate a queue pair if there isn't one already
- if (qp)
- return;
-
- qp = new QueuePair(id);
- }
-
- Connection::intrusive_ptr Connection::make() {
- return new Connection();
- }
-
- Connection::intrusive_ptr Connection::find(::rdma_cm_id* i) {
- if (!i)
- return 0;
- Connection* id = static_cast< Connection* >(i->context);
- if (!id)
- throw std::logic_error("Couldn't find existing Connection");
- return id;
- }
-
- // Make channel non-blocking by making
- // associated fd nonblocking
- void Connection::nonblocking() {
- assert(id.get());
- ::fcntl(id->channel->fd, F_SETFL, O_NONBLOCK);
- }
-
- // If we get EAGAIN because the channel has been set non blocking
- // and we'd have to wait then return an empty event
- ConnectionEvent Connection::getNextEvent() {
- assert(id.get());
- ::rdma_cm_event* e;
- int rc = ::rdma_get_cm_event(id->channel, &e);
- if (GETERR(rc) == EAGAIN)
- return ConnectionEvent();
- CHECK(rc);
- return ConnectionEvent(e);
- }
-
- void Connection::bind(const qpid::sys::SocketAddress& src_addr) const {
- assert(id.get());
- CHECK(::rdma_bind_addr(id.get(), getAddrInfo(src_addr).ai_addr));
- }
-
- void Connection::listen(int backlog) const {
- assert(id.get());
- CHECK(::rdma_listen(id.get(), backlog));
- }
-
- void Connection::resolve_addr(
- const qpid::sys::SocketAddress& dst_addr,
- int timeout_ms) const
- {
- assert(id.get());
- CHECK(::rdma_resolve_addr(id.get(), 0, getAddrInfo(dst_addr).ai_addr, timeout_ms));
- }
-
- void Connection::resolve_route(int timeout_ms) const {
- assert(id.get());
- CHECK(::rdma_resolve_route(id.get(), timeout_ms));
- }
-
- void Connection::disconnect() const {
- assert(id.get());
- int rc = ::rdma_disconnect(id.get());
- // iWarp doesn't let you disconnect a disconnected connection
- // but Infiniband can do so it's okay to call rdma_disconnect()
- // in response to a disconnect event, but we may get an error
- if (GETERR(rc) == EINVAL)
- return;
- CHECK(rc);
- }
-
- // TODO: Currently you can only connect with the default connection parameters
- void Connection::connect(const void* data, size_t len) {
- assert(id.get());
- // Need to have a queue pair before we can connect
- ensureQueuePair();
-
- ::rdma_conn_param p = DEFAULT_CONNECT_PARAM;
- p.private_data = data;
- p.private_data_len = len;
- CHECK(::rdma_connect(id.get(), &p));
- }
-
- void Connection::connect() {
- connect(0, 0);
- }
-
- void Connection::accept(const ::rdma_conn_param& param, const void* data, size_t len) {
- assert(id.get());
- // Need to have a queue pair before we can accept
- ensureQueuePair();
-
- ::rdma_conn_param p = param;
- p.private_data = data;
- p.private_data_len = len;
- CHECK(::rdma_accept(id.get(), &p));
- }
-
- void Connection::accept(const ::rdma_conn_param& param) {
- accept(param, 0, 0);
- }
-
- void Connection::reject(const void* data, size_t len) const {
- assert(id.get());
- CHECK(::rdma_reject(id.get(), data, len));
- }
-
- void Connection::reject() const {
- assert(id.get());
- CHECK(::rdma_reject(id.get(), 0, 0));
- }
-
- QueuePair::intrusive_ptr Connection::getQueuePair() {
- assert(id.get());
-
- ensureQueuePair();
-
- return qp;
- }
-
- std::string Connection::getLocalName() const {
- ::sockaddr* addr = ::rdma_get_local_addr(id.get());
- char hostName[NI_MAXHOST];
- char portName[NI_MAXSERV];
- CHECK_IBV(::getnameinfo(
- addr, sizeof(::sockaddr_storage),
- hostName, sizeof(hostName),
- portName, sizeof(portName),
- NI_NUMERICHOST | NI_NUMERICSERV));
- std::string r(hostName);
- r += ":";
- r += portName;
- return r;
- }
-
- std::string Connection::getPeerName() const {
- ::sockaddr* addr = ::rdma_get_peer_addr(id.get());
- char hostName[NI_MAXHOST];
- char portName[NI_MAXSERV];
- CHECK_IBV(::getnameinfo(
- addr, sizeof(::sockaddr_storage),
- hostName, sizeof(hostName),
- portName, sizeof(portName),
- NI_NUMERICHOST | NI_NUMERICSERV));
- std::string r(hostName);
- r += ":";
- r += portName;
- return r;
- }
-}
-
-std::ostream& operator<<(std::ostream& o, ::rdma_cm_event_type t) {
-# define CHECK_TYPE(t) case t: o << #t; break;
- switch(t) {
- CHECK_TYPE(RDMA_CM_EVENT_ADDR_RESOLVED)
- CHECK_TYPE(RDMA_CM_EVENT_ADDR_ERROR)
- CHECK_TYPE(RDMA_CM_EVENT_ROUTE_RESOLVED)
- CHECK_TYPE(RDMA_CM_EVENT_ROUTE_ERROR)
- CHECK_TYPE(RDMA_CM_EVENT_CONNECT_REQUEST)
- CHECK_TYPE(RDMA_CM_EVENT_CONNECT_RESPONSE)
- CHECK_TYPE(RDMA_CM_EVENT_CONNECT_ERROR)
- CHECK_TYPE(RDMA_CM_EVENT_UNREACHABLE)
- CHECK_TYPE(RDMA_CM_EVENT_REJECTED)
- CHECK_TYPE(RDMA_CM_EVENT_ESTABLISHED)
- CHECK_TYPE(RDMA_CM_EVENT_DISCONNECTED)
- CHECK_TYPE(RDMA_CM_EVENT_DEVICE_REMOVAL)
- CHECK_TYPE(RDMA_CM_EVENT_MULTICAST_JOIN)
- CHECK_TYPE(RDMA_CM_EVENT_MULTICAST_ERROR)
- default:
- o << "UNKNOWN_EVENT";
- }
-# undef CHECK_TYPE
- return o;
-}
diff --git a/cpp/src/qpid/sys/rdma/rdma_wrap.h b/cpp/src/qpid/sys/rdma/rdma_wrap.h
deleted file mode 100644
index 8e3429027b..0000000000
--- a/cpp/src/qpid/sys/rdma/rdma_wrap.h
+++ /dev/null
@@ -1,287 +0,0 @@
-/*
- *
- * 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.
- *
- */
-#ifndef RDMA_WRAP_H
-#define RDMA_WRAP_H
-
-#include <rdma/rdma_cma.h>
-
-#include "qpid/RefCounted.h"
-#include "qpid/sys/IOHandle.h"
-#include "qpid/sys/Mutex.h"
-
-#include <boost/shared_ptr.hpp>
-#include <boost/intrusive_ptr.hpp>
-#include <boost/ptr_container/ptr_deque.hpp>
-
-#include <vector>
-
-namespace qpid {
-namespace sys {
- class SocketAddress;
-}}
-
-namespace Rdma {
- const int DEFAULT_TIMEOUT = 2000; // 2 secs
- const int DEFAULT_BACKLOG = 100;
- const int DEFAULT_CQ_ENTRIES = 256;
- const int DEFAULT_WR_ENTRIES = 64;
- extern const ::rdma_conn_param DEFAULT_CONNECT_PARAM;
-
- int deviceCount();
-
- struct Buffer {
- friend class QueuePair;
- friend class QueuePairEvent;
-
- char* bytes() const;
- int32_t byteCount() const;
- int32_t dataCount() const;
- void dataCount(int32_t);
-
- private:
- Buffer(uint32_t lkey, char* bytes, const int32_t byteCount, const int32_t reserve=0);
- int32_t bufferSize;
- int32_t reserved; // for framing header
- ::ibv_sge sge;
- };
-
- inline char* Buffer::bytes() const {
- return (char*) sge.addr;
- }
-
- /** return the number of bytes available for application data */
- inline int32_t Buffer::byteCount() const {
- return bufferSize - reserved;
- }
-
- inline int32_t Buffer::dataCount() const {
- return sge.length;
- }
-
- inline void Buffer::dataCount(int32_t s) {
- // catch any attempt to overflow a buffer
- assert(s <= bufferSize + reserved);
- sge.length = s;
- }
-
- class Connection;
-
- enum QueueDirection {
- NONE,
- SEND,
- RECV
- };
-
- class QueuePairEvent {
- boost::shared_ptr< ::ibv_cq > cq;
- ::ibv_wc wc;
- QueueDirection dir;
-
- friend class QueuePair;
-
- QueuePairEvent();
- QueuePairEvent(
- const ::ibv_wc& w,
- boost::shared_ptr< ::ibv_cq > c,
- QueueDirection d);
-
- public:
- operator bool() const;
- bool immPresent() const;
- uint32_t getImm() const;
- QueueDirection getDirection() const;
- ::ibv_wc_opcode getEventType() const;
- ::ibv_wc_status getEventStatus() const;
- Buffer* getBuffer() const;
- };
-
- // Wrapper for a queue pair - this has the functionality for
- // putting buffers on the receive queue and for sending buffers
- // to the other end of the connection.
- class QueuePair : public qpid::sys::IOHandle, public qpid::RefCounted {
- friend class Connection;
-
- boost::shared_ptr< ::ibv_pd > pd;
- boost::shared_ptr< ::ibv_mr > smr;
- boost::shared_ptr< ::ibv_mr > rmr;
- boost::shared_ptr< ::ibv_comp_channel > cchannel;
- boost::shared_ptr< ::ibv_cq > scq;
- boost::shared_ptr< ::ibv_cq > rcq;
- boost::shared_ptr< ::ibv_qp > qp;
- int outstandingSendEvents;
- int outstandingRecvEvents;
- std::vector<Buffer> sendBuffers;
- std::vector<Buffer> recvBuffers;
- qpid::sys::Mutex bufferLock;
- std::vector<int> freeBuffers;
-
- QueuePair(boost::shared_ptr< ::rdma_cm_id > id);
- ~QueuePair();
-
- public:
- typedef boost::intrusive_ptr<QueuePair> intrusive_ptr;
-
- // Create a buffers to use for writing
- void createSendBuffers(int sendBufferCount, int dataSize, int headerSize);
-
- // Get a send buffer
- Buffer* getSendBuffer();
-
- // Return buffer to pool after use
- void returnSendBuffer(Buffer* b);
-
- // Create and post recv buffers
- void allocateRecvBuffers(int recvBufferCount, int bufferSize);
-
- // Make channel non-blocking by making
- // associated fd nonblocking
- void nonblocking();
-
- // If we get EAGAIN because the channel has been set non blocking
- // and we'd have to wait then return an empty event
- QueuePair::intrusive_ptr getNextChannelEvent();
-
- QueuePairEvent getNextEvent();
-
- void postRecv(Buffer* buf);
- void postSend(Buffer* buf);
- void postSend(uint32_t imm, Buffer* buf);
- void notifyRecv();
- void notifySend();
- };
-
- class ConnectionEvent {
- friend class Connection;
-
- // The order of the members is important as we have to acknowledge
- // the event before destroying the ids on destruction
- boost::intrusive_ptr<Connection> id;
- boost::intrusive_ptr<Connection> listen_id;
- boost::shared_ptr< ::rdma_cm_event > event;
-
- ConnectionEvent() {}
- ConnectionEvent(::rdma_cm_event* e);
-
- // Default copy, assignment and destructor ok
- public:
- operator bool() const;
- ::rdma_cm_event_type getEventType() const;
- ::rdma_conn_param getConnectionParam() const;
- boost::intrusive_ptr<Connection> getConnection () const;
- boost::intrusive_ptr<Connection> getListenId() const;
- };
-
- // For the moment this is a fairly simple wrapper for rdma_cm_id.
- //
- // NB: It allocates a protection domain (pd) per connection which means that
- // registered buffers can't be shared between different connections
- // (this can only happen between connections on the same controller in any case,
- // so needs careful management if used)
- class Connection : public qpid::sys::IOHandle, public qpid::RefCounted {
- boost::shared_ptr< ::rdma_event_channel > channel;
- boost::shared_ptr< ::rdma_cm_id > id;
- QueuePair::intrusive_ptr qp;
-
- void* context;
-
- friend class ConnectionEvent;
- friend class QueuePair;
-
- // Wrap the passed in rdma_cm_id with a Connection
- // this basically happens only on connection request
- Connection(::rdma_cm_id* i);
- Connection();
- ~Connection();
-
- void ensureQueuePair();
-
- public:
- typedef boost::intrusive_ptr<Connection> intrusive_ptr;
-
- static intrusive_ptr make();
- static intrusive_ptr find(::rdma_cm_id* i);
-
- template <typename T>
- void addContext(T* c) {
- // Don't allow replacing context
- if (!context)
- context = c;
- }
-
- void removeContext() {
- context = 0;
- }
-
- template <typename T>
- T* getContext() {
- return static_cast<T*>(context);
- }
-
- // Make channel non-blocking by making
- // associated fd nonblocking
- void nonblocking();
-
- // If we get EAGAIN because the channel has been set non blocking
- // and we'd have to wait then return an empty event
- ConnectionEvent getNextEvent();
-
- void bind(const qpid::sys::SocketAddress& src_addr) const;
- void listen(int backlog = DEFAULT_BACKLOG) const;
- void resolve_addr(
- const qpid::sys::SocketAddress& dst_addr,
- int timeout_ms = DEFAULT_TIMEOUT) const;
- void resolve_route(int timeout_ms = DEFAULT_TIMEOUT) const;
- void disconnect() const;
-
- // TODO: Currently you can only connect with the default connection parameters
- void connect(const void* data, size_t len);
- void connect();
- template <typename T>
- void connect(const T* data) {
- connect(data, sizeof(T));
- }
-
- // TODO: Not sure how to default accept params - they come from the connection request
- // event
- void accept(const ::rdma_conn_param& param, const void* data, size_t len);
- void accept(const ::rdma_conn_param& param);
- template <typename T>
- void accept(const ::rdma_conn_param& param, const T* data) {
- accept(param, data, sizeof(T));
- }
-
- void reject(const void* data, size_t len) const;
- void reject() const;
- template <typename T>
- void reject(const T* data) const {
- reject(data, sizeof(T));
- }
-
- QueuePair::intrusive_ptr getQueuePair();
- std::string getLocalName() const;
- std::string getPeerName() const;
- std::string getFullName() const { return getLocalName()+"-"+getPeerName(); }
- };
-}
-
-std::ostream& operator<<(std::ostream& o, ::rdma_cm_event_type t);
-
-#endif // RDMA_WRAP_H
diff --git a/cpp/src/qpid/sys/solaris/ECFPoller.cpp b/cpp/src/qpid/sys/solaris/ECFPoller.cpp
deleted file mode 100644
index 06d542c938..0000000000
--- a/cpp/src/qpid/sys/solaris/ECFPoller.cpp
+++ /dev/null
@@ -1,444 +0,0 @@
-/*
- *
- * 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/log/Logger.h"
-#include "qpid/sys/Poller.h"
-#include "qpid/sys/IOHandle.h"
-#include "qpid/sys/Mutex.h"
-#include "qpid/sys/DeletionManager.h"
-#include "qpid/sys/posix/check.h"
-#include "qpid/sys/posix/PrivatePosix.h"
-
-#include <port.h>
-#include <poll.h>
-#include <errno.h>
-#include <pthread.h>
-#include <signal.h>
-
-#include <assert.h>
-#include <queue>
-#include <exception>
-
-
-//TODO: Remove this
-#include "qpid/sys/Dispatcher.h"
-
-namespace qpid {
-namespace sys {
-
-// Deletion manager to handle deferring deletion of PollerHandles to when they definitely aren't being used
-DeletionManager<PollerHandlePrivate> PollerHandleDeletionManager;
-
-// Instantiate (and define) class static for DeletionManager
-template <>
-DeletionManager<PollerHandlePrivate>::AllThreadsStatuses DeletionManager<PollerHandlePrivate>::allThreadsStatuses(0);
-
-class PollerHandlePrivate {
- friend class Poller;
- friend class PollerHandle;
-
- enum FDStat {
- ABSENT,
- MONITORED,
- INACTIVE,
- HUNGUP,
- MONITORED_HUNGUP,
- DELETED
- };
-
- int fd;
- uint32_t events;
- FDStat stat;
- Mutex lock;
-
- PollerHandlePrivate(int f) :
- fd(f),
- events(0),
- stat(ABSENT) {
- }
-
- bool isActive() const {
- return stat == MONITORED || stat == MONITORED_HUNGUP;
- }
-
- void setActive() {
- stat = (stat == HUNGUP) ? MONITORED_HUNGUP : MONITORED;
- }
-
- bool isInactive() const {
- return stat == INACTIVE || stat == HUNGUP;
- }
-
- void setInactive() {
- stat = INACTIVE;
- }
-
- bool isIdle() const {
- return stat == ABSENT;
- }
-
- void setIdle() {
- stat = ABSENT;
- }
-
- bool isHungup() const {
- return stat == MONITORED_HUNGUP || stat == HUNGUP;
- }
-
- void setHungup() {
- assert(stat == MONITORED);
- stat = HUNGUP;
- }
-
- bool isDeleted() const {
- return stat == DELETED;
- }
-
- void setDeleted() {
- stat = DELETED;
- }
-};
-
-PollerHandle::PollerHandle(const IOHandle& h) :
- impl(new PollerHandlePrivate(toFd(h.impl)))
-{}
-
-PollerHandle::~PollerHandle() {
- {
- ScopedLock<Mutex> l(impl->lock);
- if (impl->isDeleted()) {
- return;
- }
- if (impl->isActive()) {
- impl->setDeleted();
- }
- }
- PollerHandleDeletionManager.markForDeletion(impl);
-}
-
-/**
- * Concrete implementation of Poller to use the Solaris Event Completion
- * Framework interface
- */
-class PollerPrivate {
- friend class Poller;
-
- class InterruptHandle: public PollerHandle {
- std::queue<PollerHandle*> handles;
-
- void processEvent(Poller::EventType) {
- PollerHandle* handle = handles.front();
- handles.pop();
- assert(handle);
-
- //Synthesise event
- Poller::Event event(handle, Poller::INTERRUPTED);
-
- //Process synthesised event
- event.process();
- }
-
- public:
- InterruptHandle() : PollerHandle(DummyIOHandle) {}
-
- void addHandle(PollerHandle& h) {
- handles.push(&h);
- }
-
- PollerHandle *getHandle() {
- PollerHandle* handle = handles.front();
- handles.pop();
- return handle;
- }
-
- bool queuedHandles() {
- return handles.size() > 0;
- }
- };
-
- const int portId;
- bool isShutdown;
- InterruptHandle interruptHandle;
-
- static uint32_t directionToPollEvent(Poller::Direction dir) {
- switch (dir) {
- case Poller::INPUT: return POLLIN;
- case Poller::OUTPUT: return POLLOUT;
- case Poller::INOUT: return POLLIN | POLLOUT;
- default: return 0;
- }
- }
-
- static Poller::EventType pollToDirection(uint32_t events) {
- uint32_t e = events & (POLLIN | POLLOUT);
- switch (e) {
- case POLLIN: return Poller::READABLE;
- case POLLOUT: return Poller::WRITABLE;
- case POLLIN | POLLOUT: return Poller::READ_WRITABLE;
- default:
- return (events & (POLLHUP | POLLERR)) ?
- Poller::DISCONNECTED : Poller::INVALID;
- }
- }
-
- PollerPrivate() :
- portId(::port_create()),
- isShutdown(false) {
- QPID_POSIX_CHECK(portId);
- QPID_LOG(trace, "port_create returned port Id: " << portId);
- }
-
- ~PollerPrivate() {
- }
-
- void interrupt() {
- //Send an Alarm to the port
- //We need to send a nonzero event mask, using POLLHUP,
- //nevertheless the wait method will only look for a PORT_ALERT_SET
- QPID_LOG(trace, "Sending a port_alert to " << portId);
- QPID_POSIX_CHECK(::port_alert(portId, PORT_ALERT_SET, POLLHUP,
- &static_cast<PollerHandle&>(interruptHandle)));
- }
-};
-
-void Poller::addFd(PollerHandle& handle, Direction dir) {
- PollerHandlePrivate& eh = *handle.impl;
- ScopedLock<Mutex> l(eh.lock);
-
- uint32_t events = 0;
-
- if (eh.isIdle()) {
- events = PollerPrivate::directionToPollEvent(dir);
- } else {
- assert(eh.isActive());
- events = eh.events | PollerPrivate::directionToPollEvent(dir);
- }
-
- //port_associate can be used to add an association or modify an
- //existing one
- QPID_POSIX_CHECK(::port_associate(impl->portId, PORT_SOURCE_FD, (uintptr_t) eh.fd, events, &handle));
- eh.events = events;
- eh.setActive();
- QPID_LOG(trace, "Poller::addFd(handle=" << &handle
- << "[" << typeid(&handle).name()
- << "], fd=" << eh.fd << ")");
-}
-
-void Poller::delFd(PollerHandle& handle) {
- PollerHandlePrivate& eh = *handle.impl;
- ScopedLock<Mutex> l(eh.lock);
- assert(!eh.isIdle());
- int rc = ::port_dissociate(impl->portId, PORT_SOURCE_FD, (uintptr_t) eh.fd);
- //Allow closing an invalid fd, allowing users to close fd before
- //doing delFd()
- if (rc == -1 && errno != EBADFD) {
- QPID_POSIX_CHECK(rc);
- }
- eh.setIdle();
- QPID_LOG(trace, "Poller::delFd(handle=" << &handle
- << ", fd=" << eh.fd << ")");
-}
-
-// modFd is equivalent to delFd followed by addFd
-void Poller::modFd(PollerHandle& handle, Direction dir) {
- PollerHandlePrivate& eh = *handle.impl;
- ScopedLock<Mutex> l(eh.lock);
- assert(!eh.isIdle());
-
- eh.events = PollerPrivate::directionToPollEvent(dir);
-
- //If fd is already associated, events and user arguments are updated
- //So, no need to check if fd is already associated
- QPID_POSIX_CHECK(::port_associate(impl->portId, PORT_SOURCE_FD, (uintptr_t) eh.fd, eh.events, &handle));
- eh.setActive();
- QPID_LOG(trace, "Poller::modFd(handle=" << &handle
- << ", fd=" << eh.fd << ")");
-}
-
-void Poller::rearmFd(PollerHandle& handle) {
- PollerHandlePrivate& eh = *handle.impl;
- ScopedLock<Mutex> l(eh.lock);
- assert(eh.isInactive());
-
- QPID_POSIX_CHECK(::port_associate(impl->portId, PORT_SOURCE_FD, (uintptr_t) eh.fd, eh.events, &handle));
- eh.setActive();
- QPID_LOG(trace, "Poller::rearmdFd(handle=" << &handle
- << ", fd=" << eh.fd << ")");
-}
-
-void Poller::shutdown() {
- //Allow sloppy code to shut us down more than once
- if (impl->isShutdown)
- return;
-
- impl->isShutdown = true;
- impl->interrupt();
-}
-
-bool Poller::hasShutdown()
-{
- return impl->isShutdown;
-}
-
-bool Poller::interrupt(PollerHandle& handle) {
- PollerPrivate::InterruptHandle& ih = impl->interruptHandle;
- PollerHandlePrivate& eh = *static_cast<PollerHandle&>(ih).impl;
- ScopedLock<Mutex> l(eh.lock);
- ih.addHandle(handle);
- impl->interrupt();
- eh.setActive();
- return true;
-}
-
-void Poller::run() {
- // Make sure we can't be interrupted by signals at a bad time
- ::sigset_t ss;
- ::sigfillset(&ss);
- ::pthread_sigmask(SIG_SETMASK, &ss, 0);
-
- do {
- Event event = wait();
-
- // If can read/write then dispatch appropriate callbacks
- if (event.handle) {
- event.process();
- } else {
- // Handle shutdown
- switch (event.type) {
- case SHUTDOWN:
- return;
- default:
- // This should be impossible
- assert(false);
- }
- }
- } while (true);
-}
-
-Poller::Event Poller::wait(Duration timeout) {
- timespec_t tout;
- timespec_t* ptout = NULL;
- port_event_t pe;
-
- AbsTime targetTimeout = (timeout == TIME_INFINITE) ? FAR_FUTURE :
- AbsTime(now(), timeout);
-
- if (timeout != TIME_INFINITE) {
- tout.tv_sec = 0;
- tout.tv_nsec = timeout;
- ptout = &tout;
- }
-
- do {
- PollerHandleDeletionManager.markAllUnusedInThisThread();
- QPID_LOG(trace, "About to enter port_get on " << impl->portId
- << ". Thread " << pthread_self()
- << ", timeout=" << timeout);
-
-
- int rc = ::port_get(impl->portId, &pe, ptout);
-
- QPID_LOG(trace, "port_get on " << impl->portId
- << " returned " << rc);
-
- if (impl->isShutdown) {
- PollerHandleDeletionManager.markAllUnusedInThisThread();
- return Event(0, SHUTDOWN);
- }
-
- if (rc < 0) {
- switch (errno) {
- case EINTR:
- continue;
- case ETIME:
- return Event(0, TIMEOUT);
- default:
- QPID_POSIX_CHECK(rc);
- }
- } else {
- PollerHandle* handle = static_cast<PollerHandle*>(pe.portev_user);
- PollerHandlePrivate& eh = *handle->impl;
- ScopedLock<Mutex> l(eh.lock);
-
- if (eh.isActive()) {
- QPID_LOG(trace, "Handle is active");
- //We use alert mode to notify interrupts
- if (pe.portev_source == PORT_SOURCE_ALERT &&
- handle == &impl->interruptHandle) {
- QPID_LOG(trace, "Interrupt notified");
-
- PollerHandle* wrappedHandle = impl->interruptHandle.getHandle();
-
- if (impl->interruptHandle.queuedHandles()) {
- impl->interrupt();
- eh.setActive();
- } else {
- eh.setInactive();
- }
- return Event(wrappedHandle, INTERRUPTED);
- }
-
- if (pe.portev_source == PORT_SOURCE_FD) {
- QPID_LOG(trace, "About to send handle: " << handle);
- if (pe.portev_events & POLLHUP) {
- if (eh.isHungup()) {
- return Event(handle, DISCONNECTED);
- }
- eh.setHungup();
- } else {
- eh.setInactive();
- }
- QPID_LOG(trace, "Sending event (thread: "
- << pthread_self() << ") for handle " << handle
- << ", direction= "
- << PollerPrivate::pollToDirection(pe.portev_events));
- return Event(handle, PollerPrivate::pollToDirection(pe.portev_events));
- }
- } else if (eh.isDeleted()) {
- //Remove the handle from the poller
- int rc = ::port_dissociate(impl->portId, PORT_SOURCE_FD,
- (uintptr_t) eh.fd);
- if (rc == -1 && errno != EBADFD) {
- QPID_POSIX_CHECK(rc);
- }
- }
- }
-
- if (timeout == TIME_INFINITE) {
- continue;
- }
- if (rc == 0 && now() > targetTimeout) {
- PollerHandleDeletionManager.markAllUnusedInThisThread();
- return Event(0, TIMEOUT);
- }
- } while (true);
-}
-
-// Concrete constructors
-Poller::Poller() :
- impl(new PollerPrivate())
-{}
-
-Poller::~Poller() {
- delete impl;
-}
-
-}}
diff --git a/cpp/src/qpid/sys/solaris/SystemInfo.cpp b/cpp/src/qpid/sys/solaris/SystemInfo.cpp
deleted file mode 100755
index 765e5a7eb0..0000000000
--- a/cpp/src/qpid/sys/solaris/SystemInfo.cpp
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * 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/sys/SystemInfo.h"
-
-#define BSD_COMP
-#include <sys/ioctl.h>
-#include <netdb.h>
-#undef BDS_COMP
-
-
-#include <unistd.h>
-#include <net/if.h>
-#include <sys/types.h>
-#include <sys/utsname.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <stdio.h>
-#include <errno.h>
-#include <limits.h>
-#include <procfs.h>
-#include <fcntl.h>
-#include <sys/types.h>
-
-using namespace std;
-
-namespace qpid {
-namespace sys {
-
-long SystemInfo::concurrency() {
- return sysconf(_SC_NPROCESSORS_ONLN);
-}
-
-bool SystemInfo::getLocalHostname(Address &address) {
- char name[MAXHOSTNAMELEN];
- if (::gethostname(name, sizeof(name)) != 0)
- return false;
- address.host = name;
- return true;
-}
-
-static const string LOCALHOST("127.0.0.1");
-static const string TCP("tcp");
-
-void SystemInfo::getLocalIpAddresses(uint16_t port,
- std::vector<Address> &addrList) {
- int s = socket(PF_INET, SOCK_STREAM, 0);
- for (int i=1;;i++) {
- struct lifreq ifr;
- ifr.lifr_index = i;
- if (::ioctl(s, SIOCGIFADDR, &ifr) < 0) {
- break;
- }
- struct sockaddr_in *sin = (struct sockaddr_in *) &ifr.lifr_addr;
- std::string addr(inet_ntoa(sin->sin_addr));
- if (addr != LOCALHOST)
- addrList.push_back(Address(TCP, addr, port));
- }
- if (addrList.empty()) {
- addrList.push_back(Address(TCP, LOCALHOST, port));
- }
- close (s);
-}
-
-void SystemInfo::getSystemId(std::string &osName,
- std::string &nodeName,
- std::string &release,
- std::string &version,
- std::string &machine) {
- struct utsname _uname;
- if (uname (&_uname) == 0) {
- osName = _uname.sysname;
- nodeName = _uname.nodename;
- release = _uname.release;
- version = _uname.version;
- machine = _uname.machine;
- }
-}
-
-uint32_t SystemInfo::getProcessId()
-{
- return (uint32_t) ::getpid();
-}
-
-uint32_t SystemInfo::getParentProcessId()
-{
- return (uint32_t) ::getppid();
-}
-
-string SystemInfo::getProcessName()
-{
- psinfo processInfo;
- char procfile[PATH_MAX];
- int fd;
- string value;
-
- snprintf(procfile, PATH_MAX, "/proc/%d/psinfo", getProcessId());
- if ((fd = open(procfile, O_RDONLY)) >= 0) {
- if (read(fd, (void *) &processInfo, sizeof(processInfo)) == sizeof(processInfo)) {
- value = processInfo.pr_fname;
- }
- }
- return value;
-}
-
-}} // namespace qpid::sys
diff --git a/cpp/src/qpid/sys/ssl/SslHandler.cpp b/cpp/src/qpid/sys/ssl/SslHandler.cpp
deleted file mode 100644
index 5516d72065..0000000000
--- a/cpp/src/qpid/sys/ssl/SslHandler.cpp
+++ /dev/null
@@ -1,195 +0,0 @@
-/*
- *
- * 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/sys/ssl/SslHandler.h"
-
-#include "qpid/sys/ssl/SslIo.h"
-#include "qpid/sys/ssl/SslSocket.h"
-#include "qpid/framing/AMQP_HighestVersion.h"
-#include "qpid/framing/ProtocolInitiation.h"
-#include "qpid/log/Statement.h"
-
-#include <boost/bind.hpp>
-
-namespace qpid {
-namespace sys {
-namespace ssl {
-
-
-// Buffer definition
-struct Buff : public SslIO::BufferBase {
- Buff() :
- SslIO::BufferBase(new char[65536], 65536)
- {}
- ~Buff()
- { delete [] bytes;}
-};
-
-SslHandler::SslHandler(std::string id, ConnectionCodec::Factory* f, bool _nodict) :
- identifier(id),
- aio(0),
- factory(f),
- codec(0),
- readError(false),
- isClient(false),
- nodict(_nodict)
-{}
-
-SslHandler::~SslHandler() {
- if (codec)
- codec->closed();
- delete codec;
-}
-
-void SslHandler::init(SslIO* a, int numBuffs) {
- aio = a;
-
- // Give connection some buffers to use
- for (int i = 0; i < numBuffs; i++) {
- aio->queueReadBuffer(new Buff);
- }
-}
-
-void SslHandler::write(const framing::ProtocolInitiation& data)
-{
- QPID_LOG(debug, "SENT [" << identifier << "] INIT(" << data << ")");
- SslIO::BufferBase* buff = aio->getQueuedBuffer();
- if (!buff)
- buff = new Buff;
- framing::Buffer out(buff->bytes, buff->byteCount);
- data.encode(out);
- buff->dataCount = data.encodedSize();
- aio->queueWrite(buff);
-}
-
-void SslHandler::abort() {
- // TODO: can't implement currently as underlying functionality not implemented
- // aio->requestCallback(boost::bind(&SslHandler::eof, this, _1));
-}
-void SslHandler::activateOutput() {
- aio->notifyPendingWrite();
-}
-
-void SslHandler::giveReadCredit(int32_t) {
- // FIXME aconway 2008-12-05: not yet implemented.
-}
-
-// Input side
-void SslHandler::readbuff(SslIO& , SslIO::BufferBase* buff) {
- if (readError) {
- return;
- }
- size_t decoded = 0;
- if (codec) { // Already initiated
- try {
- decoded = codec->decode(buff->bytes+buff->dataStart, buff->dataCount);
- }catch(const std::exception& e){
- QPID_LOG(error, e.what());
- readError = true;
- aio->queueWriteClose();
- }
- }else{
- framing::Buffer in(buff->bytes+buff->dataStart, buff->dataCount);
- framing::ProtocolInitiation protocolInit;
- if (protocolInit.decode(in)) {
- decoded = in.getPosition();
- QPID_LOG(debug, "RECV [" << identifier << "] INIT(" << protocolInit << ")");
- try {
- codec = factory->create(protocolInit.getVersion(), *this, identifier, getSecuritySettings(aio));
- if (!codec) {
- //TODO: may still want to revise this...
- //send valid version header & close connection.
- write(framing::ProtocolInitiation(framing::highestProtocolVersion));
- readError = true;
- aio->queueWriteClose();
- }
- } catch (const std::exception& e) {
- QPID_LOG(error, e.what());
- readError = true;
- aio->queueWriteClose();
- }
- }
- }
- // TODO: unreading needs to go away, and when we can cope
- // with multiple sub-buffers in the general buffer scheme, it will
- if (decoded != size_t(buff->dataCount)) {
- // Adjust buffer for used bytes and then "unread them"
- buff->dataStart += decoded;
- buff->dataCount -= decoded;
- aio->unread(buff);
- } else {
- // Give whole buffer back to aio subsystem
- aio->queueReadBuffer(buff);
- }
-}
-
-void SslHandler::eof(SslIO&) {
- QPID_LOG(debug, "DISCONNECTED [" << identifier << "]");
- if (codec) codec->closed();
- aio->queueWriteClose();
-}
-
-void SslHandler::closedSocket(SslIO&, const SslSocket& s) {
- // If we closed with data still to send log a warning
- if (!aio->writeQueueEmpty()) {
- QPID_LOG(warning, "CLOSING [" << identifier << "] unsent data (probably due to client disconnect)");
- }
- delete &s;
- aio->queueForDeletion();
- delete this;
-}
-
-void SslHandler::disconnect(SslIO& a) {
- // treat the same as eof
- eof(a);
-}
-
-// Notifications
-void SslHandler::nobuffs(SslIO&) {
-}
-
-void SslHandler::idle(SslIO&){
- if (isClient && codec == 0) {
- codec = factory->create(*this, identifier, getSecuritySettings(aio));
- write(framing::ProtocolInitiation(codec->getVersion()));
- return;
- }
- if (codec == 0) return;
- if (codec->canEncode()) {
- // Try and get a queued buffer if not then construct new one
- SslIO::BufferBase* buff = aio->getQueuedBuffer();
- if (!buff) buff = new Buff;
- size_t encoded=codec->encode(buff->bytes, buff->byteCount);
- buff->dataCount = encoded;
- aio->queueWrite(buff);
- }
- if (codec->isClosed())
- aio->queueWriteClose();
-}
-
-SecuritySettings SslHandler::getSecuritySettings(SslIO* aio)
-{
- SecuritySettings settings = aio->getSecuritySettings();
- settings.nodict = nodict;
- return settings;
-}
-
-
-}}} // namespace qpid::sys::ssl
diff --git a/cpp/src/qpid/sys/ssl/SslHandler.h b/cpp/src/qpid/sys/ssl/SslHandler.h
deleted file mode 100644
index 400fa317fd..0000000000
--- a/cpp/src/qpid/sys/ssl/SslHandler.h
+++ /dev/null
@@ -1,78 +0,0 @@
-#ifndef QPID_SYS_SSL_SSLHANDLER_H
-#define QPID_SYS_SSL_SSLHANDLER_H
-
-/*
- *
- * 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/sys/ConnectionCodec.h"
-#include "qpid/sys/OutputControl.h"
-
-namespace qpid {
-
-namespace framing {
- class ProtocolInitiation;
-}
-
-namespace sys {
-namespace ssl {
-
-class SslIO;
-struct SslIOBufferBase;
-class SslSocket;
-
-class SslHandler : public OutputControl {
- std::string identifier;
- SslIO* aio;
- ConnectionCodec::Factory* factory;
- ConnectionCodec* codec;
- bool readError;
- bool isClient;
- bool nodict;
-
- void write(const framing::ProtocolInitiation&);
- qpid::sys::SecuritySettings getSecuritySettings(SslIO* aio);
-
- public:
- SslHandler(std::string id, ConnectionCodec::Factory* f, bool nodict);
- ~SslHandler();
- void init(SslIO* a, int numBuffs);
-
- void setClient() { isClient = true; }
-
- // Output side
- void abort();
- void activateOutput();
- void giveReadCredit(int32_t);
-
- // Input side
- void readbuff(SslIO& aio, SslIOBufferBase* buff);
- void eof(SslIO& aio);
- void disconnect(SslIO& aio);
-
- // Notifications
- void nobuffs(SslIO& aio);
- void idle(SslIO& aio);
- void closedSocket(SslIO& aio, const SslSocket& s);
-};
-
-}}} // namespace qpid::sys::ssl
-
-#endif /*!QPID_SYS_SSL_SSLHANDLER_H*/
diff --git a/cpp/src/qpid/sys/ssl/SslIo.cpp b/cpp/src/qpid/sys/ssl/SslIo.cpp
deleted file mode 100644
index a58a137473..0000000000
--- a/cpp/src/qpid/sys/ssl/SslIo.cpp
+++ /dev/null
@@ -1,447 +0,0 @@
-/*
- *
- * 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/sys/ssl/SslIo.h"
-#include "qpid/sys/ssl/SslSocket.h"
-#include "qpid/sys/ssl/check.h"
-
-#include "qpid/sys/Time.h"
-#include "qpid/sys/posix/check.h"
-#include "qpid/log/Statement.h"
-
-// TODO The basic algorithm here is not really POSIX specific and with a bit more abstraction
-// could (should) be promoted to be platform portable
-#include <unistd.h>
-#include <sys/socket.h>
-#include <signal.h>
-#include <errno.h>
-#include <string.h>
-
-#include <boost/bind.hpp>
-
-using namespace qpid::sys;
-using namespace qpid::sys::ssl;
-
-namespace {
-
-/*
- * Make *process* not generate SIGPIPE when writing to closed
- * pipe/socket (necessary as default action is to terminate process)
- */
-void ignoreSigpipe() {
- ::signal(SIGPIPE, SIG_IGN);
-}
-
-/*
- * We keep per thread state to avoid locking overhead. The assumption is that
- * on average all the connections are serviced by all the threads so the state
- * recorded in each thread is about the same. If this turns out not to be the
- * case we could rebalance the info occasionally.
- */
-__thread int threadReadTotal = 0;
-__thread int threadMaxRead = 0;
-__thread int threadReadCount = 0;
-__thread int threadWriteTotal = 0;
-__thread int threadWriteCount = 0;
-__thread int64_t threadMaxReadTimeNs = 2 * 1000000; // start at 2ms
-}
-
-/*
- * Asynch Acceptor
- */
-
-SslAcceptor::SslAcceptor(const SslSocket& s, Callback callback) :
- acceptedCallback(callback),
- handle(s, boost::bind(&SslAcceptor::readable, this, _1), 0, 0),
- socket(s) {
-
- s.setNonblocking();
- ignoreSigpipe();
-}
-
-SslAcceptor::~SslAcceptor()
-{
- handle.stopWatch();
-}
-
-void SslAcceptor::start(Poller::shared_ptr poller) {
- handle.startWatch(poller);
-}
-
-/*
- * We keep on accepting as long as there is something to accept
- */
-void SslAcceptor::readable(DispatchHandle& h) {
- SslSocket* s;
- do {
- errno = 0;
- // TODO: Currently we ignore the peers address, perhaps we should
- // log it or use it for connection acceptance.
- try {
- s = socket.accept();
- if (s) {
- acceptedCallback(*s);
- } else {
- break;
- }
- } catch (const std::exception& e) {
- QPID_LOG(error, "Could not accept socket: " << e.what());
- }
- } while (true);
-
- h.rewatch();
-}
-
-/*
- * Asynch Connector
- */
-
-SslConnector::SslConnector(const SslSocket& s,
- Poller::shared_ptr poller,
- std::string hostname,
- uint16_t port,
- ConnectedCallback connCb,
- FailedCallback failCb) :
- DispatchHandle(s,
- 0,
- boost::bind(&SslConnector::connComplete, this, _1),
- boost::bind(&SslConnector::connComplete, this, _1)),
- connCallback(connCb),
- failCallback(failCb),
- socket(s)
-{
- //TODO: would be better for connect to be performed on a
- //non-blocking socket, but that doesn't work at present so connect
- //blocks until complete
- try {
- socket.connect(hostname, port);
- socket.setNonblocking();
- startWatch(poller);
- } catch(std::exception& e) {
- failure(-1, std::string(e.what()));
- }
-}
-
-void SslConnector::connComplete(DispatchHandle& h)
-{
- int errCode = socket.getError();
-
- h.stopWatch();
- if (errCode == 0) {
- connCallback(socket);
- DispatchHandle::doDelete();
- } else {
- // TODO: This need to be fixed as strerror isn't thread safe
- failure(errCode, std::string(::strerror(errCode)));
- }
-}
-
-void SslConnector::failure(int errCode, std::string message)
-{
- if (failCallback)
- failCallback(errCode, message);
-
- socket.close();
- delete &socket;
-
- DispatchHandle::doDelete();
-}
-
-/*
- * Asynch reader/writer
- */
-SslIO::SslIO(const SslSocket& s,
- ReadCallback rCb, EofCallback eofCb, DisconnectCallback disCb,
- ClosedCallback cCb, BuffersEmptyCallback eCb, IdleCallback iCb) :
-
- DispatchHandle(s,
- boost::bind(&SslIO::readable, this, _1),
- boost::bind(&SslIO::writeable, this, _1),
- boost::bind(&SslIO::disconnected, this, _1)),
- readCallback(rCb),
- eofCallback(eofCb),
- disCallback(disCb),
- closedCallback(cCb),
- emptyCallback(eCb),
- idleCallback(iCb),
- socket(s),
- queuedClose(false),
- writePending(false) {
-
- s.setNonblocking();
-}
-
-struct deleter
-{
- template <typename T>
- void operator()(T *ptr){ delete ptr;}
-};
-
-SslIO::~SslIO() {
- std::for_each( bufferQueue.begin(), bufferQueue.end(), deleter());
- std::for_each( writeQueue.begin(), writeQueue.end(), deleter());
-}
-
-void SslIO::queueForDeletion() {
- DispatchHandle::doDelete();
-}
-
-void SslIO::start(Poller::shared_ptr poller) {
- DispatchHandle::startWatch(poller);
-}
-
-void SslIO::queueReadBuffer(BufferBase* buff) {
- assert(buff);
- buff->dataStart = 0;
- buff->dataCount = 0;
- bufferQueue.push_back(buff);
- DispatchHandle::rewatchRead();
-}
-
-void SslIO::unread(BufferBase* buff) {
- assert(buff);
- if (buff->dataStart != 0) {
- memmove(buff->bytes, buff->bytes+buff->dataStart, buff->dataCount);
- buff->dataStart = 0;
- }
- bufferQueue.push_front(buff);
- DispatchHandle::rewatchRead();
-}
-
-void SslIO::queueWrite(BufferBase* buff) {
- assert(buff);
- // If we've already closed the socket then throw the write away
- if (queuedClose) {
- bufferQueue.push_front(buff);
- return;
- } else {
- writeQueue.push_front(buff);
- }
- writePending = false;
- DispatchHandle::rewatchWrite();
-}
-
-void SslIO::notifyPendingWrite() {
- writePending = true;
- DispatchHandle::rewatchWrite();
-}
-
-void SslIO::queueWriteClose() {
- queuedClose = true;
- DispatchHandle::rewatchWrite();
-}
-
-/** Return a queued buffer if there are enough
- * to spare
- */
-SslIO::BufferBase* SslIO::getQueuedBuffer() {
- // Always keep at least one buffer (it might have data that was "unread" in it)
- if (bufferQueue.size()<=1)
- return 0;
- BufferBase* buff = bufferQueue.back();
- assert(buff);
- buff->dataStart = 0;
- buff->dataCount = 0;
- bufferQueue.pop_back();
- return buff;
-}
-
-/*
- * We keep on reading as long as we have something to read and a buffer to put
- * it in
- */
-void SslIO::readable(DispatchHandle& h) {
- int readTotal = 0;
- AbsTime readStartTime = AbsTime::now();
- do {
- // (Try to) get a buffer
- if (!bufferQueue.empty()) {
- // Read into buffer
- BufferBase* buff = bufferQueue.front();
- assert(buff);
- bufferQueue.pop_front();
- errno = 0;
- int readCount = buff->byteCount-buff->dataCount;
- int rc = socket.read(buff->bytes + buff->dataCount, readCount);
- if (rc > 0) {
- buff->dataCount += rc;
- threadReadTotal += rc;
- readTotal += rc;
-
- readCallback(*this, buff);
- if (rc != readCount) {
- // If we didn't fill the read buffer then time to stop reading
- break;
- }
-
- // Stop reading if we've overrun our timeslot
- if (Duration(readStartTime, AbsTime::now()) > threadMaxReadTimeNs) {
- break;
- }
-
- } else {
- // Put buffer back (at front so it doesn't interfere with unread buffers)
- bufferQueue.push_front(buff);
- assert(buff);
-
- // Eof or other side has gone away
- if (rc == 0 || errno == ECONNRESET) {
- eofCallback(*this);
- h.unwatchRead();
- break;
- } else if (errno == EAGAIN) {
- // We have just put a buffer back so we know
- // we can carry on watching for reads
- break;
- } else {
- // Report error then just treat as a socket disconnect
- QPID_LOG(error, "Error reading socket: " << getErrorString(PR_GetError()));
- eofCallback(*this);
- h.unwatchRead();
- break;
- }
- }
- } else {
- // Something to read but no buffer
- if (emptyCallback) {
- emptyCallback(*this);
- }
- // If we still have no buffers we can't do anything more
- if (bufferQueue.empty()) {
- h.unwatchRead();
- break;
- }
-
- }
- } while (true);
-
- ++threadReadCount;
- threadMaxRead = std::max(threadMaxRead, readTotal);
- return;
-}
-
-/*
- * We carry on writing whilst we have data to write and we can write
- */
-void SslIO::writeable(DispatchHandle& h) {
- int writeTotal = 0;
- do {
- // See if we've got something to write
- if (!writeQueue.empty()) {
- // Write buffer
- BufferBase* buff = writeQueue.back();
- writeQueue.pop_back();
- errno = 0;
- assert(buff->dataStart+buff->dataCount <= buff->byteCount);
- int rc = socket.write(buff->bytes+buff->dataStart, buff->dataCount);
- if (rc >= 0) {
- threadWriteTotal += rc;
- writeTotal += rc;
-
- // If we didn't write full buffer put rest back
- if (rc != buff->dataCount) {
- buff->dataStart += rc;
- buff->dataCount -= rc;
- writeQueue.push_back(buff);
- break;
- }
-
- // Recycle the buffer
- queueReadBuffer(buff);
-
- // If we've already written more than the max for reading then stop
- // (this is to stop writes dominating reads)
- if (writeTotal > threadMaxRead)
- break;
- } else {
- // Put buffer back
- writeQueue.push_back(buff);
- if (errno == ECONNRESET || errno == EPIPE) {
- // Just stop watching for write here - we'll get a
- // disconnect callback soon enough
- h.unwatchWrite();
- break;
- } else if (errno == EAGAIN) {
- // We have just put a buffer back so we know
- // we can carry on watching for writes
- break;
- } else {
- QPID_LOG(error, "Error writing to socket: " << getErrorString(PR_GetError()));
- h.unwatchWrite();
- break;
- }
- }
- } else {
- // If we're waiting to close the socket then can do it now as there is nothing to write
- if (queuedClose) {
- close(h);
- break;
- }
- // Fd is writable, but nothing to write
- if (idleCallback) {
- writePending = false;
- idleCallback(*this);
- }
- // If we still have no buffers to write we can't do anything more
- if (writeQueue.empty() && !writePending && !queuedClose) {
- h.unwatchWrite();
- // The following handles the case where writePending is
- // set to true after the test above; in this case its
- // possible that the unwatchWrite overwrites the
- // desired rewatchWrite so we correct that here
- if (writePending)
- h.rewatchWrite();
- break;
- }
- }
- } while (true);
-
- ++threadWriteCount;
- return;
-}
-
-void SslIO::disconnected(DispatchHandle& h) {
- // If we've already queued close do it instead of disconnected callback
- if (queuedClose) {
- close(h);
- } else if (disCallback) {
- disCallback(*this);
- h.unwatch();
- }
-}
-
-/*
- * Close the socket and callback to say we've done it
- */
-void SslIO::close(DispatchHandle& h) {
- h.stopWatch();
- socket.close();
- if (closedCallback) {
- closedCallback(*this, socket);
- }
-}
-
-SecuritySettings SslIO::getSecuritySettings() {
- SecuritySettings settings;
- settings.ssf = socket.getKeyLen();
- settings.authid = socket.getClientAuthId();
- return settings;
-}
diff --git a/cpp/src/qpid/sys/ssl/SslIo.h b/cpp/src/qpid/sys/ssl/SslIo.h
deleted file mode 100644
index 53ac69d8d6..0000000000
--- a/cpp/src/qpid/sys/ssl/SslIo.h
+++ /dev/null
@@ -1,172 +0,0 @@
-#ifndef _sys_ssl_SslIO
-#define _sys_ssl_SslIO
-/*
- *
- * 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/sys/DispatchHandle.h"
-#include "qpid/sys/SecuritySettings.h"
-
-#include <boost/function.hpp>
-#include <deque>
-
-namespace qpid {
-namespace sys {
-namespace ssl {
-
-class SslSocket;
-
-/*
- * Asynchronous ssl acceptor: accepts connections then does a callback
- * with the accepted fd
- */
-class SslAcceptor {
-public:
- typedef boost::function1<void, const SslSocket&> Callback;
-
-private:
- Callback acceptedCallback;
- qpid::sys::DispatchHandle handle;
- const SslSocket& socket;
-
-public:
- SslAcceptor(const SslSocket& s, Callback callback);
- ~SslAcceptor();
- void start(qpid::sys::Poller::shared_ptr poller);
-
-private:
- void readable(qpid::sys::DispatchHandle& handle);
-};
-
-/*
- * Asynchronous ssl connector: starts the process of initiating a
- * connection and invokes a callback when completed or failed.
- */
-class SslConnector : private qpid::sys::DispatchHandle {
-public:
- typedef boost::function1<void, const SslSocket&> ConnectedCallback;
- typedef boost::function2<void, int, std::string> FailedCallback;
-
-private:
- ConnectedCallback connCallback;
- FailedCallback failCallback;
- const SslSocket& socket;
-
-public:
- SslConnector(const SslSocket& socket,
- Poller::shared_ptr poller,
- std::string hostname,
- uint16_t port,
- ConnectedCallback connCb,
- FailedCallback failCb = 0);
-
-private:
- void connComplete(DispatchHandle& handle);
- void failure(int, std::string);
-};
-
-struct SslIOBufferBase {
- char* const bytes;
- const int32_t byteCount;
- int32_t dataStart;
- int32_t dataCount;
-
- SslIOBufferBase(char* const b, const int32_t s) :
- bytes(b),
- byteCount(s),
- dataStart(0),
- dataCount(0)
- {}
-
- virtual ~SslIOBufferBase()
- {}
-};
-
-/*
- * Asychronous reader/writer:
- * Reader accepts buffers to read into; reads into the provided buffers
- * and then does a callback with the buffer and amount read. Optionally it can callback
- * when there is something to read but no buffer to read it into.
- *
- * Writer accepts a buffer and queues it for writing; can also be given
- * a callback for when writing is "idle" (ie fd is writable, but nothing to write)
- *
- * The class is implemented in terms of DispatchHandle to allow it to be deleted by deleting
- * the contained DispatchHandle
- */
-class SslIO : private qpid::sys::DispatchHandle {
-public:
- typedef SslIOBufferBase BufferBase;
-
- typedef boost::function2<void, SslIO&, BufferBase*> ReadCallback;
- typedef boost::function1<void, SslIO&> EofCallback;
- typedef boost::function1<void, SslIO&> DisconnectCallback;
- typedef boost::function2<void, SslIO&, const SslSocket&> ClosedCallback;
- typedef boost::function1<void, SslIO&> BuffersEmptyCallback;
- typedef boost::function1<void, SslIO&> IdleCallback;
-
-
-private:
- ReadCallback readCallback;
- EofCallback eofCallback;
- DisconnectCallback disCallback;
- ClosedCallback closedCallback;
- BuffersEmptyCallback emptyCallback;
- IdleCallback idleCallback;
- const SslSocket& socket;
- std::deque<BufferBase*> bufferQueue;
- std::deque<BufferBase*> writeQueue;
- bool queuedClose;
- /**
- * This flag is used to detect and handle concurrency between
- * calls to notifyPendingWrite() (which can be made from any thread) and
- * the execution of the writeable() method (which is always on the
- * thread processing this handle.
- */
- volatile bool writePending;
-
-public:
- SslIO(const SslSocket& s,
- ReadCallback rCb, EofCallback eofCb, DisconnectCallback disCb,
- ClosedCallback cCb = 0, BuffersEmptyCallback eCb = 0, IdleCallback iCb = 0);
- void queueForDeletion();
-
- void start(qpid::sys::Poller::shared_ptr poller);
- void queueReadBuffer(BufferBase* buff);
- void unread(BufferBase* buff);
- void queueWrite(BufferBase* buff);
- void notifyPendingWrite();
- void queueWriteClose();
- bool writeQueueEmpty() { return writeQueue.empty(); }
- BufferBase* getQueuedBuffer();
-
- qpid::sys::SecuritySettings getSecuritySettings();
-
-private:
- ~SslIO();
- void readable(qpid::sys::DispatchHandle& handle);
- void writeable(qpid::sys::DispatchHandle& handle);
- void disconnected(qpid::sys::DispatchHandle& handle);
- void close(qpid::sys::DispatchHandle& handle);
-};
-
-}}}
-
-#endif // _sys_ssl_SslIO
diff --git a/cpp/src/qpid/sys/ssl/SslSocket.cpp b/cpp/src/qpid/sys/ssl/SslSocket.cpp
deleted file mode 100644
index 01e2658877..0000000000
--- a/cpp/src/qpid/sys/ssl/SslSocket.cpp
+++ /dev/null
@@ -1,360 +0,0 @@
-/*
- *
- * 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/sys/ssl/SslSocket.h"
-#include "qpid/sys/ssl/check.h"
-#include "qpid/sys/ssl/util.h"
-#include "qpid/Exception.h"
-#include "qpid/sys/posix/check.h"
-#include "qpid/sys/posix/PrivatePosix.h"
-
-#include <fcntl.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/errno.h>
-#include <netinet/in.h>
-#include <netinet/tcp.h>
-#include <netdb.h>
-#include <cstdlib>
-#include <string.h>
-#include <iostream>
-
-#include <private/pprio.h>
-#include <nss.h>
-#include <pk11pub.h>
-#include <ssl.h>
-#include <key.h>
-
-#include <boost/format.hpp>
-
-namespace qpid {
-namespace sys {
-namespace ssl {
-
-namespace {
-std::string getName(int fd, bool local, bool includeService = false)
-{
- ::sockaddr_storage name; // big enough for any socket address
- ::socklen_t namelen = sizeof(name);
-
- int result = -1;
- if (local) {
- result = ::getsockname(fd, (::sockaddr*)&name, &namelen);
- } else {
- result = ::getpeername(fd, (::sockaddr*)&name, &namelen);
- }
-
- QPID_POSIX_CHECK(result);
-
- char servName[NI_MAXSERV];
- char dispName[NI_MAXHOST];
- if (includeService) {
- if (int rc=::getnameinfo((::sockaddr*)&name, namelen, dispName, sizeof(dispName),
- servName, sizeof(servName),
- NI_NUMERICHOST | NI_NUMERICSERV) != 0)
- throw QPID_POSIX_ERROR(rc);
- return std::string(dispName) + ":" + std::string(servName);
-
- } else {
- if (int rc=::getnameinfo((::sockaddr*)&name, namelen, dispName, sizeof(dispName), 0, 0, NI_NUMERICHOST) != 0)
- throw QPID_POSIX_ERROR(rc);
- return dispName;
- }
-}
-
-std::string getService(int fd, bool local)
-{
- ::sockaddr_storage name; // big enough for any socket address
- ::socklen_t namelen = sizeof(name);
-
- int result = -1;
- if (local) {
- result = ::getsockname(fd, (::sockaddr*)&name, &namelen);
- } else {
- result = ::getpeername(fd, (::sockaddr*)&name, &namelen);
- }
-
- QPID_POSIX_CHECK(result);
-
- char servName[NI_MAXSERV];
- if (int rc=::getnameinfo((::sockaddr*)&name, namelen, 0, 0,
- servName, sizeof(servName),
- NI_NUMERICHOST | NI_NUMERICSERV) != 0)
- throw QPID_POSIX_ERROR(rc);
- return servName;
-}
-
-const std::string DOMAIN_SEPARATOR("@");
-const std::string DC_SEPARATOR(".");
-const std::string DC("DC");
-const std::string DN_DELIMS(" ,=");
-
-std::string getDomainFromSubject(std::string subject)
-{
- std::string::size_type last = subject.find_first_not_of(DN_DELIMS, 0);
- std::string::size_type i = subject.find_first_of(DN_DELIMS, last);
-
- std::string domain;
- bool nextTokenIsDC = false;
- while (std::string::npos != i || std::string::npos != last)
- {
- std::string token = subject.substr(last, i - last);
- if (nextTokenIsDC) {
- if (domain.size()) domain += DC_SEPARATOR;
- domain += token;
- nextTokenIsDC = false;
- } else if (token == DC) {
- nextTokenIsDC = true;
- }
- last = subject.find_first_not_of(DN_DELIMS, i);
- i = subject.find_first_of(DN_DELIMS, last);
- }
- return domain;
-}
-
-}
-
-SslSocket::SslSocket() : IOHandle(new IOHandlePrivate()), socket(0), prototype(0)
-{
- impl->fd = ::socket (PF_INET, SOCK_STREAM, 0);
- if (impl->fd < 0) throw QPID_POSIX_ERROR(errno);
- socket = SSL_ImportFD(0, PR_ImportTCPSocket(impl->fd));
-}
-
-/**
- * This form of the constructor is used with the server-side sockets
- * returned from accept. Because we use posix accept rather than
- * PR_Accept, we have to reset the handshake.
- */
-SslSocket::SslSocket(IOHandlePrivate* ioph, PRFileDesc* model) : IOHandle(ioph), socket(0), prototype(0)
-{
- socket = SSL_ImportFD(model, PR_ImportTCPSocket(impl->fd));
- NSS_CHECK(SSL_ResetHandshake(socket, true));
-}
-
-void SslSocket::setNonblocking() const
-{
- PRSocketOptionData option;
- option.option = PR_SockOpt_Nonblocking;
- option.value.non_blocking = true;
- PR_SetSocketOption(socket, &option);
-}
-
-void SslSocket::connect(const std::string& host, uint16_t port) const
-{
- std::stringstream namestream;
- namestream << host << ":" << port;
- connectname = namestream.str();
-
- void* arg;
- // Use the connection's cert-name if it has one; else use global cert-name
- if (certname != "") {
- arg = const_cast<char*>(certname.c_str());
- } else if (SslOptions::global.certName.empty()) {
- arg = 0;
- } else {
- arg = const_cast<char*>(SslOptions::global.certName.c_str());
- }
- NSS_CHECK(SSL_GetClientAuthDataHook(socket, NSS_GetClientAuthData, arg));
- NSS_CHECK(SSL_SetURL(socket, host.data()));
-
- char hostBuffer[PR_NETDB_BUF_SIZE];
- PRHostEnt hostEntry;
- PR_CHECK(PR_GetHostByName(host.data(), hostBuffer, PR_NETDB_BUF_SIZE, &hostEntry));
- PRNetAddr address;
- int value = PR_EnumerateHostEnt(0, &hostEntry, port, &address);
- if (value < 0) {
- throw Exception(QPID_MSG("Error getting address for host: " << ErrorString()));
- } else if (value == 0) {
- throw Exception(QPID_MSG("Could not resolve address for host."));
- }
- PR_CHECK(PR_Connect(socket, &address, PR_INTERVAL_NO_TIMEOUT));
- NSS_CHECK(SSL_ForceHandshake(socket));
-}
-
-void SslSocket::close() const
-{
- if (impl->fd > 0) {
- PR_Close(socket);
- impl->fd = -1;
- }
-}
-
-int SslSocket::listen(uint16_t port, int backlog, const std::string& certName, bool clientAuth) const
-{
- //configure prototype socket:
- prototype = SSL_ImportFD(0, PR_NewTCPSocket());
- if (clientAuth) {
- NSS_CHECK(SSL_OptionSet(prototype, SSL_REQUEST_CERTIFICATE, PR_TRUE));
- NSS_CHECK(SSL_OptionSet(prototype, SSL_REQUIRE_CERTIFICATE, PR_TRUE));
- }
-
- //get certificate and key (is this the correct way?)
- CERTCertificate *cert = PK11_FindCertFromNickname(const_cast<char*>(certName.c_str()), 0);
- if (!cert) throw Exception(QPID_MSG("Failed to load certificate '" << certName << "'"));
- SECKEYPrivateKey *key = PK11_FindKeyByAnyCert(cert, 0);
- if (!key) throw Exception(QPID_MSG("Failed to retrieve private key from certificate"));
- NSS_CHECK(SSL_ConfigSecureServer(prototype, cert, key, NSS_FindCertKEAType(cert)));
- SECKEY_DestroyPrivateKey(key);
- CERT_DestroyCertificate(cert);
-
- //bind and listen
- const int& socket = impl->fd;
- int yes=1;
- QPID_POSIX_CHECK(setsockopt(socket,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(yes)));
- 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 Exception(QPID_MSG("Can't bind to port " << port << ": " << strError(errno)));
- if (::listen(socket, backlog) < 0)
- throw Exception(QPID_MSG("Can't listen on port " << port << ": " << strError(errno)));
-
- socklen_t namelen = sizeof(name);
- if (::getsockname(socket, (struct sockaddr*)&name, &namelen) < 0)
- throw QPID_POSIX_ERROR(errno);
-
- return ntohs(name.sin_port);
-}
-
-SslSocket* SslSocket::accept() const
-{
- int afd = ::accept(impl->fd, 0, 0);
- if ( afd >= 0) {
- return new SslSocket(new IOHandlePrivate(afd), prototype);
- } else if (errno == EAGAIN) {
- return 0;
- } else {
- throw QPID_POSIX_ERROR(errno);
- }
-}
-
-int SslSocket::read(void *buf, size_t count) const
-{
- return PR_Read(socket, buf, count);
-}
-
-int SslSocket::write(const void *buf, size_t count) const
-{
- return PR_Write(socket, buf, count);
-}
-
-std::string SslSocket::getSockname() const
-{
- return getName(impl->fd, true);
-}
-
-std::string SslSocket::getPeername() const
-{
- return getName(impl->fd, false);
-}
-
-std::string SslSocket::getPeerAddress() const
-{
- if (!connectname.empty())
- return connectname;
- return getName(impl->fd, false, true);
-}
-
-std::string SslSocket::getLocalAddress() const
-{
- return getName(impl->fd, true, true);
-}
-
-uint16_t SslSocket::getLocalPort() const
-{
- return std::atoi(getService(impl->fd, true).c_str());
-}
-
-uint16_t SslSocket::getRemotePort() const
-{
- return atoi(getService(impl->fd, true).c_str());
-}
-
-int SslSocket::getError() const
-{
- int result;
- socklen_t rSize = sizeof (result);
-
- if (::getsockopt(impl->fd, SOL_SOCKET, SO_ERROR, &result, &rSize) < 0)
- throw QPID_POSIX_ERROR(errno);
-
- return result;
-}
-
-void SslSocket::setTcpNoDelay(bool nodelay) const
-{
- if (nodelay) {
- PRSocketOptionData option;
- option.option = PR_SockOpt_NoDelay;
- option.value.no_delay = true;
- PR_SetSocketOption(socket, &option);
- }
-}
-
-void SslSocket::setCertName(const std::string& name)
-{
- certname = name;
-}
-
-
-/** get the bit length of the current cipher's key */
-int SslSocket::getKeyLen() const
-{
- int enabled = 0;
- int keySize = 0;
- SECStatus rc;
-
- rc = SSL_SecurityStatus( socket,
- &enabled,
- NULL,
- NULL,
- &keySize,
- NULL, NULL );
- if (rc == SECSuccess && enabled) {
- return keySize;
- }
- return 0;
-}
-
-std::string SslSocket::getClientAuthId() const
-{
- std::string authId;
- CERTCertificate* cert = SSL_PeerCertificate(socket);
- if (cert) {
- authId = CERT_GetCommonName(&(cert->subject));
- /*
- * The NSS function CERT_GetDomainComponentName only returns
- * the last component of the domain name, so we have to parse
- * the subject manually to extract the full domain.
- */
- std::string domain = getDomainFromSubject(cert->subjectName);
- if (!domain.empty()) {
- authId += DOMAIN_SEPARATOR;
- authId += domain;
- }
- CERT_DestroyCertificate(cert);
- }
- return authId;
-}
-
-}}} // namespace qpid::sys::ssl
diff --git a/cpp/src/qpid/sys/ssl/SslSocket.h b/cpp/src/qpid/sys/ssl/SslSocket.h
deleted file mode 100644
index 25712c98d5..0000000000
--- a/cpp/src/qpid/sys/ssl/SslSocket.h
+++ /dev/null
@@ -1,132 +0,0 @@
-#ifndef _sys_ssl_Socket_h
-#define _sys_ssl_Socket_h
-
-/*
- *
- * 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/sys/IOHandle.h"
-#include <nspr.h>
-
-#include <string>
-
-struct sockaddr;
-
-namespace qpid {
-namespace sys {
-
-class Duration;
-
-namespace ssl {
-
-class SslSocket : public qpid::sys::IOHandle
-{
-public:
- /** Create a socket wrapper for descriptor. */
- SslSocket();
-
- /** Set socket non blocking */
- void setNonblocking() const;
-
- /** Set tcp-nodelay */
- void setTcpNoDelay(bool nodelay) const;
-
- /** Set SSL cert-name. Allows the cert-name to be set per
- * connection, overriding global cert-name settings from
- * NSSInit().*/
- void setCertName(const std::string& certName);
-
- void connect(const std::string& host, uint16_t port) const;
-
- void close() const;
-
- /** Bind to a port and start listening.
- *@param port 0 means choose an available port.
- *@param backlog maximum number of pending connections.
- *@param certName name of certificate to use to identify the server
- *@return The bound port.
- */
- int listen(uint16_t port = 0, int backlog = 10, const std::string& certName = "localhost.localdomain", bool clientAuth = false) const;
-
- /**
- * Accept a connection from a socket that is already listening
- * and has an incoming connection
- */
- SslSocket* accept() const;
-
- // TODO The following are raw operations, maybe they need better wrapping?
- int read(void *buf, size_t count) const;
- int write(const void *buf, size_t count) const;
-
- /** Returns the "socket name" ie the address bound to
- * the near end of the socket
- */
- std::string getSockname() const;
-
- /** Returns the "peer name" ie the address bound to
- * the remote end of the socket
- */
- std::string getPeername() const;
-
- /**
- * Returns an address (host and port) for the remote end of the
- * socket
- */
- std::string getPeerAddress() const;
- /**
- * Returns an address (host and port) for the local end of the
- * socket
- */
- std::string getLocalAddress() const;
-
- /**
- * Returns the full address of the connection: local and remote host and port.
- */
- std::string getFullAddress() const { return getLocalAddress()+"-"+getPeerAddress(); }
-
- uint16_t getLocalPort() const;
- uint16_t getRemotePort() const;
-
- /**
- * Returns the error code stored in the socket. This may be used
- * to determine the result of a non-blocking connect.
- */
- int getError() const;
-
- int getKeyLen() const;
- std::string getClientAuthId() const;
-
-private:
- mutable std::string connectname;
- mutable PRFileDesc* socket;
- std::string certname;
-
- /**
- * 'model' socket, with configuration to use when importing
- * accepted sockets for use as ssl sockets. Set on listen(), used
- * in accept to pass through to newly created socket instances.
- */
- mutable PRFileDesc* prototype;
-
- SslSocket(IOHandlePrivate* ioph, PRFileDesc* model);
-};
-
-}}}
-#endif /*!_sys_ssl_Socket_h*/
diff --git a/cpp/src/qpid/sys/ssl/check.cpp b/cpp/src/qpid/sys/ssl/check.cpp
deleted file mode 100644
index 72a2e265bd..0000000000
--- a/cpp/src/qpid/sys/ssl/check.cpp
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- *
- * 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/sys/ssl/check.h"
-#include <secerr.h>
-#include <sslerr.h>
-#include <boost/format.hpp>
-
-using boost::format;
-using boost::str;
-
-namespace qpid {
-namespace sys {
-namespace ssl {
-
-ErrorString::ErrorString() : code(PR_GetError()), buffer(new char[PR_GetErrorTextLength()]), used(PR_GetErrorText(buffer)) {}
-
-ErrorString::~ErrorString()
-{
- delete[] buffer;
-}
-
-std::string ErrorString::getString() const
-{
- std::string msg = std::string(buffer, used);
- if (!used) {
- //seems most of the NSPR/NSS errors don't have text set for
- //them, add a few specific ones in here. (TODO: more complete
- //list?):
- return getErrorString(code);
- } else {
- return str(format("%1% [%2%]") % msg % code);
- }
-}
-
-std::string getErrorString(int code)
-{
- std::string msg;
- switch (code) {
- case SSL_ERROR_EXPORT_ONLY_SERVER: msg = "Unable to communicate securely. Peer does not support high-grade encryption."; break;
- case SSL_ERROR_US_ONLY_SERVER: msg = "Unable to communicate securely. Peer requires high-grade encryption which is not supported."; break;
- case SSL_ERROR_NO_CYPHER_OVERLAP: msg = "Cannot communicate securely with peer: no common encryption algorithm(s)."; break;
- case SSL_ERROR_NO_CERTIFICATE: msg = "Unable to find the certificate or key necessary for authentication."; break;
- case SSL_ERROR_BAD_CERTIFICATE: msg = "Unable to communicate securely with peer: peers's certificate was rejected."; break;
- case SSL_ERROR_UNSUPPORTED_CERTIFICATE_TYPE: msg = "Unsupported certificate type."; break;
- case SSL_ERROR_WRONG_CERTIFICATE: msg = "Client authentication failed: private key in key database does not correspond to public key in certificate database."; break;
- case SSL_ERROR_BAD_CERT_DOMAIN: msg = "Unable to communicate securely with peer: requested domain name does not match the server's certificate."; break;
- case SSL_ERROR_BAD_CERT_ALERT: msg = "SSL peer cannot verify your certificate."; break;
- case SSL_ERROR_REVOKED_CERT_ALERT: msg = "SSL peer rejected your certificate as revoked."; break;
- case SSL_ERROR_EXPIRED_CERT_ALERT: msg = "SSL peer rejected your certificate as expired."; break;
-
- case PR_DIRECTORY_LOOKUP_ERROR: msg = "A directory lookup on a network address has failed"; break;
- case PR_CONNECT_RESET_ERROR: msg = "TCP connection reset by peer"; break;
- case PR_END_OF_FILE_ERROR: msg = "Encountered end of file"; break;
- case SEC_ERROR_EXPIRED_CERTIFICATE: msg = "Peer's certificate has expired"; break;
- default: msg = (code < -6000) ? "NSS error" : "NSPR error"; break;
- }
- return str(format("%1% [%2%]") % msg % code);
-}
-
-std::ostream& operator<<(std::ostream& out, const ErrorString& err)
-{
- out << err.getString();
- return out;
-}
-
-
-}}} // namespace qpid::sys::ssl
diff --git a/cpp/src/qpid/sys/ssl/check.h b/cpp/src/qpid/sys/ssl/check.h
deleted file mode 100644
index 28d3c74ad0..0000000000
--- a/cpp/src/qpid/sys/ssl/check.h
+++ /dev/null
@@ -1,57 +0,0 @@
-#ifndef QPID_SYS_SSL_CHECK_H
-#define QPID_SYS_SSL_CHECK_H
-
-/*
- *
- * 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/Msg.h"
-
-#include <iostream>
-#include <string>
-#include <nspr.h>
-#include <nss.h>
-
-namespace qpid {
-namespace sys {
-namespace ssl {
-
-std::string getErrorString(int code);
-
-class ErrorString
-{
- public:
- ErrorString();
- ~ErrorString();
- std::string getString() const;
- private:
- const int code;
- char* const buffer;
- const size_t used;
-};
-
-std::ostream& operator<<(std::ostream& out, const ErrorString& err);
-
-}}} // namespace qpid::sys::ssl
-
-
-#define NSS_CHECK(value) if (value != SECSuccess) { throw Exception(QPID_MSG("Failed: " << qpid::sys::ssl::ErrorString())); }
-#define PR_CHECK(value) if (value != PR_SUCCESS) { throw Exception(QPID_MSG("Failed: " << qpid::sys::ssl::ErrorString())); }
-
-#endif /*!QPID_SYS_SSL_CHECK_H*/
diff --git a/cpp/src/qpid/sys/ssl/util.cpp b/cpp/src/qpid/sys/ssl/util.cpp
deleted file mode 100644
index 3078e894df..0000000000
--- a/cpp/src/qpid/sys/ssl/util.cpp
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- *
- * 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/sys/ssl/util.h"
-#include "qpid/sys/ssl/check.h"
-#include "qpid/Exception.h"
-#include "qpid/sys/SystemInfo.h"
-
-#include <unistd.h>
-#include <nspr.h>
-#include <nss.h>
-#include <pk11pub.h>
-#include <ssl.h>
-
-#include <iostream>
-#include <fstream>
-#include <boost/filesystem/operations.hpp>
-#include <boost/filesystem/path.hpp>
-
-namespace qpid {
-namespace sys {
-namespace ssl {
-
-static const std::string LOCALHOST("127.0.0.1");
-
-std::string defaultCertName()
-{
- Address address;
- if (SystemInfo::getLocalHostname(address)) {
- return address.host;
- } else {
- return LOCALHOST;
- }
-}
-
-SslOptions::SslOptions() : qpid::Options("SSL Settings"),
- certName(defaultCertName()),
- exportPolicy(false)
-{
- addOptions()
- ("ssl-use-export-policy", optValue(exportPolicy), "Use NSS export policy")
- ("ssl-cert-password-file", optValue(certPasswordFile, "PATH"), "File containing password to use for accessing certificate database")
- ("ssl-cert-db", optValue(certDbPath, "PATH"), "Path to directory containing certificate database")
- ("ssl-cert-name", optValue(certName, "NAME"), "Name of the certificate to use");
-}
-
-SslOptions& SslOptions::operator=(const SslOptions& o)
-{
- certDbPath = o.certDbPath;
- certName = o.certName;
- certPasswordFile = o.certPasswordFile;
- exportPolicy = o.exportPolicy;
- return *this;
-}
-
-char* promptForPassword(PK11SlotInfo*, PRBool retry, void*)
-{
- if (retry) return 0;
- //TODO: something else?
- return PL_strdup(getpass("Please enter the password for accessing the certificate database:"));
-}
-
-SslOptions SslOptions::global;
-
-char* readPasswordFromFile(PK11SlotInfo*, PRBool retry, void*)
-{
- const std::string& passwordFile = SslOptions::global.certPasswordFile;
- if (retry || passwordFile.empty() || !boost::filesystem::exists(passwordFile)) {
- return 0;
- } else {
- std::ifstream file(passwordFile.c_str());
- std::string password;
- file >> password;
- return PL_strdup(password.c_str());
- }
-}
-
-void initNSS(const SslOptions& options, bool server)
-{
- SslOptions::global = options;
- if (options.certPasswordFile.empty()) {
- PK11_SetPasswordFunc(promptForPassword);
- } else {
- PK11_SetPasswordFunc(readPasswordFromFile);
- }
- NSS_CHECK(NSS_Init(options.certDbPath.c_str()));
- if (options.exportPolicy) {
- NSS_CHECK(NSS_SetExportPolicy());
- } else {
- NSS_CHECK(NSS_SetDomesticPolicy());
- }
- if (server) {
- //use defaults for all args, TODO: may want to make this configurable
- SSL_ConfigServerSessionIDCache(0, 0, 0, 0);
- }
-}
-
-void shutdownNSS()
-{
- NSS_Shutdown();
-}
-
-}}} // namespace qpid::sys::ssl
diff --git a/cpp/src/qpid/sys/ssl/util.h b/cpp/src/qpid/sys/ssl/util.h
deleted file mode 100644
index f34adab7be..0000000000
--- a/cpp/src/qpid/sys/ssl/util.h
+++ /dev/null
@@ -1,50 +0,0 @@
-#ifndef QPID_SYS_SSL_UTIL_H
-#define QPID_SYS_SSL_UTIL_H
-
-/*
- *
- * 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/Options.h"
-#include <string>
-
-namespace qpid {
-namespace sys {
-namespace ssl {
-
-struct SslOptions : qpid::Options
-{
- static SslOptions global;
-
- std::string certDbPath;
- std::string certName;
- std::string certPasswordFile;
- bool exportPolicy;
-
- SslOptions();
- SslOptions& operator=(const SslOptions&);
-};
-
-void initNSS(const SslOptions& options, bool server = false);
-void shutdownNSS();
-
-}}} // namespace qpid::sys::ssl
-
-#endif /*!QPID_SYS_SSL_UTIL_H*/
diff --git a/cpp/src/qpid/sys/uuid.h b/cpp/src/qpid/sys/uuid.h
deleted file mode 100644
index 804ab34463..0000000000
--- a/cpp/src/qpid/sys/uuid.h
+++ /dev/null
@@ -1,28 +0,0 @@
-#ifndef _sys_uuid_h
-#define _sys_uuid_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 _WIN32
-# include "qpid/sys/windows/uuid.h"
-#else
-# include <uuid/uuid.h>
-#endif /* _WIN32 */
-
-#endif /* _sys_uuid_h */
diff --git a/cpp/src/qpid/sys/windows/AsynchIO.cpp b/cpp/src/qpid/sys/windows/AsynchIO.cpp
deleted file mode 100644
index 71138757a5..0000000000
--- a/cpp/src/qpid/sys/windows/AsynchIO.cpp
+++ /dev/null
@@ -1,755 +0,0 @@
-/*
- *
- * 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/sys/windows/AsynchIoResult.h"
-#include "qpid/sys/windows/IoHandlePrivate.h"
-#include "qpid/sys/AsynchIO.h"
-#include "qpid/sys/Mutex.h"
-#include "qpid/sys/Socket.h"
-#include "qpid/sys/Poller.h"
-#include "qpid/sys/Thread.h"
-#include "qpid/sys/Time.h"
-#include "qpid/log/Statement.h"
-
-#include "qpid/sys/windows/check.h"
-#include "qpid/sys/windows/mingw32_compat.h"
-
-#include <boost/thread/once.hpp>
-
-#include <queue>
-#include <winsock2.h>
-#include <mswsock.h>
-#include <windows.h>
-
-#include <boost/bind.hpp>
-
-namespace {
-
- typedef qpid::sys::ScopedLock<qpid::sys::Mutex> QLock;
-
-/*
- * The function pointers for AcceptEx and ConnectEx need to be looked up
- * at run time. Make sure this is done only once.
- */
-boost::once_flag lookUpAcceptExOnce = BOOST_ONCE_INIT;
-LPFN_ACCEPTEX fnAcceptEx = 0;
-typedef void (*lookUpFunc)(const qpid::sys::Socket &);
-
-void lookUpAcceptEx() {
- SOCKET h = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
- GUID guidAcceptEx = WSAID_ACCEPTEX;
- DWORD dwBytes = 0;
- WSAIoctl(h,
- SIO_GET_EXTENSION_FUNCTION_POINTER,
- &guidAcceptEx,
- sizeof(guidAcceptEx),
- &fnAcceptEx,
- sizeof(fnAcceptEx),
- &dwBytes,
- NULL,
- NULL);
- closesocket(h);
- if (fnAcceptEx == 0)
- throw qpid::Exception(QPID_MSG("Failed to look up AcceptEx"));
-}
-
-}
-
-namespace qpid {
-namespace sys {
-namespace windows {
-
-/*
- * Asynch Acceptor
- *
- */
-class AsynchAcceptor : public qpid::sys::AsynchAcceptor {
-
- friend class AsynchAcceptResult;
-
-public:
- AsynchAcceptor(const Socket& s, AsynchAcceptor::Callback callback);
- ~AsynchAcceptor();
- void start(Poller::shared_ptr poller);
-
-private:
- void restart(void);
-
- AsynchAcceptor::Callback acceptedCallback;
- const Socket& socket;
-};
-
-AsynchAcceptor::AsynchAcceptor(const Socket& s, Callback callback)
- : acceptedCallback(callback),
- socket(s) {
-
- s.setNonblocking();
-#if (BOOST_VERSION >= 103500) /* boost 1.35 or later reversed the args */
- boost::call_once(lookUpAcceptExOnce, lookUpAcceptEx);
-#else
- boost::call_once(lookUpAcceptEx, lookUpAcceptExOnce);
-#endif
-}
-
-AsynchAcceptor::~AsynchAcceptor()
-{
- socket.close();
-}
-
-void AsynchAcceptor::start(Poller::shared_ptr poller) {
- PollerHandle ph = PollerHandle(socket);
- poller->monitorHandle(ph, Poller::INPUT);
- restart ();
-}
-
-void AsynchAcceptor::restart(void) {
- DWORD bytesReceived = 0; // Not used, needed for AcceptEx API
- AsynchAcceptResult *result = new AsynchAcceptResult(acceptedCallback,
- this,
- toSocketHandle(socket));
- BOOL status;
- status = ::fnAcceptEx(toSocketHandle(socket),
- toSocketHandle(*result->newSocket),
- result->addressBuffer,
- 0,
- AsynchAcceptResult::SOCKADDRMAXLEN,
- AsynchAcceptResult::SOCKADDRMAXLEN,
- &bytesReceived,
- result->overlapped());
- QPID_WINDOWS_CHECK_ASYNC_START(status);
-}
-
-
-AsynchAcceptResult::AsynchAcceptResult(AsynchAcceptor::Callback cb,
- AsynchAcceptor *acceptor,
- SOCKET listener)
- : callback(cb), acceptor(acceptor), listener(listener) {
- newSocket.reset (new Socket());
-}
-
-void AsynchAcceptResult::success(size_t /*bytesTransferred*/) {
- ::setsockopt (toSocketHandle(*newSocket),
- SOL_SOCKET,
- SO_UPDATE_ACCEPT_CONTEXT,
- (char*)&listener,
- sizeof (listener));
- callback(*(newSocket.release()));
- acceptor->restart ();
- delete this;
-}
-
-void AsynchAcceptResult::failure(int /*status*/) {
- //if (status != WSA_OPERATION_ABORTED)
- // Can there be anything else? ;
- delete this;
-}
-
-/*
- * AsynchConnector does synchronous connects for now... to do asynch the
- * IocpPoller will need some extension to register an event handle as a
- * CONNECT-type "direction", the connect completion/result will need an
- * event handle to associate with the connecting handle. But there's no
- * time for that right now...
- */
-class AsynchConnector : public qpid::sys::AsynchConnector {
-private:
- ConnectedCallback connCallback;
- FailedCallback failCallback;
- const Socket& socket;
- const std::string hostname;
- const uint16_t port;
-
-public:
- AsynchConnector(const Socket& socket,
- std::string hostname,
- uint16_t port,
- ConnectedCallback connCb,
- FailedCallback failCb = 0);
- void start(Poller::shared_ptr poller);
-};
-
-AsynchConnector::AsynchConnector(const Socket& sock,
- std::string hname,
- uint16_t p,
- ConnectedCallback connCb,
- FailedCallback failCb) :
- connCallback(connCb), failCallback(failCb), socket(sock),
- hostname(hname), port(p)
-{
-}
-
-void AsynchConnector::start(Poller::shared_ptr)
-{
- try {
- socket.connect(hostname, port);
- socket.setNonblocking();
- connCallback(socket);
- } catch(std::exception& e) {
- if (failCallback)
- failCallback(socket, -1, std::string(e.what()));
- socket.close();
- }
-}
-
-} // namespace windows
-
-AsynchAcceptor* AsynchAcceptor::create(const Socket& s,
- Callback callback)
-{
- return new windows::AsynchAcceptor(s, callback);
-}
-
-AsynchConnector* qpid::sys::AsynchConnector::create(const Socket& s,
- std::string hostname,
- uint16_t port,
- ConnectedCallback connCb,
- FailedCallback failCb)
-{
- return new windows::AsynchConnector(s,
- hostname,
- port,
- connCb,
- failCb);
-}
-
-
-/*
- * Asynch reader/writer
- */
-
-namespace windows {
-
-class AsynchIO : public qpid::sys::AsynchIO {
-public:
- AsynchIO(const Socket& s,
- ReadCallback rCb,
- EofCallback eofCb,
- DisconnectCallback disCb,
- ClosedCallback cCb = 0,
- BuffersEmptyCallback eCb = 0,
- IdleCallback iCb = 0);
- ~AsynchIO();
-
- // Methods inherited from qpid::sys::AsynchIO
-
- /**
- * Notify the object is should delete itself as soon as possible.
- */
- virtual void queueForDeletion();
-
- /// Take any actions needed to prepare for working with the poller.
- virtual void start(Poller::shared_ptr poller);
- virtual void queueReadBuffer(BufferBase* buff);
- virtual void unread(BufferBase* buff);
- virtual void queueWrite(BufferBase* buff);
- virtual void notifyPendingWrite();
- virtual void queueWriteClose();
- virtual bool writeQueueEmpty();
- virtual void startReading();
- virtual void stopReading();
- virtual void requestCallback(RequestCallback);
-
- /**
- * getQueuedBuffer returns a buffer from the buffer queue, if one is
- * available.
- *
- * @retval Pointer to BufferBase buffer; 0 if none is available.
- */
- virtual BufferBase* getQueuedBuffer();
-
-private:
- ReadCallback readCallback;
- EofCallback eofCallback;
- DisconnectCallback disCallback;
- ClosedCallback closedCallback;
- BuffersEmptyCallback emptyCallback;
- IdleCallback idleCallback;
- const Socket& socket;
- Poller::shared_ptr poller;
-
- std::deque<BufferBase*> bufferQueue;
- std::deque<BufferBase*> writeQueue;
- /* The MSVC-supplied deque is not thread-safe; keep locks to serialize
- * access to the buffer queue and write queue.
- */
- Mutex bufferQueueLock;
-
- // Number of outstanding I/O operations.
- volatile LONG opsInProgress;
- // Is there a write in progress?
- volatile bool writeInProgress;
- // Deletion requested, but there are callbacks in progress.
- volatile bool queuedDelete;
- // Socket close requested, but there are operations in progress.
- volatile bool queuedClose;
-
-private:
- // Dispatch events that have completed.
- void notifyEof(void);
- void notifyDisconnect(void);
- void notifyClosed(void);
- void notifyBuffersEmpty(void);
- void notifyIdle(void);
-
- /**
- * Initiate a write of the specified buffer. There's no callback for
- * write completion to the AsynchIO object.
- */
- void startWrite(AsynchIO::BufferBase* buff);
-
- void close(void);
-
- /**
- * readComplete is called when a read request is complete.
- *
- * @param result Results of the operation.
- */
- void readComplete(AsynchReadResult *result);
-
- /**
- * writeComplete is called when a write request is complete.
- *
- * @param result Results of the operation.
- */
- void writeComplete(AsynchWriteResult *result);
-
- /**
- * Queue of completions to run. This queue enforces the requirement
- * from upper layers that only one thread at a time is allowed to act
- * on any given connection. Once a thread is busy processing a completion
- * on this object, other threads that dispatch completions queue the
- * completions here for the in-progress thread to handle when done.
- * Thus, any threads can dispatch a completion from the IocpPoller, but
- * this class ensures that actual processing at the connection level is
- * only on one thread at a time.
- */
- std::queue<AsynchIoResult *> completionQueue;
- volatile bool working;
- Mutex completionLock;
-
- /**
- * Called when there's a completion to process.
- */
- void completion(AsynchIoResult *result);
-};
-
-// This is used to encapsulate pure callbacks into a handle
-class CallbackHandle : public IOHandle {
-public:
- CallbackHandle(AsynchIoResult::Completer completeCb,
- AsynchIO::RequestCallback reqCb = 0) :
- IOHandle(new IOHandlePrivate (INVALID_SOCKET, completeCb, reqCb))
- {}
-};
-
-AsynchIO::AsynchIO(const Socket& s,
- ReadCallback rCb,
- EofCallback eofCb,
- DisconnectCallback disCb,
- ClosedCallback cCb,
- BuffersEmptyCallback eCb,
- IdleCallback iCb) :
-
- readCallback(rCb),
- eofCallback(eofCb),
- disCallback(disCb),
- closedCallback(cCb),
- emptyCallback(eCb),
- idleCallback(iCb),
- socket(s),
- opsInProgress(0),
- writeInProgress(false),
- queuedDelete(false),
- queuedClose(false),
- working(false) {
-}
-
-struct deleter
-{
- template <typename T>
- void operator()(T *ptr){ delete ptr;}
-};
-
-AsynchIO::~AsynchIO() {
- std::for_each( bufferQueue.begin(), bufferQueue.end(), deleter());
- std::for_each( writeQueue.begin(), writeQueue.end(), deleter());
-}
-
-void AsynchIO::queueForDeletion() {
- queuedDelete = true;
- if (opsInProgress > 0) {
- QPID_LOG(info, "Delete AsynchIO queued; ops in progress");
- // AsynchIOHandler calls this then deletes itself; don't do any more
- // callbacks.
- readCallback = 0;
- eofCallback = 0;
- disCallback = 0;
- closedCallback = 0;
- emptyCallback = 0;
- idleCallback = 0;
- }
- else {
- delete this;
- }
-}
-
-void AsynchIO::start(Poller::shared_ptr poller0) {
- PollerHandle ph = PollerHandle(socket);
- poller = poller0;
- poller->monitorHandle(ph, Poller::INPUT);
- if (writeQueue.size() > 0) // Already have data queued for write
- notifyPendingWrite();
- startReading();
-}
-
-void AsynchIO::queueReadBuffer(AsynchIO::BufferBase* buff) {
- assert(buff);
- buff->dataStart = 0;
- buff->dataCount = 0;
- QLock l(bufferQueueLock);
- bufferQueue.push_back(buff);
-}
-
-void AsynchIO::unread(AsynchIO::BufferBase* buff) {
- assert(buff);
- buff->squish();
- QLock l(bufferQueueLock);
- bufferQueue.push_front(buff);
-}
-
-void AsynchIO::queueWrite(AsynchIO::BufferBase* buff) {
- assert(buff);
- QLock l(bufferQueueLock);
- writeQueue.push_back(buff);
- if (!writeInProgress)
- notifyPendingWrite();
-}
-
-void AsynchIO::notifyPendingWrite() {
- // This method is generally called from a processing thread; transfer
- // work on this to an I/O thread. Much of the upper layer code assumes
- // that all I/O-related things happen in an I/O thread.
- if (poller == 0) // Not really going yet...
- return;
-
- InterlockedIncrement(&opsInProgress);
- PollerHandle ph(CallbackHandle(boost::bind(&AsynchIO::completion, this, _1)));
- poller->monitorHandle(ph, Poller::OUTPUT);
-}
-
-void AsynchIO::queueWriteClose() {
- queuedClose = true;
- if (!writeInProgress)
- notifyPendingWrite();
-}
-
-bool AsynchIO::writeQueueEmpty() {
- QLock l(bufferQueueLock);
- return writeQueue.size() == 0;
-}
-
-/*
- * Initiate a read operation. AsynchIO::readComplete() will be
- * called when the read is complete and data is available.
- */
-void AsynchIO::startReading() {
- if (queuedDelete)
- return;
-
- // (Try to) get a buffer; look on the front since there may be an
- // "unread" one there with data remaining from last time.
- AsynchIO::BufferBase *buff = 0;
- {
- QLock l(bufferQueueLock);
-
- if (!bufferQueue.empty()) {
- buff = bufferQueue.front();
- assert(buff);
- bufferQueue.pop_front();
- }
- }
- if (buff != 0) {
- int readCount = buff->byteCount - buff->dataCount;
- AsynchReadResult *result =
- new AsynchReadResult(boost::bind(&AsynchIO::completion, this, _1),
- buff,
- readCount);
- DWORD bytesReceived = 0, flags = 0;
- InterlockedIncrement(&opsInProgress);
- int status = WSARecv(toSocketHandle(socket),
- const_cast<LPWSABUF>(result->getWSABUF()), 1,
- &bytesReceived,
- &flags,
- result->overlapped(),
- 0);
- if (status != 0) {
- int error = WSAGetLastError();
- if (error != WSA_IO_PENDING) {
- result->failure(error);
- result = 0; // result is invalid here
- return;
- }
- }
- // On status 0 or WSA_IO_PENDING, completion will handle the rest.
- }
- else {
- notifyBuffersEmpty();
- }
- return;
-}
-
-// stopReading was added to prevent a race condition with read-credit on Linux.
-// It may or may not be required on windows.
-//
-// AsynchIOHandler::readbuff() calls stopReading() inside the same
-// critical section that protects startReading() in
-// AsynchIOHandler::giveReadCredit().
-//
-void AsynchIO::stopReading() {}
-
-// Queue the specified callback for invocation from an I/O thread.
-void AsynchIO::requestCallback(RequestCallback callback) {
- // This method is generally called from a processing thread; transfer
- // work on this to an I/O thread. Much of the upper layer code assumes
- // that all I/O-related things happen in an I/O thread.
- if (poller == 0) // Not really going yet...
- return;
-
- InterlockedIncrement(&opsInProgress);
- PollerHandle ph(CallbackHandle(
- boost::bind(&AsynchIO::completion, this, _1),
- callback));
- poller->monitorHandle(ph, Poller::INPUT);
-}
-
-/**
- * Return a queued buffer if there are enough to spare.
- */
-AsynchIO::BufferBase* AsynchIO::getQueuedBuffer() {
- QLock l(bufferQueueLock);
- // Always keep at least one buffer (it might have data that was
- // "unread" in it).
- if (bufferQueue.size() <= 1)
- return 0;
- BufferBase* buff = bufferQueue.back();
- assert(buff);
- bufferQueue.pop_back();
- return buff;
-}
-
-void AsynchIO::notifyEof(void) {
- if (eofCallback)
- eofCallback(*this);
-}
-
-void AsynchIO::notifyDisconnect(void) {
- if (disCallback)
- disCallback(*this);
-}
-
-void AsynchIO::notifyClosed(void) {
- if (closedCallback)
- closedCallback(*this, socket);
-}
-
-void AsynchIO::notifyBuffersEmpty(void) {
- if (emptyCallback)
- emptyCallback(*this);
-}
-
-void AsynchIO::notifyIdle(void) {
- if (idleCallback)
- idleCallback(*this);
-}
-
-/*
- * Asynch reader/writer using overlapped I/O
- */
-
-void AsynchIO::startWrite(AsynchIO::BufferBase* buff) {
- writeInProgress = true;
- InterlockedIncrement(&opsInProgress);
- AsynchWriteResult *result =
- new AsynchWriteResult(boost::bind(&AsynchIO::completion, this, _1),
- buff,
- buff->dataCount);
- DWORD bytesSent = 0;
- int status = WSASend(toSocketHandle(socket),
- const_cast<LPWSABUF>(result->getWSABUF()), 1,
- &bytesSent,
- 0,
- result->overlapped(),
- 0);
- if (status != 0) {
- int error = WSAGetLastError();
- if (error != WSA_IO_PENDING) {
- result->failure(error); // Also decrements in-progress count
- result = 0; // result is invalid here
- return;
- }
- }
- // On status 0 or WSA_IO_PENDING, completion will handle the rest.
- return;
-}
-
-/*
- * Close the socket and callback to say we've done it
- */
-void AsynchIO::close(void) {
- socket.close();
- notifyClosed();
-}
-
-void AsynchIO::readComplete(AsynchReadResult *result) {
- int status = result->getStatus();
- size_t bytes = result->getTransferred();
- if (status == 0 && bytes > 0) {
- bool restartRead = true; // May not if receiver doesn't want more
- if (readCallback)
- readCallback(*this, result->getBuff());
- if (restartRead)
- startReading();
- }
- else {
- // No data read, so put the buffer back. It may be partially filled,
- // so "unread" it back to the front of the queue.
- unread(result->getBuff());
- notifyEof();
- if (status != 0)
- {
- notifyDisconnect();
- }
- }
-}
-
-/*
- * NOTE - this completion is called for completed writes and also when
- * a write is desired. The difference is in the buff - if a write is desired
- * the buff is 0.
- */
-void AsynchIO::writeComplete(AsynchWriteResult *result) {
- int status = result->getStatus();
- size_t bytes = result->getTransferred();
- AsynchIO::BufferBase *buff = result->getBuff();
- if (buff != 0) {
- writeInProgress = false;
- if (status == 0 && bytes > 0) {
- if (bytes < result->getRequested()) // Still more to go; resubmit
- startWrite(buff);
- else
- queueReadBuffer(buff); // All done; back to the pool
- }
- else {
- // An error... if it's a connection close, ignore it - it will be
- // noticed and handled on a read completion any moment now.
- // What to do with real error??? Save the Buffer?
- }
- }
-
- // If there are no writes outstanding, check for more writes to initiate
- // (either queued or via idle). The opsInProgress count is handled in
- // completion()
- if (!writeInProgress) {
- bool writing = false;
- {
- QLock l(bufferQueueLock);
- if (writeQueue.size() > 0) {
- buff = writeQueue.front();
- assert(buff);
- writeQueue.pop_front();
- startWrite(buff);
- writing = true;
- }
- }
- if (!writing && !queuedClose) {
- notifyIdle();
- }
- }
- return;
-}
-
-void AsynchIO::completion(AsynchIoResult *result) {
- {
- ScopedLock<Mutex> l(completionLock);
- if (working) {
- completionQueue.push(result);
- return;
- }
-
- // First thread in with something to do; note we're working then keep
- // handling completions.
- working = true;
- while (result != 0) {
- // New scope to unlock temporarily.
- {
- ScopedUnlock<Mutex> ul(completionLock);
- AsynchReadResult *r = dynamic_cast<AsynchReadResult*>(result);
- if (r != 0)
- readComplete(r);
- else {
- AsynchWriteResult *w =
- dynamic_cast<AsynchWriteResult*>(result);
- if (w != 0)
- writeComplete(w);
- else {
- AsynchCallbackRequest *req =
- dynamic_cast<AsynchCallbackRequest*>(result);
- req->reqCallback(*this);
- }
- }
- delete result;
- result = 0;
- InterlockedDecrement(&opsInProgress);
- }
- // Lock is held again.
- if (completionQueue.empty())
- continue;
- result = completionQueue.front();
- completionQueue.pop();
- }
- working = false;
- }
- // Lock released; ok to close if ops are done and close requested.
- // Layer above will call back to queueForDeletion() if it hasn't
- // already been done. If it already has, go ahead and delete.
- if (opsInProgress == 0) {
- if (queuedClose)
- // close() may cause a delete; don't trust 'this' on return
- close();
- else if (queuedDelete)
- delete this;
- }
-}
-
-} // namespace windows
-
-AsynchIO* qpid::sys::AsynchIO::create(const Socket& s,
- AsynchIO::ReadCallback rCb,
- AsynchIO::EofCallback eofCb,
- AsynchIO::DisconnectCallback disCb,
- AsynchIO::ClosedCallback cCb,
- AsynchIO::BuffersEmptyCallback eCb,
- AsynchIO::IdleCallback iCb)
-{
- return new qpid::sys::windows::AsynchIO(s, rCb, eofCb, disCb, cCb, eCb, iCb);
-}
-
-}} // namespace qpid::sys
diff --git a/cpp/src/qpid/sys/windows/AsynchIoResult.h b/cpp/src/qpid/sys/windows/AsynchIoResult.h
deleted file mode 100755
index b11324918b..0000000000
--- a/cpp/src/qpid/sys/windows/AsynchIoResult.h
+++ /dev/null
@@ -1,204 +0,0 @@
-#ifndef _windows_asynchIoResult_h
-#define _windows_asynchIoResult_h
-
-/*
- *
- * 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/sys/AsynchIO.h"
-#include "qpid/sys/Socket.h"
-#include <memory.h>
-#include <winsock2.h>
-#include <ws2tcpip.h>
-
-namespace qpid {
-namespace sys {
-namespace windows {
-
-/*
- * AsynchIoResult defines the class that receives the result of an
- * asynchronous I/O operation, either send/recv or accept/connect.
- *
- * Operation factories should set one of these up before beginning the
- * operation. Poller knows how to dispatch completion to this class.
- * This class must be subclassed for needed operations; this class provides
- * an interface only and cannot be instantiated.
- *
- * This class is tied to Windows; it inherits from OVERLAPPED so that the
- * IocpPoller can cast OVERLAPPED pointers back to AsynchIoResult and call
- * the completion handler.
- */
-class AsynchResult : private OVERLAPPED {
-public:
- LPOVERLAPPED overlapped(void) { return this; }
- static AsynchResult* from_overlapped(LPOVERLAPPED ol) {
- return static_cast<AsynchResult*>(ol);
- }
- virtual void success (size_t bytesTransferred) {
- bytes = bytesTransferred;
- status = 0;
- complete();
- }
- virtual void failure (int error) {
- bytes = 0;
- status = error;
- complete();
- }
- size_t getTransferred(void) const { return bytes; }
- int getStatus(void) const { return status; }
-
-protected:
- AsynchResult() : bytes(0), status(0)
- { memset(overlapped(), 0, sizeof(OVERLAPPED)); }
- ~AsynchResult() {}
- virtual void complete(void) = 0;
-
- size_t bytes;
- int status;
-};
-
-class AsynchAcceptor;
-
-class AsynchAcceptResult : public AsynchResult {
-
- friend class AsynchAcceptor;
-
-public:
- AsynchAcceptResult(qpid::sys::AsynchAcceptor::Callback cb,
- AsynchAcceptor *acceptor,
- SOCKET listener);
- virtual void success (size_t bytesTransferred);
- virtual void failure (int error);
-
-private:
- virtual void complete(void) {} // No-op for this class.
-
- std::auto_ptr<qpid::sys::Socket> newSocket;
- qpid::sys::AsynchAcceptor::Callback callback;
- AsynchAcceptor *acceptor;
- SOCKET listener;
-
- // AcceptEx needs a place to write the local and remote addresses
- // when accepting the connection. Place those here; get enough for
- // IPv6 addresses, even if the socket is IPv4.
- enum { SOCKADDRMAXLEN = sizeof(sockaddr_in6) + 16,
- SOCKADDRBUFLEN = 2 * SOCKADDRMAXLEN };
- char addressBuffer[SOCKADDRBUFLEN];
-};
-
-class AsynchIoResult : public AsynchResult {
-public:
- typedef boost::function1<void, AsynchIoResult *> Completer;
-
- virtual ~AsynchIoResult() {}
- qpid::sys::AsynchIO::BufferBase *getBuff(void) const { return iobuff; }
- size_t getRequested(void) const { return requested; }
- const WSABUF *getWSABUF(void) const { return &wsabuf; }
-
-protected:
- void setBuff (qpid::sys::AsynchIO::BufferBase *buffer) { iobuff = buffer; }
-
-protected:
- AsynchIoResult(Completer cb,
- qpid::sys::AsynchIO::BufferBase *buff, size_t length)
- : completionCallback(cb), iobuff(buff), requested(length) {}
-
- virtual void complete(void) = 0;
- WSABUF wsabuf;
- Completer completionCallback;
-
-private:
- qpid::sys::AsynchIO::BufferBase *iobuff;
- size_t requested; // Number of bytes in original I/O request
-};
-
-class AsynchReadResult : public AsynchIoResult {
-
- // complete() updates buffer then does completion callback.
- virtual void complete(void) {
- getBuff()->dataCount += bytes;
- completionCallback(this);
- }
-
-public:
- AsynchReadResult(AsynchIoResult::Completer cb,
- qpid::sys::AsynchIO::BufferBase *buff,
- size_t length)
- : AsynchIoResult(cb, buff, length) {
- wsabuf.buf = buff->bytes + buff->dataCount;
- wsabuf.len = length;
- }
-};
-
-class AsynchWriteResult : public AsynchIoResult {
-
- // complete() updates buffer then does completion callback.
- virtual void complete(void) {
- qpid::sys::AsynchIO::BufferBase *b = getBuff();
- b->dataStart += bytes;
- b->dataCount -= bytes;
- completionCallback(this);
- }
-
-public:
- AsynchWriteResult(AsynchIoResult::Completer cb,
- qpid::sys::AsynchIO::BufferBase *buff,
- size_t length)
- : AsynchIoResult(cb, buff, length) {
- wsabuf.buf = buff ? buff->bytes : 0;
- wsabuf.len = length;
- }
-};
-
-class AsynchWriteWanted : public AsynchWriteResult {
-
- // complete() just does completion callback; no buffers used.
- virtual void complete(void) {
- completionCallback(this);
- }
-
-public:
- AsynchWriteWanted(AsynchIoResult::Completer cb)
- : AsynchWriteResult(cb, 0, 0) {
- wsabuf.buf = 0;
- wsabuf.len = 0;
- }
-};
-
-class AsynchCallbackRequest : public AsynchIoResult {
- // complete() needs to simply call the completionCallback; no buffers.
- virtual void complete(void) {
- completionCallback(this);
- }
-
-public:
- AsynchCallbackRequest(AsynchIoResult::Completer cb,
- qpid::sys::AsynchIO::RequestCallback reqCb)
- : AsynchIoResult(cb, 0, 0), reqCallback(reqCb) {
- wsabuf.buf = 0;
- wsabuf.len = 0;
- }
-
- qpid::sys::AsynchIO::RequestCallback reqCallback;
-};
-
-}}} // qpid::sys::windows
-
-#endif /*!_windows_asynchIoResult_h*/
diff --git a/cpp/src/qpid/sys/windows/FileSysDir.cpp b/cpp/src/qpid/sys/windows/FileSysDir.cpp
deleted file mode 100644
index 88f1637d48..0000000000
--- a/cpp/src/qpid/sys/windows/FileSysDir.cpp
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- *
- * 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/sys/FileSysDir.h"
-#include "qpid/sys/StrError.h"
-#include "qpid/Exception.h"
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <direct.h>
-#include <errno.h>
-
-namespace qpid {
-namespace sys {
-
-bool FileSysDir::exists (void) const
-{
- const char *cpath = dirPath.c_str ();
- struct _stat s;
- if (::_stat(cpath, &s)) {
- if (errno == ENOENT) {
- return false;
- }
- throw qpid::Exception (strError(errno) +
- ": Can't check directory: " + dirPath);
- }
- if (s.st_mode & _S_IFDIR)
- return true;
- throw qpid::Exception(dirPath + " is not a directory");
-}
-
-void FileSysDir::mkdir(void)
-{
- if (::_mkdir(dirPath.c_str()) == -1)
- throw Exception ("Can't create directory: " + dirPath);
-}
-
-}} // namespace qpid::sys
diff --git a/cpp/src/qpid/sys/windows/IOHandle.cpp b/cpp/src/qpid/sys/windows/IOHandle.cpp
deleted file mode 100755
index 250737cb99..0000000000
--- a/cpp/src/qpid/sys/windows/IOHandle.cpp
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- *
- * 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/sys/IOHandle.h"
-#include "qpid/sys/windows/IoHandlePrivate.h"
-#include <windows.h>
-
-namespace qpid {
-namespace sys {
-
-SOCKET toFd(const IOHandlePrivate* h)
-{
- return h->fd;
-}
-
-IOHandle::IOHandle(IOHandlePrivate* h) :
- impl(h)
-{}
-
-IOHandle::~IOHandle() {
- delete impl;
-}
-
-}} // namespace qpid::sys
diff --git a/cpp/src/qpid/sys/windows/IoHandlePrivate.h b/cpp/src/qpid/sys/windows/IoHandlePrivate.h
deleted file mode 100755
index 5943db5cc7..0000000000
--- a/cpp/src/qpid/sys/windows/IoHandlePrivate.h
+++ /dev/null
@@ -1,61 +0,0 @@
-#ifndef _sys_windows_IoHandlePrivate_h
-#define _sys_windows_IoHandlePrivate_h
-
-/*
- *
- * 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/sys/AsynchIO.h"
-#include "qpid/sys/windows/AsynchIoResult.h"
-#include "qpid/CommonImportExport.h"
-
-#include <winsock2.h>
-
-namespace qpid {
-namespace sys {
-
-// Private fd related implementation details
-// There should be either a valid socket handle or a completer callback.
-// Handle is used to associate with poller's iocp; completer is used to
-// inject a completion that will very quickly trigger a callback to the
-// completer from an I/O thread. If the callback mechanism is used, there
-// can be a RequestCallback set - this carries the callback object through
-// from AsynchIO::requestCallback() through to the I/O completion processing.
-class IOHandlePrivate {
- friend QPID_COMMON_EXTERN SOCKET toSocketHandle(const Socket& s);
- static IOHandlePrivate* getImpl(const IOHandle& h);
-
-public:
- IOHandlePrivate(SOCKET f = INVALID_SOCKET,
- windows::AsynchIoResult::Completer cb = 0,
- AsynchIO::RequestCallback reqCallback = 0) :
- fd(f), event(cb), cbRequest(reqCallback)
- {}
-
- SOCKET fd;
- windows::AsynchIoResult::Completer event;
- AsynchIO::RequestCallback cbRequest;
-};
-
-QPID_COMMON_EXTERN SOCKET toSocketHandle(const Socket& s);
-
-}}
-
-#endif /* _sys_windows_IoHandlePrivate_h */
diff --git a/cpp/src/qpid/sys/windows/IocpPoller.cpp b/cpp/src/qpid/sys/windows/IocpPoller.cpp
deleted file mode 100755
index 1805dd2cd8..0000000000
--- a/cpp/src/qpid/sys/windows/IocpPoller.cpp
+++ /dev/null
@@ -1,219 +0,0 @@
-/*
- *
- * 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/sys/Poller.h"
-#include "qpid/sys/Mutex.h"
-#include "qpid/sys/Dispatcher.h"
-
-#include "qpid/sys/windows/AsynchIoResult.h"
-#include "qpid/sys/windows/IoHandlePrivate.h"
-#include "qpid/sys/windows/check.h"
-
-#include <winsock2.h>
-#include <windows.h>
-
-#include <assert.h>
-#include <vector>
-#include <exception>
-
-namespace qpid {
-namespace sys {
-
-class PollerHandlePrivate {
- friend class Poller;
- friend class PollerHandle;
-
- SOCKET fd;
- windows::AsynchIoResult::Completer cb;
- AsynchIO::RequestCallback cbRequest;
-
- PollerHandlePrivate(SOCKET f,
- windows::AsynchIoResult::Completer cb0 = 0,
- AsynchIO::RequestCallback rcb = 0)
- : fd(f), cb(cb0), cbRequest(rcb)
- {
- }
-
-};
-
-PollerHandle::PollerHandle(const IOHandle& h) :
- impl(new PollerHandlePrivate(toSocketHandle(static_cast<const Socket&>(h)), h.impl->event, h.impl->cbRequest))
-{}
-
-PollerHandle::~PollerHandle() {
- delete impl;
-}
-
-/**
- * Concrete implementation of Poller to use the Windows I/O Completion
- * port (IOCP) facility.
- */
-class PollerPrivate {
- friend class Poller;
-
- const HANDLE iocp;
-
- // The number of threads running the event loop.
- volatile LONG threadsRunning;
-
- // Shutdown request is handled by setting isShutdown and injecting a
- // well-formed completion event into the iocp.
- bool isShutdown;
-
- PollerPrivate() :
- iocp(::CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0)),
- threadsRunning(0),
- isShutdown(false) {
- QPID_WINDOWS_CHECK_NULL(iocp);
- }
-
- ~PollerPrivate() {
- // It's probably okay to ignore any errors here as there can't be
- // data loss
- ::CloseHandle(iocp);
- }
-};
-
-void Poller::shutdown() {
- // Allow sloppy code to shut us down more than once.
- if (impl->isShutdown)
- return;
- ULONG_PTR key = 1; // Tell wait() it's a shutdown, not I/O
- PostQueuedCompletionStatus(impl->iocp, 0, key, 0);
-}
-
-bool Poller::hasShutdown()
-{
- return impl->isShutdown;
-}
-
-bool Poller::interrupt(PollerHandle&) {
- return false; // There's no concept of a registered handle.
-}
-
-void Poller::run() {
- do {
- Poller::Event event = this->wait();
-
- // Handle shutdown
- switch (event.type) {
- case Poller::SHUTDOWN:
- return;
- break;
- case Poller::INVALID: // On any type of success or fail completion
- break;
- default:
- // This should be impossible
- assert(false);
- }
- } while (true);
-}
-
-void Poller::monitorHandle(PollerHandle& handle, Direction dir) {
- HANDLE h = (HANDLE)(handle.impl->fd);
- if (h != INVALID_HANDLE_VALUE) {
- HANDLE iocpHandle = ::CreateIoCompletionPort (h, impl->iocp, 0, 0);
- QPID_WINDOWS_CHECK_NULL(iocpHandle);
- }
- else {
- // INPUT is used to request a callback; OUTPUT to request a write
- assert(dir == Poller::INPUT || dir == Poller::OUTPUT);
-
- if (dir == Poller::OUTPUT) {
- windows::AsynchWriteWanted *result =
- new windows::AsynchWriteWanted(handle.impl->cb);
- PostQueuedCompletionStatus(impl->iocp, 0, 0, result->overlapped());
- }
- else {
- windows::AsynchCallbackRequest *result =
- new windows::AsynchCallbackRequest(handle.impl->cb,
- handle.impl->cbRequest);
- PostQueuedCompletionStatus(impl->iocp, 0, 0, result->overlapped());
- }
- }
-}
-
-// All no-ops...
-void Poller::unmonitorHandle(PollerHandle& /*handle*/, Direction /*dir*/) {}
-void Poller::registerHandle(PollerHandle& /*handle*/) {}
-void Poller::unregisterHandle(PollerHandle& /*handle*/) {}
-
-Poller::Event Poller::wait(Duration timeout) {
- DWORD timeoutMs = 0;
- DWORD numTransferred = 0;
- ULONG_PTR completionKey = 0;
- OVERLAPPED *overlapped = 0;
- windows::AsynchResult *result = 0;
-
- // Wait for either an I/O operation to finish (thus signaling the
- // IOCP handle) or a shutdown request to be made (thus signaling the
- // shutdown event).
- if (timeout == TIME_INFINITE)
- timeoutMs = INFINITE;
- else
- timeoutMs = static_cast<DWORD>(timeout / TIME_MSEC);
-
- InterlockedIncrement(&impl->threadsRunning);
- bool goodOp = ::GetQueuedCompletionStatus (impl->iocp,
- &numTransferred,
- &completionKey,
- &overlapped,
- timeoutMs);
- LONG remainingThreads = InterlockedDecrement(&impl->threadsRunning);
- if (goodOp) {
- // Dequeued a successful completion. If it's a posted packet from
- // shutdown() the overlapped ptr is 0 and key is 1. Else downcast
- // the OVERLAPPED pointer to an AsynchIoResult and call the
- // completion handler.
- if (overlapped == 0 && completionKey == 1) {
- // If there are other threads still running this wait, re-post
- // the completion.
- if (remainingThreads > 0)
- PostQueuedCompletionStatus(impl->iocp, 0, completionKey, 0);
- return Event(0, SHUTDOWN);
- }
-
- result = windows::AsynchResult::from_overlapped(overlapped);
- result->success (static_cast<size_t>(numTransferred));
- }
- else {
- if (overlapped != 0) {
- // Dequeued a completion for a failed operation. Downcast back
- // to the result object and inform it that the operation failed.
- DWORD status = ::GetLastError();
- result = windows::AsynchResult::from_overlapped(overlapped);
- result->failure (static_cast<int>(status));
- }
- }
- return Event(0, INVALID); // TODO - this may need to be changed.
-
-}
-
-// Concrete constructors
-Poller::Poller() :
- impl(new PollerPrivate())
-{}
-
-Poller::~Poller() {
- delete impl;
-}
-
-}}
diff --git a/cpp/src/qpid/sys/windows/LockFile.cpp b/cpp/src/qpid/sys/windows/LockFile.cpp
deleted file mode 100755
index 048c2d5b18..0000000000
--- a/cpp/src/qpid/sys/windows/LockFile.cpp
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- *
- * Copyright (c) 2008 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/sys/LockFile.h"
-#include "qpid/sys/windows/check.h"
-
-#include <windows.h>
-
-namespace qpid {
-namespace sys {
-
-class LockFilePrivate {
- friend class LockFile;
-
- HANDLE fd;
-
-public:
- LockFilePrivate(HANDLE f) : fd(f) {}
-};
-
-LockFile::LockFile(const std::string& path_, bool create)
- : path(path_), created(create) {
-
- HANDLE h = ::CreateFile(path.c_str(),
- create ? (GENERIC_READ|GENERIC_WRITE) : GENERIC_READ,
- FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
- 0, /* Default security */
- create ? OPEN_ALWAYS : OPEN_EXISTING,
- FILE_FLAG_DELETE_ON_CLOSE, /* Delete file when closed */
- NULL);
- if (h == INVALID_HANDLE_VALUE)
- throw qpid::Exception(path + ": " + qpid::sys::strError(GetLastError()));
-
- // Lock up to 4Gb
- if (!::LockFile(h, 0, 0, 0xffffffff, 0))
- throw qpid::Exception(path + ": " + qpid::sys::strError(GetLastError()));
- impl.reset(new LockFilePrivate(h));
-}
-
-LockFile::~LockFile() {
- if (impl) {
- if (impl->fd != INVALID_HANDLE_VALUE) {
- ::UnlockFile(impl->fd, 0, 0, 0xffffffff, 0);
- ::CloseHandle(impl->fd);
- }
- }
-}
-
-}} /* namespace qpid::sys */
diff --git a/cpp/src/qpid/sys/windows/PipeHandle.cpp b/cpp/src/qpid/sys/windows/PipeHandle.cpp
deleted file mode 100755
index 062458ae5f..0000000000
--- a/cpp/src/qpid/sys/windows/PipeHandle.cpp
+++ /dev/null
@@ -1,101 +0,0 @@
-//
-// 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/sys/PipeHandle.h"
-#include "qpid/sys/windows/check.h"
-#include <winsock2.h>
-
-namespace qpid {
-namespace sys {
-
-PipeHandle::PipeHandle(bool nonBlocking) {
-
- SOCKET listener, pair[2];
- struct sockaddr_in addr;
- int err;
- int addrlen = sizeof(addr);
- pair[0] = pair[1] = INVALID_SOCKET;
- if ((listener = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
- throw QPID_WINDOWS_ERROR(WSAGetLastError());
-
- memset(&addr, 0, sizeof(addr));
- addr.sin_family = AF_INET;
- addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
- addr.sin_port = 0;
-
- err = bind(listener, (const struct sockaddr*) &addr, sizeof(addr));
- if (err == SOCKET_ERROR) {
- err = WSAGetLastError();
- closesocket(listener);
- throw QPID_WINDOWS_ERROR(err);
- }
-
- err = getsockname(listener, (struct sockaddr*) &addr, &addrlen);
- if (err == SOCKET_ERROR) {
- err = WSAGetLastError();
- closesocket(listener);
- throw QPID_WINDOWS_ERROR(err);
- }
-
- try {
- if (listen(listener, 1) == SOCKET_ERROR)
- throw QPID_WINDOWS_ERROR(WSAGetLastError());
- if ((pair[0] = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
- throw QPID_WINDOWS_ERROR(WSAGetLastError());
- if (connect(pair[0], (const struct sockaddr*)&addr, sizeof(addr)) == SOCKET_ERROR)
- throw QPID_WINDOWS_ERROR(WSAGetLastError());
- if ((pair[1] = accept(listener, NULL, NULL)) == INVALID_SOCKET)
- throw QPID_WINDOWS_ERROR(WSAGetLastError());
-
- closesocket(listener);
- writeFd = pair[0];
- readFd = pair[1];
- }
- catch (...) {
- closesocket(listener);
- if (pair[0] != INVALID_SOCKET)
- closesocket(pair[0]);
- throw;
- }
-
- // Set the socket to non-blocking
- if (nonBlocking) {
- unsigned long nonblock = 1;
- ioctlsocket(readFd, FIONBIO, &nonblock);
- }
-}
-
-PipeHandle::~PipeHandle() {
- closesocket(readFd);
- closesocket(writeFd);
-}
-
-int PipeHandle::read(void* buf, size_t bufSize) {
- return ::recv(readFd, (char *)buf, bufSize, 0);
-}
-
-int PipeHandle::write(const void* buf, size_t bufSize) {
- return ::send(writeFd, (const char *)buf, bufSize, 0);
-}
-
-int PipeHandle::getReadHandle() {
- return readFd;
-}
-
-}} // namespace qpid::sys
diff --git a/cpp/src/qpid/sys/windows/PollableCondition.cpp b/cpp/src/qpid/sys/windows/PollableCondition.cpp
deleted file mode 100644
index 6a1d9045b4..0000000000
--- a/cpp/src/qpid/sys/windows/PollableCondition.cpp
+++ /dev/null
@@ -1,114 +0,0 @@
-#ifndef QPID_SYS_WINDOWS_POLLABLECONDITION_CPP
-#define QPID_SYS_WINDOWS_POLLABLECONDITION_CPP
-
-/*
- *
- * 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/sys/PollableCondition.h"
-#include "qpid/sys/IOHandle.h"
-#include "qpid/sys/windows/AsynchIoResult.h"
-#include "qpid/sys/windows/IoHandlePrivate.h"
-
-#include <boost/bind.hpp>
-#include <windows.h>
-
-namespace qpid {
-namespace sys {
-
-// PollableConditionPrivate will reuse the IocpPoller's ability to queue
-// a completion to the IOCP and have it dispatched to the completer callback
-// noted in the IOHandlePrivate when the request is queued. The
-// AsynchCallbackRequest object is not really used - we already have the
-// desired callback for the user of PollableCondition.
-class PollableConditionPrivate : private IOHandle {
- friend class PollableCondition;
-
-private:
- PollableConditionPrivate(const sys::PollableCondition::Callback& cb,
- sys::PollableCondition& parent,
- const boost::shared_ptr<sys::Poller>& poller);
- ~PollableConditionPrivate();
-
- void poke();
- void dispatch(windows::AsynchIoResult *result);
-
-private:
- PollableCondition::Callback cb;
- PollableCondition& parent;
- boost::shared_ptr<sys::Poller> poller;
- LONG isSet;
-};
-
-PollableConditionPrivate::PollableConditionPrivate(const sys::PollableCondition::Callback& cb,
- sys::PollableCondition& parent,
- const boost::shared_ptr<sys::Poller>& poller)
- : IOHandle(new sys::IOHandlePrivate(INVALID_SOCKET,
- boost::bind(&PollableConditionPrivate::dispatch, this, _1))),
- cb(cb), parent(parent), poller(poller), isSet(0)
-{
-}
-
-PollableConditionPrivate::~PollableConditionPrivate()
-{
-}
-
-void PollableConditionPrivate::poke()
-{
- // monitorHandle will queue a completion for the IOCP; when it's handled, a
- // poller thread will call back to dispatch() below.
- PollerHandle ph(*this);
- poller->monitorHandle(ph, Poller::INPUT);
-}
-
-void PollableConditionPrivate::dispatch(windows::AsynchIoResult *result)
-{
- delete result; // Poller::monitorHandle() allocates this
- cb(parent);
- if (isSet)
- poke();
-}
-
- /* PollableCondition */
-
-PollableCondition::PollableCondition(const Callback& cb,
- const boost::shared_ptr<sys::Poller>& poller)
- : impl(new PollableConditionPrivate(cb, *this, poller))
-{
-}
-
-PollableCondition::~PollableCondition()
-{
- delete impl;
-}
-
-void PollableCondition::set() {
- // Add one to the set count and poke it to provoke a callback
- ::InterlockedIncrement(&impl->isSet);
- impl->poke();
-}
-
-void PollableCondition::clear() {
- ::InterlockedExchange(&impl->isSet, 0);
-}
-
-}} // namespace qpid::sys
-
-#endif /*!QPID_SYS_WINDOWS_POLLABLECONDITION_CPP*/
diff --git a/cpp/src/qpid/sys/windows/Shlib.cpp b/cpp/src/qpid/sys/windows/Shlib.cpp
deleted file mode 100644
index ba18747eb4..0000000000
--- a/cpp/src/qpid/sys/windows/Shlib.cpp
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * 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/sys/Shlib.h"
-#include "qpid/Exception.h"
-#include "qpid/sys/windows/check.h"
-#include <windows.h>
-
-namespace qpid {
-namespace sys {
-
-void Shlib::load(const char* name) {
- HMODULE h = LoadLibrary(name);
- if (h == NULL) {
- throw QPID_WINDOWS_ERROR(GetLastError());
- }
- handle = static_cast<void*>(h);
-}
-
-void Shlib::unload() {
- if (handle) {
- if (FreeLibrary(static_cast<HMODULE>(handle)) == 0) {
- throw QPID_WINDOWS_ERROR(GetLastError());
- }
- handle = 0;
- }
-}
-
-void* Shlib::getSymbol(const char* name) {
- // Double cast avoids warning about casting function pointer to object
- void *sym = reinterpret_cast<void*>(reinterpret_cast<intptr_t>(GetProcAddress(static_cast<HMODULE>(handle), name)));
- if (sym == NULL)
- throw QPID_WINDOWS_ERROR(GetLastError());
- return sym;
-}
-
-}} // namespace qpid::sys
diff --git a/cpp/src/qpid/sys/windows/Socket.cpp b/cpp/src/qpid/sys/windows/Socket.cpp
deleted file mode 100755
index 2ce274acc9..0000000000
--- a/cpp/src/qpid/sys/windows/Socket.cpp
+++ /dev/null
@@ -1,348 +0,0 @@
-/*
- *
- * 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.
- *
- */
-
-// Ensure we get all of winsock2.h
-#ifndef _WIN32_WINNT
-#define _WIN32_WINNT 0x0501
-#endif
-
-#include "qpid/sys/Socket.h"
-#include "qpid/sys/SocketAddress.h"
-#include "qpid/sys/windows/IoHandlePrivate.h"
-#include "qpid/sys/windows/check.h"
-#include "qpid/sys/Time.h"
-
-#include <cstdlib>
-#include <string.h>
-
-#include <winsock2.h>
-
-#include <boost/format.hpp>
-#include <boost/lexical_cast.hpp>
-
-// Need to initialize WinSock. Ideally, this would be a singleton or embedded
-// in some one-time initialization function. I tried boost singleton and could
-// not get it to compile (and others located in google had the same problem).
-// So, this simple static with an interlocked increment will do for known
-// use cases at this time. Since this will only shut down winsock at process
-// termination, there may be some problems with client programs that also
-// expect to load and unload winsock, but we'll see...
-// If someone does get an easy-to-use singleton sometime, converting to it
-// may be preferable.
-
-namespace {
-
-static LONG volatile initialized = 0;
-
-class WinSockSetup {
- // : public boost::details::pool::singleton_default<WinSockSetup> {
-
-public:
- WinSockSetup() {
- LONG timesEntered = InterlockedIncrement(&initialized);
- if (timesEntered > 1)
- return;
- err = 0;
- WORD wVersionRequested;
- WSADATA wsaData;
-
- /* Request WinSock 2.2 */
- wVersionRequested = MAKEWORD(2, 2);
- err = WSAStartup(wVersionRequested, &wsaData);
- }
-
- ~WinSockSetup() {
- WSACleanup();
- }
-
-public:
- int error(void) const { return err; }
-
-protected:
- DWORD err;
-};
-
-static WinSockSetup setup;
-
-} /* namespace */
-
-namespace qpid {
-namespace sys {
-
-namespace {
-
-std::string getName(SOCKET fd, bool local, bool includeService = false)
-{
- sockaddr_in name; // big enough for any socket address
- socklen_t namelen = sizeof(name);
- if (local) {
- QPID_WINSOCK_CHECK(::getsockname(fd, (sockaddr*)&name, &namelen));
- } else {
- QPID_WINSOCK_CHECK(::getpeername(fd, (sockaddr*)&name, &namelen));
- }
-
- char servName[NI_MAXSERV];
- char dispName[NI_MAXHOST];
- if (includeService) {
- if (int rc = ::getnameinfo((sockaddr*)&name, namelen,
- dispName, sizeof(dispName),
- servName, sizeof(servName),
- NI_NUMERICHOST | NI_NUMERICSERV) != 0)
- throw qpid::Exception(QPID_MSG(gai_strerror(rc)));
- return std::string(dispName) + ":" + std::string(servName);
- } else {
- if (int rc = ::getnameinfo((sockaddr*)&name, namelen,
- dispName, sizeof(dispName),
- 0, 0,
- NI_NUMERICHOST) != 0)
- throw qpid::Exception(QPID_MSG(gai_strerror(rc)));
- return dispName;
- }
-}
-
-std::string getService(SOCKET fd, bool local)
-{
- sockaddr_in name; // big enough for any socket address
- socklen_t namelen = sizeof(name);
-
- if (local) {
- QPID_WINSOCK_CHECK(::getsockname(fd, (sockaddr*)&name, &namelen));
- } else {
- QPID_WINSOCK_CHECK(::getpeername(fd, (sockaddr*)&name, &namelen));
- }
-
- char servName[NI_MAXSERV];
- if (int rc = ::getnameinfo((sockaddr*)&name, namelen,
- 0, 0,
- servName, sizeof(servName),
- NI_NUMERICHOST | NI_NUMERICSERV) != 0)
- throw qpid::Exception(QPID_MSG(gai_strerror(rc)));
- return servName;
-}
-} // namespace
-
-Socket::Socket() :
- IOHandle(new IOHandlePrivate),
- nonblocking(false),
- nodelay(false)
-{
- SOCKET& socket = impl->fd;
- if (socket != INVALID_SOCKET) Socket::close();
- SOCKET s = ::socket (PF_INET, SOCK_STREAM, 0);
- if (s == INVALID_SOCKET) throw QPID_WINDOWS_ERROR(WSAGetLastError());
- socket = s;
-}
-
-Socket::Socket(IOHandlePrivate* h) :
- IOHandle(h),
- nonblocking(false),
- nodelay(false)
-{}
-
-void
-Socket::createSocket(const SocketAddress& sa) const
-{
- SOCKET& socket = impl->fd;
- if (socket != INVALID_SOCKET) Socket::close();
-
- SOCKET s = ::socket (getAddrInfo(sa).ai_family,
- getAddrInfo(sa).ai_socktype,
- 0);
- if (s == INVALID_SOCKET) throw QPID_WINDOWS_ERROR(WSAGetLastError());
- socket = s;
-
- try {
- if (nonblocking) setNonblocking();
- if (nodelay) setTcpNoDelay();
- } catch (std::exception&) {
- closesocket(s);
- socket = INVALID_SOCKET;
- throw;
- }
-}
-
-void Socket::setTimeout(const Duration& interval) const
-{
- const SOCKET& socket = impl->fd;
- int64_t nanosecs = interval;
- nanosecs /= (1000 * 1000); // nsecs -> usec -> msec
- int msec = 0;
- if (nanosecs > std::numeric_limits<int>::max())
- msec = std::numeric_limits<int>::max();
- else
- msec = static_cast<int>(nanosecs);
- setsockopt(socket, SOL_SOCKET, SO_SNDTIMEO, (char *)&msec, sizeof(msec));
- setsockopt(socket, SOL_SOCKET, SO_RCVTIMEO, (char *)&msec, sizeof(msec));
-}
-
-void Socket::setNonblocking() const {
- u_long nonblock = 1;
- QPID_WINSOCK_CHECK(ioctlsocket(impl->fd, FIONBIO, &nonblock));
-}
-
-void Socket::connect(const std::string& host, uint16_t port) const
-{
- SocketAddress sa(host, boost::lexical_cast<std::string>(port));
- connect(sa);
-}
-
-void
-Socket::connect(const SocketAddress& addr) const
-{
- const SOCKET& socket = impl->fd;
- const addrinfo *addrs = &(getAddrInfo(addr));
- int error = 0;
- WSASetLastError(0);
- while (addrs != 0) {
- if ((::connect(socket, addrs->ai_addr, addrs->ai_addrlen) == 0) ||
- (WSAGetLastError() == WSAEWOULDBLOCK))
- break;
- // Error... save this error code and see if there are other address
- // to try before throwing the exception.
- error = WSAGetLastError();
- addrs = addrs->ai_next;
- }
- if (error)
- throw qpid::Exception(QPID_MSG(strError(error) << ": " << connectname));
-}
-
-void
-Socket::close() const
-{
- SOCKET& socket = impl->fd;
- if (socket == INVALID_SOCKET) return;
- QPID_WINSOCK_CHECK(closesocket(socket));
- socket = INVALID_SOCKET;
-}
-
-
-int Socket::write(const void *buf, size_t count) const
-{
- const SOCKET& socket = impl->fd;
- int sent = ::send(socket, (const char *)buf, count, 0);
- if (sent == SOCKET_ERROR)
- return -1;
- return sent;
-}
-
-int Socket::read(void *buf, size_t count) const
-{
- const SOCKET& socket = impl->fd;
- int received = ::recv(socket, (char *)buf, count, 0);
- if (received == SOCKET_ERROR)
- return -1;
- return received;
-}
-
-int Socket::listen(uint16_t port, int backlog) const
-{
- const SOCKET& socket = impl->fd;
- BOOL yes=1;
- QPID_WINSOCK_CHECK(setsockopt(socket, SOL_SOCKET, SO_REUSEADDR, (char *)&yes, sizeof(yes)));
- struct sockaddr_in name;
- memset(&name, 0, sizeof(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)) == SOCKET_ERROR)
- throw Exception(QPID_MSG("Can't bind to port " << port << ": " << strError(WSAGetLastError())));
- if (::listen(socket, backlog) == SOCKET_ERROR)
- throw Exception(QPID_MSG("Can't listen on port " << port << ": " << strError(WSAGetLastError())));
-
- socklen_t namelen = sizeof(name);
- QPID_WINSOCK_CHECK(::getsockname(socket, (struct sockaddr*)&name, &namelen));
- return ntohs(name.sin_port);
-}
-
-Socket* Socket::accept() const
-{
- SOCKET afd = ::accept(impl->fd, 0, 0);
- if (afd != INVALID_SOCKET)
- return new Socket(new IOHandlePrivate(afd));
- else if (WSAGetLastError() == EAGAIN)
- return 0;
- else throw QPID_WINDOWS_ERROR(WSAGetLastError());
-}
-
-std::string Socket::getSockname() const
-{
- return getName(impl->fd, true);
-}
-
-std::string Socket::getPeername() const
-{
- return getName(impl->fd, false);
-}
-
-std::string Socket::getPeerAddress() const
-{
- if (!connectname.empty())
- return std::string (connectname);
- return getName(impl->fd, false, true);
-}
-
-std::string Socket::getLocalAddress() const
-{
- return getName(impl->fd, true, true);
-}
-
-uint16_t Socket::getLocalPort() const
-{
- return atoi(getService(impl->fd, true).c_str());
-}
-
-uint16_t Socket::getRemotePort() const
-{
- return atoi(getService(impl->fd, true).c_str());
-}
-
-int Socket::getError() const
-{
- int result;
- socklen_t rSize = sizeof (result);
-
- QPID_WINSOCK_CHECK(::getsockopt(impl->fd, SOL_SOCKET, SO_ERROR, (char *)&result, &rSize));
- return result;
-}
-
-void Socket::setTcpNoDelay() const
-{
- int flag = 1;
- int result = setsockopt(impl->fd,
- IPPROTO_TCP,
- TCP_NODELAY,
- (char *)&flag,
- sizeof(flag));
- QPID_WINSOCK_CHECK(result);
- nodelay = true;
-}
-
-inline IOHandlePrivate* IOHandlePrivate::getImpl(const qpid::sys::IOHandle &h)
-{
- return h.impl;
-}
-
-SOCKET toSocketHandle(const Socket& s)
-{
- return IOHandlePrivate::getImpl(s)->fd;
-}
-
-}} // namespace qpid::sys
diff --git a/cpp/src/qpid/sys/windows/SocketAddress.cpp b/cpp/src/qpid/sys/windows/SocketAddress.cpp
deleted file mode 100644
index 5efdad0183..0000000000
--- a/cpp/src/qpid/sys/windows/SocketAddress.cpp
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- *
- * 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.
- *
- */
-
-// Ensure we get all of winsock2.h
-#ifndef _WIN32_WINNT
-#define _WIN32_WINNT 0x0501
-#endif
-
-#include "qpid/sys/SocketAddress.h"
-
-#include "qpid/sys/windows/check.h"
-
-#include <winsock2.h>
-#include <ws2tcpip.h>
-#include <string.h>
-
-namespace qpid {
-namespace sys {
-
-SocketAddress::SocketAddress(const std::string& host0, const std::string& port0) :
- host(host0),
- port(port0),
- addrInfo(0)
-{
- ::addrinfo hints;
- ::memset(&hints, 0, sizeof(hints));
- hints.ai_family = AF_INET; // In order to allow AF_INET6 we'd have to change createTcp() as well
- hints.ai_socktype = SOCK_STREAM;
-
- const char* node = 0;
- if (host.empty()) {
- hints.ai_flags |= AI_PASSIVE;
- } else {
- node = host.c_str();
- }
- const char* service = port.empty() ? "0" : port.c_str();
-
- int n = ::getaddrinfo(node, service, &hints, &addrInfo);
- if (n != 0)
- throw Exception(QPID_MSG("Cannot resolve " << host << ": " << ::gai_strerror(n)));
-}
-
-SocketAddress::~SocketAddress()
-{
- ::freeaddrinfo(addrInfo);
-}
-
-std::string SocketAddress::asString() const
-{
- return host + ":" + port;
-}
-
-const ::addrinfo& getAddrInfo(const SocketAddress& sa)
-{
- return *sa.addrInfo;
-}
-
-}}
diff --git a/cpp/src/qpid/sys/windows/SslAsynchIO.cpp b/cpp/src/qpid/sys/windows/SslAsynchIO.cpp
deleted file mode 100644
index 11a3389e45..0000000000
--- a/cpp/src/qpid/sys/windows/SslAsynchIO.cpp
+++ /dev/null
@@ -1,661 +0,0 @@
-/*
- *
- * 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 "SslAsynchIO.h"
-#include "qpid/sys/Mutex.h"
-#include "qpid/sys/Socket.h"
-#include "qpid/sys/Poller.h"
-#include "qpid/sys/Thread.h"
-#include "qpid/sys/Time.h"
-#include "qpid/log/Statement.h"
-
-#include "qpid/sys/windows/check.h"
-
-// security.h needs to see this to distinguish from kernel use.
-#define SECURITY_WIN32
-#include <security.h>
-#include <Schnlsp.h>
-#undef SECURITY_WIN32
-
-#include <queue>
-#include <boost/bind.hpp>
-
-namespace {
-
- /*
- * To make the SSL encryption more efficient, set up a new BufferBase
- * that leaves room for the SSL header to be prepended and the SSL
- * trailer to be appended.
- *
- * This works by accepting a properly formed BufferBase, remembering it,
- * and resetting the members of this struct to reflect the reserved
- * header and trailer areas. It's only needed for giving buffers up to
- * the frame layer for writing into.
- */
- struct SslIoBuff : public qpid::sys::AsynchIO::BufferBase {
- std::auto_ptr<qpid::sys::AsynchIO::BufferBase> aioBuff;
-
- SslIoBuff (qpid::sys::AsynchIO::BufferBase *base,
- const SecPkgContext_StreamSizes &sizes)
- : qpid::sys::AsynchIO::BufferBase(&base->bytes[sizes.cbHeader],
- std::min(base->byteCount - sizes.cbHeader - sizes.cbTrailer,
- sizes.cbMaximumMessage)),
- aioBuff(base)
- {}
-
- ~SslIoBuff() {}
- qpid::sys::AsynchIO::BufferBase* release() { return aioBuff.release(); }
- };
-}
-
-namespace qpid {
-namespace sys {
-namespace windows {
-
-SslAsynchIO::SslAsynchIO(const qpid::sys::Socket& s,
- CredHandle hCred,
- ReadCallback rCb,
- EofCallback eofCb,
- DisconnectCallback disCb,
- ClosedCallback cCb,
- BuffersEmptyCallback eCb,
- IdleCallback iCb,
- NegotiateDoneCallback nCb) :
- credHandle(hCred),
- aio(0),
- state(Negotiating),
- readCallback(rCb),
- idleCallback(iCb),
- negotiateDoneCallback(nCb),
- callbacksInProgress(0),
- queuedDelete(false),
- leftoverPlaintext(0)
-{
- SecInvalidateHandle(&ctxtHandle);
- peerAddress = s.getPeerAddress();
- aio = qpid::sys::AsynchIO::create(s,
- boost::bind(&SslAsynchIO::sslDataIn, this, _1, _2),
- eofCb,
- disCb,
- cCb,
- eCb,
- boost::bind(&SslAsynchIO::idle, this, _1));
-}
-
-SslAsynchIO::~SslAsynchIO() {
- if (leftoverPlaintext) {
- delete leftoverPlaintext;
- leftoverPlaintext = 0;
- }
-}
-
-void SslAsynchIO::queueForDeletion() {
- // This method effectively disconnects the layer above; pass it on the
- // AsynchIO and delete.
- aio->queueForDeletion();
- queuedDelete = true;
- if (!callbacksInProgress)
- delete this;
-}
-
-void SslAsynchIO::start(qpid::sys::Poller::shared_ptr poller) {
- aio->start(poller);
- startNegotiate();
-}
-
-void SslAsynchIO::queueReadBuffer(AsynchIO::BufferBase* buff) {
- aio->queueReadBuffer(buff);
-}
-
-void SslAsynchIO::unread(AsynchIO::BufferBase* buff) {
- // This is plaintext data being given back for more. Since it's already
- // decrypted, don't give it back to the aio layer; keep it to append
- // any new data for the upper layer.
- assert(buff);
- buff->squish();
- assert(leftoverPlaintext == 0);
- leftoverPlaintext = buff;
-}
-
-void SslAsynchIO::queueWrite(AsynchIO::BufferBase* buff) {
- // @@TODO: Need to delay the write if the session is renegotiating.
-
- // Should not have gotten here without an SslIoBuff. This assert is
- // primarily to catch any stray cases where write is called with a buffer
- // not obtained via getQueuedBuffer.
- SslIoBuff *sslBuff = dynamic_cast<SslIoBuff*>(buff);
- assert(sslBuff != 0);
-
- // Encrypt and hand off to the io layer. Remember that the upper layer's
- // encoding was working on, and adjusting counts for, the SslIoBuff.
- // Update the count of the original BufferBase before handing off to
- // the I/O layer.
- buff = sslBuff->release();
- SecBuffer buffs[4];
- buffs[0].cbBuffer = schSizes.cbHeader;
- buffs[0].BufferType = SECBUFFER_STREAM_HEADER;
- buffs[0].pvBuffer = buff->bytes; // This space was left by SslIoBuff
- buffs[1].cbBuffer = sslBuff->dataCount;
- buffs[1].BufferType = SECBUFFER_DATA;
- buffs[1].pvBuffer = sslBuff->bytes;
- buffs[2].cbBuffer = schSizes.cbTrailer;
- buffs[2].BufferType = SECBUFFER_STREAM_TRAILER;
- buffs[2].pvBuffer = &sslBuff->bytes[sslBuff->dataCount];
- buffs[3].cbBuffer = 0;
- buffs[3].BufferType = SECBUFFER_EMPTY;
- buffs[3].pvBuffer = 0;
- SecBufferDesc buffDesc;
- buffDesc.ulVersion = SECBUFFER_VERSION;
- buffDesc.cBuffers = 4;
- buffDesc.pBuffers = buffs;
- SECURITY_STATUS status = ::EncryptMessage(&ctxtHandle, 0, &buffDesc, 0);
-
- // EncryptMessage encrypts the data in place. The header and trailer
- // areas were left previously and must now be included in the updated
- // count of bytes to write to the peer.
- delete sslBuff;
- buff->dataCount = buffs[0].cbBuffer + buffs[1].cbBuffer + buffs[2].cbBuffer;
- aio->queueWrite(buff);
-}
-
-void SslAsynchIO::notifyPendingWrite() {
- aio->notifyPendingWrite();
-}
-
-void SslAsynchIO::queueWriteClose() {
- if (state == Negotiating) {
- // Never got going, so don't bother trying to close SSL down orderly.
- state = ShuttingDown;
- aio->queueWriteClose();
- return;
- }
-
- state = ShuttingDown;
-
- DWORD shutdown = SCHANNEL_SHUTDOWN;
- SecBuffer shutBuff;
- shutBuff.cbBuffer = sizeof(DWORD);
- shutBuff.BufferType = SECBUFFER_TOKEN;
- shutBuff.pvBuffer = &shutdown;
- SecBufferDesc desc;
- desc.ulVersion = SECBUFFER_VERSION;
- desc.cBuffers = 1;
- desc.pBuffers = &shutBuff;
- ::ApplyControlToken(&ctxtHandle, &desc);
- negotiateStep(0);
- // When the shutdown sequence is done, negotiateDone() will handle
- // shutting down aio.
-}
-
-bool SslAsynchIO::writeQueueEmpty() {
- return aio->writeQueueEmpty();
-}
-
-/*
- * Initiate a read operation. AsynchIO::readComplete() will be
- * called when the read is complete and data is available.
- */
-void SslAsynchIO::startReading() {
- aio->startReading();
-}
-
-void SslAsynchIO::stopReading() {
- aio->stopReading();
-}
-
-// Queue the specified callback for invocation from an I/O thread.
-void SslAsynchIO::requestCallback(RequestCallback callback) {
- aio->requestCallback(callback);
-}
-
-/**
- * Return a queued buffer read to put new data in for writing.
- * This method ALWAYS returns a SslIoBuff reflecting a BufferBase from
- * the aio layer that has header and trailer space reserved.
- */
-AsynchIO::BufferBase* SslAsynchIO::getQueuedBuffer() {
- SslIoBuff *sslBuff = 0;
- BufferBase* buff = aio->getQueuedBuffer();
- if (buff == 0)
- return 0;
-
- sslBuff = new SslIoBuff(buff, schSizes);
- return sslBuff;
-}
-
-unsigned int SslAsynchIO::getSslKeySize() {
- SecPkgContext_KeyInfo info;
- memset(&info, 0, sizeof(info));
- ::QueryContextAttributes(&ctxtHandle, SECPKG_ATTR_KEY_INFO, &info);
- return info.KeySize;
-}
-
-void SslAsynchIO::negotiationDone() {
- switch(state) {
- case Negotiating:
- ::QueryContextAttributes(&ctxtHandle,
- SECPKG_ATTR_STREAM_SIZES,
- &schSizes);
- state = Running;
- if (negotiateDoneCallback)
- negotiateDoneCallback(SEC_E_OK);
- break;
- case Redo:
- state = Running;
- break;
- case ShuttingDown:
- aio->queueWriteClose();
- break;
- default:
- assert(0);
- }
-}
-
-void SslAsynchIO::negotiationFailed(SECURITY_STATUS status) {
- QPID_LOG(notice, "SSL negotiation failed to " << peerAddress << ": " <<
- qpid::sys::strError(status));
- if (negotiateDoneCallback)
- negotiateDoneCallback(status);
- else
- queueWriteClose();
-}
-
-void SslAsynchIO::sslDataIn(qpid::sys::AsynchIO& a, BufferBase *buff) {
- if (state != Running) {
- negotiateStep(buff);
- return;
- }
-
- // Decrypt the buffer; if there's legit data, pass it on through.
- // However, it's also possible that the peer hasn't supplied enough
- // data yet, or the session needs to be renegotiated, or the session
- // is ending.
- SecBuffer recvBuffs[4];
- recvBuffs[0].cbBuffer = buff->dataCount;
- recvBuffs[0].BufferType = SECBUFFER_DATA;
- recvBuffs[0].pvBuffer = &buff->bytes[buff->dataStart];
- recvBuffs[1].BufferType = SECBUFFER_EMPTY;
- recvBuffs[2].BufferType = SECBUFFER_EMPTY;
- recvBuffs[3].BufferType = SECBUFFER_EMPTY;
- SecBufferDesc buffDesc;
- buffDesc.ulVersion = SECBUFFER_VERSION;
- buffDesc.cBuffers = 4;
- buffDesc.pBuffers = recvBuffs;
- SECURITY_STATUS status = ::DecryptMessage(&ctxtHandle, &buffDesc, 0, NULL);
- if (status != SEC_E_OK) {
- if (status == SEC_E_INCOMPLETE_MESSAGE) {
- // Give the partially filled buffer back and get more data
- a.unread(buff);
- }
- else {
- // Don't need this any more...
- a.queueReadBuffer(buff);
-
- if (status == SEC_I_RENEGOTIATE) {
- state = Redo;
- negotiateStep(0);
- }
- else if (status == SEC_I_CONTEXT_EXPIRED) {
- queueWriteClose();
- }
- else {
- throw QPID_WINDOWS_ERROR(status);
- }
- }
- return;
- }
-
- // All decrypted and verified... continue with AMQP. The recvBuffs have
- // been set up by DecryptMessage to demarcate the SSL header, data, and
- // trailer, as well as any extra data left over. Walk through and find
- // that info, adjusting the buff data accordingly to reflect only the
- // actual decrypted data.
- // If there's extra data, copy that out to a new buffer and run through
- // this method again.
- BufferBase *extraBuff = 0;
- for (int i = 0; i < 4; i++) {
- switch (recvBuffs[i].BufferType) {
- case SECBUFFER_STREAM_HEADER:
- buff->dataStart += recvBuffs[i].cbBuffer;
- // Fall through - also don't count these bytes as data
- case SECBUFFER_STREAM_TRAILER:
- buff->dataCount -= recvBuffs[i].cbBuffer;
- break;
- case SECBUFFER_EXTRA:
- // Very important to get this buffer from the downstream aio.
- // The ones constructed from the local getQueuedBuffer() are
- // restricted size for encrypting. However, data coming up from
- // TCP may have a bunch of SSL segments coalesced and be much
- // larger than the maximum single SSL segment.
- extraBuff = a.getQueuedBuffer();
- if (0 == extraBuff)
- throw QPID_WINDOWS_ERROR(WSAENOBUFS);
- memmove(extraBuff->bytes,
- recvBuffs[i].pvBuffer,
- recvBuffs[i].cbBuffer);
- extraBuff->dataCount = recvBuffs[i].cbBuffer;
- break;
- default:
- break;
- }
- }
-
- // Since we've already taken (possibly) all the available bytes from the
- // aio layer, need to be sure that everything that's processable is
- // processed before returning back to aio. It could be that any
- // leftoverPlaintext data plus new buff data won't fit in one buffer, so
- // need to keep going around the input processing loop until either
- // all the bytes are gone, or there's less than a full frame remaining
- // (so we can count on more bytes being on the way via aio).
- do {
- BufferBase *temp = 0;
- // Now that buff reflects only decrypted data, see if there was any
- // partial data left over from last time. If so, append this new
- // data to that and release the current buff back to aio. Assume that
- // leftoverPlaintext was squished so the data starts at 0.
- if (leftoverPlaintext != 0) {
- // There is leftover data; append all the new data that will fit.
- int32_t count = buff->dataCount;
- if (leftoverPlaintext->dataCount + count > leftoverPlaintext->byteCount)
- count = (leftoverPlaintext->byteCount - leftoverPlaintext->dataCount);
- ::memmove(&leftoverPlaintext->bytes[leftoverPlaintext->dataCount],
- &buff->bytes[buff->dataStart],
- count);
- leftoverPlaintext->dataCount += count;
- buff->dataCount -= count;
- buff->dataStart += count;
- if (buff->dataCount == 0) {
- a.queueReadBuffer(buff);
- buff = 0;
- }
- // Prepare to pass the buffer up. Beware that the read callback
- // may do an unread(), so move the leftoverPlaintext pointer
- // out of the way. It also may release the buffer back to aio,
- // so in either event, the pointer passed to the callback is not
- // valid on return.
- temp = leftoverPlaintext;
- leftoverPlaintext = 0;
- }
- else {
- temp = buff;
- buff = 0;
- }
- if (readCallback) {
- // The callback guard here is to prevent an upcall from deleting
- // this out from under us via queueForDeletion().
- ++callbacksInProgress;
- readCallback(*this, temp);
- --callbacksInProgress;
- }
- else
- a.queueReadBuffer(temp); // What else can we do with this???
- } while (buff != 0);
-
- // Ok, the current decrypted data is done. If there was any extra data,
- // go back and handle that.
- if (extraBuff != 0)
- sslDataIn(a, extraBuff);
-
- // If the upper layer queued for delete, do that now that all the
- // callbacks are done.
- if (queuedDelete && callbacksInProgress == 0)
- delete this;
-}
-
-void SslAsynchIO::idle(qpid::sys::AsynchIO&) {
- // Don't relay idle indication to layer above until SSL session is up.
- if (state == Running) {
- state = Running;
- if (idleCallback)
- idleCallback(*this);
- }
-}
-
- /**************************************************/
-
-ClientSslAsynchIO::ClientSslAsynchIO(const std::string& brokerHost,
- const qpid::sys::Socket& s,
- CredHandle hCred,
- ReadCallback rCb,
- EofCallback eofCb,
- DisconnectCallback disCb,
- ClosedCallback cCb,
- BuffersEmptyCallback eCb,
- IdleCallback iCb,
- NegotiateDoneCallback nCb) :
- SslAsynchIO(s, hCred, rCb, eofCb, disCb, cCb, eCb, iCb, nCb),
- serverHost(brokerHost)
-{
-}
-
-void ClientSslAsynchIO::startNegotiate() {
- // SEC_CHAR is non-const, so do all the typing here.
- SEC_CHAR *host = const_cast<SEC_CHAR *>(serverHost.c_str());
-
- // Need a buffer to receive the token to send to the server.
- BufferBase *buff = aio->getQueuedBuffer();
- ULONG ctxtRequested = ISC_REQ_STREAM;
- ULONG ctxtAttrs;
- // sendBuffs gets information to forward to the peer.
- SecBuffer sendBuffs[2];
- sendBuffs[0].cbBuffer = buff->byteCount;
- sendBuffs[0].BufferType = SECBUFFER_TOKEN;
- sendBuffs[0].pvBuffer = buff->bytes;
- sendBuffs[1].cbBuffer = 0;
- sendBuffs[1].BufferType = SECBUFFER_EMPTY;
- sendBuffs[1].pvBuffer = 0;
- SecBufferDesc sendBuffDesc;
- sendBuffDesc.ulVersion = SECBUFFER_VERSION;
- sendBuffDesc.cBuffers = 2;
- sendBuffDesc.pBuffers = sendBuffs;
- SECURITY_STATUS status = ::InitializeSecurityContext(&credHandle,
- NULL,
- host,
- ctxtRequested,
- 0,
- 0,
- NULL,
- 0,
- &ctxtHandle,
- &sendBuffDesc,
- &ctxtAttrs,
- NULL);
- if (status == SEC_I_CONTINUE_NEEDED) {
- buff->dataCount = sendBuffs[0].cbBuffer;
- aio->queueWrite(buff);
- }
-}
-
-void ClientSslAsynchIO::negotiateStep(BufferBase* buff) {
- // SEC_CHAR is non-const, so do all the typing here.
- SEC_CHAR *host = const_cast<SEC_CHAR *>(serverHost.c_str());
- ULONG ctxtRequested = ISC_REQ_STREAM;
- ULONG ctxtAttrs;
-
- // tokenBuffs describe the buffer that's coming in. It should have
- // a token from the SSL server.
- SecBuffer tokenBuffs[2];
- tokenBuffs[0].cbBuffer = buff ? buff->dataCount : 0;
- tokenBuffs[0].BufferType = SECBUFFER_TOKEN;
- tokenBuffs[0].pvBuffer = buff ? buff->bytes : 0;
- tokenBuffs[1].cbBuffer = 0;
- tokenBuffs[1].BufferType = SECBUFFER_EMPTY;
- tokenBuffs[1].pvBuffer = 0;
- SecBufferDesc tokenBuffDesc;
- tokenBuffDesc.ulVersion = SECBUFFER_VERSION;
- tokenBuffDesc.cBuffers = 2;
- tokenBuffDesc.pBuffers = tokenBuffs;
-
- // Need a buffer to receive any token to send back to the server.
- BufferBase *sendbuff = aio->getQueuedBuffer();
- // sendBuffs gets information to forward to the peer.
- SecBuffer sendBuffs[2];
- sendBuffs[0].cbBuffer = sendbuff->byteCount;
- sendBuffs[0].BufferType = SECBUFFER_TOKEN;
- sendBuffs[0].pvBuffer = sendbuff->bytes;
- sendBuffs[1].cbBuffer = 0;
- sendBuffs[1].BufferType = SECBUFFER_EMPTY;
- sendBuffs[1].pvBuffer = 0;
- SecBufferDesc sendBuffDesc;
- sendBuffDesc.ulVersion = SECBUFFER_VERSION;
- sendBuffDesc.cBuffers = 2;
- sendBuffDesc.pBuffers = sendBuffs;
-
- SECURITY_STATUS status = ::InitializeSecurityContext(&credHandle,
- &ctxtHandle,
- host,
- ctxtRequested,
- 0,
- 0,
- &tokenBuffDesc,
- 0,
- NULL,
- &sendBuffDesc,
- &ctxtAttrs,
- NULL);
-
- if (status == SEC_E_INCOMPLETE_MESSAGE) {
- // Not enough - get more data from the server then try again.
- aio->unread(buff);
- aio->queueReadBuffer(sendbuff); // Don't need this one for now...
- return;
- }
- // Done with the buffer that came in...
- if (buff)
- aio->queueReadBuffer(buff);
- if (status == SEC_I_CONTINUE_NEEDED) {
- sendbuff->dataCount = sendBuffs[0].cbBuffer;
- aio->queueWrite(sendbuff);
- return;
- }
- // Nothing to send back to the server...
- aio->queueReadBuffer(sendbuff);
- // SEC_I_CONTEXT_EXPIRED means session stop complete; SEC_E_OK can be
- // either session stop or negotiation done (session up).
- if (status == SEC_E_OK || status == SEC_I_CONTEXT_EXPIRED)
- negotiationDone();
- else
- negotiationFailed(status);
-}
-
-/*************************************************/
-
-ServerSslAsynchIO::ServerSslAsynchIO(bool clientMustAuthenticate,
- const qpid::sys::Socket& s,
- CredHandle hCred,
- ReadCallback rCb,
- EofCallback eofCb,
- DisconnectCallback disCb,
- ClosedCallback cCb,
- BuffersEmptyCallback eCb,
- IdleCallback iCb,
- NegotiateDoneCallback nCb) :
- SslAsynchIO(s, hCred, rCb, eofCb, disCb, cCb, eCb, iCb, nCb),
- clientAuth(clientMustAuthenticate)
-{
-}
-
-void ServerSslAsynchIO::startNegotiate() {
- // Nothing... need the client to send a token first.
-}
-
-void ServerSslAsynchIO::negotiateStep(BufferBase* buff) {
- ULONG ctxtRequested = ASC_REQ_STREAM;
- if (clientAuth)
- ctxtRequested |= ASC_REQ_MUTUAL_AUTH;
- ULONG ctxtAttrs;
-
- // tokenBuffs describe the buffer that's coming in. It should have
- // a token from the SSL server except if shutting down or renegotiating.
- SecBuffer tokenBuffs[2];
- tokenBuffs[0].cbBuffer = buff ? buff->dataCount : 0;
- tokenBuffs[0].BufferType = SECBUFFER_TOKEN;
- tokenBuffs[0].pvBuffer = buff ? buff->bytes : 0;
- tokenBuffs[1].cbBuffer = 0;
- tokenBuffs[1].BufferType = SECBUFFER_EMPTY;
- tokenBuffs[1].pvBuffer = 0;
- SecBufferDesc tokenBuffDesc;
- tokenBuffDesc.ulVersion = SECBUFFER_VERSION;
- tokenBuffDesc.cBuffers = 2;
- tokenBuffDesc.pBuffers = tokenBuffs;
-
- // Need a buffer to receive any token to send back to the server.
- BufferBase *sendbuff = aio->getQueuedBuffer();
- // sendBuffs gets information to forward to the peer.
- SecBuffer sendBuffs[2];
- sendBuffs[0].cbBuffer = sendbuff->byteCount;
- sendBuffs[0].BufferType = SECBUFFER_TOKEN;
- sendBuffs[0].pvBuffer = sendbuff->bytes;
- sendBuffs[1].cbBuffer = 0;
- sendBuffs[1].BufferType = SECBUFFER_EMPTY;
- sendBuffs[1].pvBuffer = 0;
- SecBufferDesc sendBuffDesc;
- sendBuffDesc.ulVersion = SECBUFFER_VERSION;
- sendBuffDesc.cBuffers = 2;
- sendBuffDesc.pBuffers = sendBuffs;
- PCtxtHandle ctxtHandlePtr = (SecIsValidHandle(&ctxtHandle)) ? &ctxtHandle : 0;
- SECURITY_STATUS status = ::AcceptSecurityContext(&credHandle,
- ctxtHandlePtr,
- &tokenBuffDesc,
- ctxtRequested,
- 0,
- &ctxtHandle,
- &sendBuffDesc,
- &ctxtAttrs,
- NULL);
- if (status == SEC_E_INCOMPLETE_MESSAGE) {
- // Not enough - get more data from the server then try again.
- if (buff)
- aio->unread(buff);
- aio->queueReadBuffer(sendbuff); // Don't need this one for now...
- return;
- }
- // Done with the buffer that came in...
- if (buff)
- aio->queueReadBuffer(buff);
- if (status == SEC_I_CONTINUE_NEEDED) {
- sendbuff->dataCount = sendBuffs[0].cbBuffer;
- aio->queueWrite(sendbuff);
- return;
- }
- // There may have been a token generated; if so, send it to the client.
- if (sendBuffs[0].cbBuffer > 0) {
- sendbuff->dataCount = sendBuffs[0].cbBuffer;
- aio->queueWrite(sendbuff);
- }
- else
- // Nothing to send back to the server...
- aio->queueReadBuffer(sendbuff);
-
- // SEC_I_CONTEXT_EXPIRED means session stop complete; SEC_E_OK can be
- // either session stop or negotiation done (session up).
- if (status == SEC_E_OK || status == SEC_I_CONTEXT_EXPIRED) {
- if (clientAuth)
- QPID_LOG(warning, "DID WE CHECK FOR CLIENT AUTH???");
-
- negotiationDone();
- }
- else {
- negotiationFailed(status);
- }
-}
-
-}}} // namespace qpid::sys::windows
diff --git a/cpp/src/qpid/sys/windows/SslAsynchIO.h b/cpp/src/qpid/sys/windows/SslAsynchIO.h
deleted file mode 100644
index 3cdf2c8f08..0000000000
--- a/cpp/src/qpid/sys/windows/SslAsynchIO.h
+++ /dev/null
@@ -1,191 +0,0 @@
-#ifndef _sys_windows_SslAsynchIO
-#define _sys_windows_SslAsynchIO
-
-/*
- *
- * 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/sys/AsynchIO.h"
-#include "qpid/sys/IntegerTypes.h"
-#include "qpid/sys/Poller.h"
-#include "qpid/CommonImportExport.h"
-#include <boost/function.hpp>
-#include <boost/shared_ptr.hpp>
-#include <windows.h>
-// security.h needs to see this to distinguish from kernel use.
-#define SECURITY_WIN32
-#include <security.h>
-#include <Schnlsp.h>
-#undef SECURITY_WIN32
-
-namespace qpid {
-namespace sys {
-namespace windows {
-
-class Socket;
-class Poller;
-
-/*
- * SSL/Schannel shim between the frame-handling and AsynchIO layers.
- * SslAsynchIO creates a regular AsynchIO object to handle I/O and this class
- * gets involved for SSL negotiations and encrypt/decrypt. The details of
- * how this all works are invisible to the layers on either side. The only
- * change from normal AsynchIO usage is that there's an extra callback
- * from SslAsynchIO to indicate that the initial session negotiation is
- * complete.
- *
- * The details of session negotiation are different for client and server
- * SSL roles. These differences are handled by deriving separate client
- * and server role classes.
- */
-class SslAsynchIO : public qpid::sys::AsynchIO {
-public:
- typedef boost::function1<void, SECURITY_STATUS> NegotiateDoneCallback;
-
- SslAsynchIO(const qpid::sys::Socket& s,
- CredHandle hCred,
- ReadCallback rCb,
- EofCallback eofCb,
- DisconnectCallback disCb,
- ClosedCallback cCb = 0,
- BuffersEmptyCallback eCb = 0,
- IdleCallback iCb = 0,
- NegotiateDoneCallback nCb = 0);
- ~SslAsynchIO();
-
- virtual void queueForDeletion();
-
- virtual void start(qpid::sys::Poller::shared_ptr poller);
- virtual void queueReadBuffer(BufferBase* buff);
- virtual void unread(BufferBase* buff);
- virtual void queueWrite(BufferBase* buff);
- virtual void notifyPendingWrite();
- virtual void queueWriteClose();
- virtual bool writeQueueEmpty();
- virtual void startReading();
- virtual void stopReading();
- virtual void requestCallback(RequestCallback);
- virtual BufferBase* getQueuedBuffer();
-
- QPID_COMMON_EXTERN unsigned int getSslKeySize();
-
-protected:
- CredHandle credHandle;
-
- // AsynchIO layer below that's actually doing the I/O
- qpid::sys::AsynchIO *aio;
-
- // Track what the state of the SSL session is. Have to know when it's
- // time to notify the upper layer that the session is up, and also to
- // know when it's not legit to pass data through to either side.
- enum { Negotiating, Running, Redo, ShuttingDown } state;
- bool sessionUp;
- CtxtHandle ctxtHandle;
- TimeStamp credExpiry;
-
- // Client- and server-side SSL subclasses implement these to do the
- // proper negotiation steps. negotiateStep() is called with a buffer
- // just received from the peer.
- virtual void startNegotiate() = 0;
- virtual void negotiateStep(BufferBase *buff) = 0;
-
- // The negotiating steps call one of these when it's finalized:
- void negotiationDone();
- void negotiationFailed(SECURITY_STATUS status);
-
-private:
- // These are callbacks from AsynchIO to here.
- void sslDataIn(qpid::sys::AsynchIO& a, BufferBase *buff);
- void idle(qpid::sys::AsynchIO&);
-
- // These callbacks are to the layer above.
- ReadCallback readCallback;
- IdleCallback idleCallback;
- NegotiateDoneCallback negotiateDoneCallback;
- volatile unsigned int callbacksInProgress; // >0 if w/in callbacks
- volatile bool queuedDelete;
-
- // Address of peer, in case it's needed for logging.
- std::string peerAddress;
-
- // Partial buffer of decrypted plaintext given back by the layer above.
- AsynchIO::BufferBase *leftoverPlaintext;
-
- SecPkgContext_StreamSizes schSizes;
-};
-
-/*
- * SSL/Schannel client-side shim between the frame-handling and AsynchIO
- * layers.
- */
-class ClientSslAsynchIO : public SslAsynchIO {
-public:
- // Args same as for SslIoShim, with the addition of brokerHost which is
- // the expected SSL name of the server.
- QPID_COMMON_EXTERN ClientSslAsynchIO(const std::string& brokerHost,
- const qpid::sys::Socket& s,
- CredHandle hCred,
- ReadCallback rCb,
- EofCallback eofCb,
- DisconnectCallback disCb,
- ClosedCallback cCb = 0,
- BuffersEmptyCallback eCb = 0,
- IdleCallback iCb = 0,
- NegotiateDoneCallback nCb = 0);
-
-private:
- std::string serverHost;
-
- // Client- and server-side SSL subclasses implement these to do the
- // proper negotiation steps. negotiateStep() is called with a buffer
- // just received from the peer.
- void startNegotiate();
- void negotiateStep(BufferBase *buff);
-};
-/*
- * SSL/Schannel server-side shim between the frame-handling and AsynchIO
- * layers.
- */
-class ServerSslAsynchIO : public SslAsynchIO {
-public:
- QPID_COMMON_EXTERN ServerSslAsynchIO(bool clientMustAuthenticate,
- const qpid::sys::Socket& s,
- CredHandle hCred,
- ReadCallback rCb,
- EofCallback eofCb,
- DisconnectCallback disCb,
- ClosedCallback cCb = 0,
- BuffersEmptyCallback eCb = 0,
- IdleCallback iCb = 0,
- NegotiateDoneCallback nCb = 0);
-
-private:
- bool clientAuth;
-
- // Client- and server-side SSL subclasses implement these to do the
- // proper negotiation steps. negotiateStep() is called with a buffer
- // just received from the peer.
- void startNegotiate();
- void negotiateStep(BufferBase *buff);
-};
-
-}}} // namespace qpid::sys::windows
-
-#endif // _sys_windows_SslAsynchIO
diff --git a/cpp/src/qpid/sys/windows/StrError.cpp b/cpp/src/qpid/sys/windows/StrError.cpp
deleted file mode 100755
index 546d399d16..0000000000
--- a/cpp/src/qpid/sys/windows/StrError.cpp
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- *
- * 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/sys/StrError.h"
-#include <string>
-#include <string.h>
-#include <windows.h>
-
-namespace qpid {
-namespace sys {
-
-std::string strError(int err) {
- const size_t bufsize = 512;
- char buf[bufsize];
- buf[0] = 0;
- if (0 == FormatMessage (FORMAT_MESSAGE_MAX_WIDTH_MASK
- | FORMAT_MESSAGE_FROM_SYSTEM,
- 0,
- err,
- 0, // Default language
- buf,
- bufsize,
- 0))
- {
-#ifdef _MSC_VER
- strerror_s(buf, bufsize, err);
-#else
- return std::string(strerror(err));
-#endif
- }
- return std::string(buf);
-}
-
-}}
diff --git a/cpp/src/qpid/sys/windows/SystemInfo.cpp b/cpp/src/qpid/sys/windows/SystemInfo.cpp
deleted file mode 100755
index 4da440bdd4..0000000000
--- a/cpp/src/qpid/sys/windows/SystemInfo.cpp
+++ /dev/null
@@ -1,203 +0,0 @@
-/*
- * 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.
- *
- */
-
-/* GetNativeSystemInfo call requires _WIN32_WINNT 0x0501 or higher */
-#ifndef _WIN32_WINNT
-# define _WIN32_WINNT 0x0501
-#endif
-
-#include "qpid/sys/IntegerTypes.h"
-#include "qpid/sys/SystemInfo.h"
-
-#include <winsock2.h>
-#include <ws2tcpip.h>
-#include <windows.h>
-#include <tlhelp32.h>
-
-#ifndef HOST_NAME_MAX
-# define HOST_NAME_MAX 256
-#endif
-
-namespace qpid {
-namespace sys {
-
-long SystemInfo::concurrency() {
- SYSTEM_INFO sys_info;
- ::GetSystemInfo (&sys_info);
- long activeProcessors = 0;
- DWORD_PTR mask = sys_info.dwActiveProcessorMask;
- while (mask != 0) {
- if (mask & 1)
- ++activeProcessors;
- mask >>= 1;
- }
- return activeProcessors;
-}
-
-bool SystemInfo::getLocalHostname (Address &address) {
- char name[HOST_NAME_MAX];
- if (::gethostname(name, sizeof(name)) != 0) {
- errno = WSAGetLastError();
- return false;
- }
- address.host = name;
- return true;
-}
-
-static const std::string LOCALHOST("127.0.0.1");
-static const std::string TCP("tcp");
-
-void SystemInfo::getLocalIpAddresses (uint16_t port,
- std::vector<Address> &addrList) {
- enum { MAX_URL_INTERFACES = 100 };
-
- SOCKET s = socket (PF_INET, SOCK_STREAM, 0);
- if (s != INVALID_SOCKET) {
- INTERFACE_INFO interfaces[MAX_URL_INTERFACES];
- DWORD filledBytes = 0;
- WSAIoctl (s,
- SIO_GET_INTERFACE_LIST,
- 0,
- 0,
- interfaces,
- sizeof (interfaces),
- &filledBytes,
- 0,
- 0);
- unsigned int interfaceCount = filledBytes / sizeof (INTERFACE_INFO);
- for (unsigned int i = 0; i < interfaceCount; ++i) {
- if (interfaces[i].iiFlags & IFF_UP) {
- std::string addr(inet_ntoa(interfaces[i].iiAddress.AddressIn.sin_addr));
- if (addr != LOCALHOST)
- addrList.push_back(Address(TCP, addr, port));
- }
- }
- closesocket (s);
- }
-}
-
-void SystemInfo::getSystemId (std::string &osName,
- std::string &nodeName,
- std::string &release,
- std::string &version,
- std::string &machine)
-{
- osName = "Microsoft Windows";
-
- char node[MAX_COMPUTERNAME_LENGTH + 1];
- DWORD nodelen = MAX_COMPUTERNAME_LENGTH + 1;
- GetComputerName (node, &nodelen);
- nodeName = node;
-
- OSVERSIONINFOEX vinfo;
- vinfo.dwOSVersionInfoSize = sizeof(vinfo);
- GetVersionEx ((OSVERSIONINFO *)&vinfo);
-
- SYSTEM_INFO sinfo;
- GetNativeSystemInfo(&sinfo);
-
- switch(vinfo.dwMajorVersion) {
- case 5:
- switch(vinfo.dwMinorVersion) {
- case 0:
- release ="2000";
- break;
- case 1:
- release = "XP";
- break;
- case 2:
- if (sinfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64 ||
- sinfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_IA64)
- release = "XP-64";
- else
- release = "Server 2003";
- break;
- default:
- release = "Windows";
- }
- break;
- case 6:
- if (vinfo.wProductType == VER_NT_SERVER)
- release = "Server 2008";
- else
- release = "Vista";
- break;
- default:
- release = "Microsoft Windows";
- }
- version = vinfo.szCSDVersion;
-
- switch(sinfo.wProcessorArchitecture) {
- case PROCESSOR_ARCHITECTURE_AMD64:
- machine = "x86-64";
- break;
- case PROCESSOR_ARCHITECTURE_IA64:
- machine = "IA64";
- break;
- case PROCESSOR_ARCHITECTURE_INTEL:
- machine = "x86";
- break;
- default:
- machine = "unknown";
- break;
- }
-}
-
-uint32_t SystemInfo::getProcessId()
-{
- return static_cast<uint32_t>(::GetCurrentProcessId());
-}
-
-uint32_t SystemInfo::getParentProcessId()
-{
- // Only want info for the current process, so ask for something specific.
- // The module info won't be used here but it keeps the snapshot limited to
- // the current process so a search through all processes is not needed.
- HANDLE snap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, 0);
- if (snap == INVALID_HANDLE_VALUE)
- return 0;
- PROCESSENTRY32 entry;
- entry.dwSize = sizeof(entry);
- if (!Process32First(snap, &entry))
- entry.th32ParentProcessID = 0;
- CloseHandle(snap);
- return static_cast<uint32_t>(entry.th32ParentProcessID);
-}
-
-std::string SystemInfo::getProcessName()
-{
- std::string name;
-
- // Only want info for the current process, so ask for something specific.
- // The module info won't be used here but it keeps the snapshot limited to
- // the current process so a search through all processes is not needed.
- HANDLE snap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, 0);
- if (snap == INVALID_HANDLE_VALUE)
- return name;
- PROCESSENTRY32 entry;
- entry.dwSize = sizeof(entry);
- if (!Process32First(snap, &entry))
- entry.szExeFile[0] = '\0';
- CloseHandle(snap);
- name = entry.szExeFile;
- return name;
-}
-
-}} // namespace qpid::sys
diff --git a/cpp/src/qpid/sys/windows/Thread.cpp b/cpp/src/qpid/sys/windows/Thread.cpp
deleted file mode 100755
index 583a9613a3..0000000000
--- a/cpp/src/qpid/sys/windows/Thread.cpp
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- *
- * 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/sys/Thread.h"
-#include "qpid/sys/Runnable.h"
-#include "qpid/sys/windows/check.h"
-
-#include <process.h>
-#include <windows.h>
-
-namespace {
-unsigned __stdcall runRunnable(void* p)
-{
- static_cast<qpid::sys::Runnable*>(p)->run();
- _endthreadex(0);
- return 0;
-}
-}
-
-namespace qpid {
-namespace sys {
-
-class ThreadPrivate {
- friend class Thread;
-
- HANDLE threadHandle;
- unsigned threadId;
-
- ThreadPrivate(Runnable* runnable) {
- uintptr_t h = _beginthreadex(0,
- 0,
- runRunnable,
- runnable,
- 0,
- &threadId);
- QPID_WINDOWS_CHECK_CRT_NZ(h);
- threadHandle = reinterpret_cast<HANDLE>(h);
- }
-
- ThreadPrivate()
- : threadHandle(GetCurrentThread()), threadId(GetCurrentThreadId()) {}
-};
-
-Thread::Thread() {}
-
-Thread::Thread(Runnable* runnable) : impl(new ThreadPrivate(runnable)) {}
-
-Thread::Thread(Runnable& runnable) : impl(new ThreadPrivate(&runnable)) {}
-
-Thread::operator bool() {
- return impl;
-}
-
-bool Thread::operator==(const Thread& t) const {
- return impl->threadId == t.impl->threadId;
-}
-
-bool Thread::operator!=(const Thread& t) const {
- return !(*this==t);
-}
-
-void Thread::join() {
- if (impl) {
- DWORD status = WaitForSingleObject (impl->threadHandle, INFINITE);
- QPID_WINDOWS_CHECK_NOT(status, WAIT_FAILED);
- CloseHandle (impl->threadHandle);
- impl->threadHandle = 0;
- }
-}
-
-unsigned long Thread::logId() {
- return GetCurrentThreadId();
-}
-
-/* static */
-Thread Thread::current() {
- Thread t;
- t.impl.reset(new ThreadPrivate());
- return t;
-}
-
-}} /* qpid::sys */
diff --git a/cpp/src/qpid/sys/windows/Time.cpp b/cpp/src/qpid/sys/windows/Time.cpp
deleted file mode 100644
index 25c50819cd..0000000000
--- a/cpp/src/qpid/sys/windows/Time.cpp
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- *
- * 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/sys/Time.h"
-#include <ostream>
-#include <boost/date_time/posix_time/posix_time.hpp>
-#include <boost/thread/thread_time.hpp>
-#include <windows.h>
-
-using namespace boost::posix_time;
-
-namespace {
-
-// High-res timing support. This will display times since program start,
-// more or less. Keep track of the start value and the conversion factor to
-// seconds.
-bool timeInitialized = false;
-LARGE_INTEGER start;
-double freq = 1.0;
-
-}
-
-namespace qpid {
-namespace sys {
-
-AbsTime::AbsTime(const AbsTime& t, const Duration& d) {
- if (d == Duration::max()) {
- timepoint = ptime(max_date_time);
- }
- else {
- time_duration td = microseconds(d.nanosecs / 1000);
- timepoint = t.timepoint + td;
- }
-}
-
-AbsTime AbsTime::FarFuture() {
- AbsTime ff;
- ptime maxd(max_date_time);
- ff.timepoint = maxd;
- return ff;
-}
-
-AbsTime AbsTime::Epoch() {
- AbsTime time_epoch;
- time_epoch.timepoint = boost::posix_time::from_time_t(0);
- return time_epoch;
-}
-
-AbsTime AbsTime::now() {
- AbsTime time_now;
- time_now.timepoint = boost::get_system_time();
- return time_now;
-}
-
-Duration::Duration(const AbsTime& start, const AbsTime& finish) {
- time_duration d = finish.timepoint - start.timepoint;
- nanosecs = d.total_nanoseconds();
-}
-
-std::ostream& operator<<(std::ostream& o, const Duration& d) {
- return o << int64_t(d) << "ns";
-}
-
-std::ostream& operator<<(std::ostream& o, const AbsTime& t) {
- std::string time_string = to_simple_string(t.timepoint);
- return o << time_string;
-}
-
-
-void sleep(int secs) {
- ::Sleep(secs * 1000);
-}
-
-void usleep(uint64_t usecs) {
- DWORD msecs = usecs / 1000;
- if (msecs == 0)
- msecs = 1;
- ::Sleep(msecs);
-}
-
-void outputFormattedNow(std::ostream& o) {
- ::time_t rawtime;
- ::tm timeinfo;
- char time_string[100];
-
- ::time( &rawtime );
-#ifdef _MSC_VER
- ::localtime_s(&timeinfo, &rawtime);
-#else
- timeinfo = *(::localtime(&rawtime));
-#endif
- ::strftime(time_string, 100,
- "%Y-%m-%d %H:%M:%S",
- &timeinfo);
- o << time_string << " ";
-}
-
-void outputHiresNow(std::ostream& o) {
- if (!timeInitialized) {
- start.QuadPart = 0;
- LARGE_INTEGER iFreq;
- iFreq.QuadPart = 1;
- QueryPerformanceCounter(&start);
- QueryPerformanceFrequency(&iFreq);
- freq = static_cast<double>(iFreq.QuadPart);
- timeInitialized = true;
- }
- LARGE_INTEGER iNow;
- iNow.QuadPart = 0;
- QueryPerformanceCounter(&iNow);
- iNow.QuadPart -= start.QuadPart;
- if (iNow.QuadPart < 0)
- iNow.QuadPart = 0;
- double now = static_cast<double>(iNow.QuadPart);
- now /= freq; // now is seconds after this
- o << std::fixed << std::setprecision(8) << std::setw(16) << std::setfill('0') << now << "s ";
-}
-}}
diff --git a/cpp/src/qpid/sys/windows/mingw32_compat.h b/cpp/src/qpid/sys/windows/mingw32_compat.h
deleted file mode 100644
index 51f613cc25..0000000000
--- a/cpp/src/qpid/sys/windows/mingw32_compat.h
+++ /dev/null
@@ -1,39 +0,0 @@
-#ifndef _sys_windows_mingw32_compat
-#define _sys_windows_mingw32_compat
-/*
- *
- * 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.
- *
- */
-
-#ifdef WIN32
-#ifndef _MSC_VER
-
-//
-// The following definitions for extension function GUIDs and signatures are taken from
-// MswSock.h in the Windows32 SDK. These rightfully belong in the mingw32 version of
-// mswsock.h, but are not included presently.
-//
-
-#define WSAID_ACCEPTEX {0xb5367df1,0xcbac,0x11cf,{0x95,0xca,0x00,0x80,0x5f,0x48,0xa1,0x92}}
-typedef BOOL (PASCAL *LPFN_ACCEPTEX)(SOCKET,SOCKET,PVOID,DWORD,DWORD,DWORD,LPDWORD,LPOVERLAPPED);
-
-#endif
-#endif
-
-#endif
diff --git a/cpp/src/qpid/sys/windows/uuid.cpp b/cpp/src/qpid/sys/windows/uuid.cpp
deleted file mode 100644
index 3316ecbc00..0000000000
--- a/cpp/src/qpid/sys/windows/uuid.cpp
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- *
- * 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 <rpc.h>
-#ifdef uuid_t /* Done in rpcdce.h */
-# undef uuid_t
-#endif
-
-#include "qpid/sys/windows/uuid.h"
-
-#include <string.h>
-
-void uuid_clear (uuid_t uu) {
- UuidCreateNil (reinterpret_cast<UUID*>(uu));
-}
-
-void uuid_copy (uuid_t dst, const uuid_t src) {
- memcpy (dst, src, qpid::sys::UuidSize);
-}
-
-void uuid_generate (uuid_t out) {
- UuidCreate (reinterpret_cast<UUID*>(out));
-}
-
-int uuid_is_null (const uuid_t uu) {
- RPC_STATUS unused;
- return UuidIsNil ((UUID*)uu, &unused);
-}
-
-int uuid_parse (const char *in, uuid_t uu) {
- return UuidFromString ((unsigned char*)in, (UUID*)uu) == RPC_S_OK ? 0 : -1;
-}
-
-void uuid_unparse (const uuid_t uu, char *out) {
- unsigned char *formatted;
- if (UuidToString((UUID*)uu, &formatted) == RPC_S_OK) {
-#ifdef _MSC_VER
- strncpy_s (out, 36+1, (char*)formatted, _TRUNCATE);
-#else
- strncpy (out, (char*)formatted, 36+1);
-#endif
- RpcStringFree(&formatted);
- }
-}
-
-int uuid_compare (const uuid_t a, const uuid_t b) {
- RPC_STATUS unused;
- return !UuidEqual((UUID*)a, (UUID*)b, &unused);
-}
diff --git a/cpp/src/qpid/sys/windows/uuid.h b/cpp/src/qpid/sys/windows/uuid.h
deleted file mode 100644
index 8ab132e9ce..0000000000
--- a/cpp/src/qpid/sys/windows/uuid.h
+++ /dev/null
@@ -1,39 +0,0 @@
-#ifndef _sys_windows_uuid_h
-#define _sys_windows_uuid_h
-
-/*
- *
- * 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/types/ImportExport.h"
-#include <qpid/sys/IntegerTypes.h>
-
-namespace qpid { namespace sys { const size_t UuidSize = 16; }}
-typedef uint8_t uuid_t[qpid::sys::UuidSize];
-
-QPID_TYPES_EXTERN void uuid_clear (uuid_t uu);
-QPID_TYPES_EXTERN void uuid_copy (uuid_t dst, const uuid_t src);
-QPID_TYPES_EXTERN void uuid_generate (uuid_t out);
-QPID_TYPES_EXTERN int uuid_is_null (const uuid_t uu); // Returns 1 if null, else 0
-QPID_TYPES_EXTERN int uuid_parse (const char *in, uuid_t uu); // Returns 0 on success, else -1
-QPID_TYPES_EXTERN void uuid_unparse (const uuid_t uu, char *out);
-QPID_TYPES_EXTERN int uuid_compare (const uuid_t a, const uuid_t b);
-
-#endif /*!_sys_windows_uuid_h*/