Index: c/xplcommon/Acceptor.h
===================================================================
--- src/xplcommon/Acceptor.h	(revision 17)
+++ 	(revision )
@@ -1,116 +1,0 @@
-// Copyright (c) 2012 by István Váradi
-
-// This file is part of libxplcommon, a common utility library for
-// development related to X-Plane
-
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-
-// 1. Redistributions of source code must retain the above copyright notice, this
-//    list of conditions and the following disclaimer.
-// 2. Redistributions in binary form must reproduce the above copyright notice,
-//    this list of conditions and the following disclaimer in the documentation
-//    and/or other materials provided with the distribution.
-
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
-// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// The views and conclusions contained in the software and documentation are those
-// of the authors and should not be interpreted as representing official policies,
-// either expressed or implied, of the FreeBSD Project.
-
-#ifndef XPLCOMMON_ACCEPTOR_H
-#define XPLCOMMON_ACCEPTOR_H
-//------------------------------------------------------------------------------
-
-#include "Failable.h"
-
-//------------------------------------------------------------------------------
-
-#if 0 // The public interface of a connection acceptor for a socket
-
-//------------------------------------------------------------------------------
-
-namespace xplcommon {
-
-//------------------------------------------------------------------------------
-
-/**
- * Class representing the accepting of an incoming connection on a
- * socket. It cannot be created directly, only acquired from a server
- * socket. Usually some more concrete subclass is returned from which
- * the socket representing the accepted connection can be queried.
- */
-class Acceptor : public FailableReference<Acceptor>
-{
-public:
-    /**
-     * Destroy the acceptor.
-     */
-    virtual ~Acceptor();
-
-    /**
-     * Start accepting a connection.
-     *
-     * If a connection is already accepted, but not retrieved yet, it
-     * returns true.
-     *
-     * If a new socket becomes immediately available, it returns true.
-     *
-     * If some error occurs, the acceptor is marked as failed.
-     */
-    bool accept();
-};
-
-//------------------------------------------------------------------------------
-
-} /* namespace xplcommon */
-
-//------------------------------------------------------------------------------
-
-#endif // 0, The public interface of a connection acceptor for a socket
-
-//------------------------------------------------------------------------------
-
-#include "config.h"
-
-//------------------------------------------------------------------------------
-
-#if TARGET_API_WIN32
-
-//------------------------------------------------------------------------------
-
-#include "win32/Acceptor.h"
-
-namespace xplcommon { typedef win32::Acceptor Acceptor; }
-
-//------------------------------------------------------------------------------
-
-#else // TARGET_API_WIN32
-
-//------------------------------------------------------------------------------
-
-#include "posix/Acceptor.h"
-
-namespace xplcommon { typedef posix::Acceptor Acceptor; }
-
-//------------------------------------------------------------------------------
-
-#endif // TARGET_API_WIN32
-
-//------------------------------------------------------------------------------
-#endif // XPLCOMMON_ACCEPTOR_H
-
-// Local Variables:
-// mode: C++
-// c-basic-offset: 4
-// indent-tabs-mode: nil
-// End:
Index: src/xplcommon/BufferedStream.h
===================================================================
--- src/xplcommon/BufferedStream.h	(revision 17)
+++ src/xplcommon/BufferedStream.h	(revision 21)
@@ -58,5 +58,5 @@
 public:
     /**
-     * Destroy the buffered waitable.
+     * Destroy the buffered stream.
      */
     virtual ~BufferedStream();
@@ -64,5 +64,5 @@
     /**
      * Get the reference of the reading buffer. Note, that it can be a
-     * 0 reference, if the waitable has no reading buffer.
+     * 0 reference, if the stream has no reading buffer.
      */
     ReadingBuffer& getReadingBuffer();
@@ -70,5 +70,5 @@
     /**
      * Get the reference of the writing buffer. Note, that it can be a
-     * 0 reference, if the waitable has no writing buffer.
+     * 0 reference, if the stream has no writing buffer.
      */
     WritingBuffer& getWritingBuffer();
Index: c/xplcommon/ClientSocket.h
===================================================================
--- src/xplcommon/ClientSocket.h	(revision 17)
+++ 	(revision )
@@ -1,107 +1,0 @@
-// Copyright (c) 2012 by István Váradi
-
-// This file is part of libxplcommon, a common utility library for
-// development related to X-Plane
-
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-
-// 1. Redistributions of source code must retain the above copyright notice, this
-//    list of conditions and the following disclaimer.
-// 2. Redistributions in binary form must reproduce the above copyright notice,
-//    this list of conditions and the following disclaimer in the documentation
-//    and/or other materials provided with the distribution.
-
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
-// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// The views and conclusions contained in the software and documentation are those
-// of the authors and should not be interpreted as representing official policies,
-// either expressed or implied, of the FreeBSD Project.
-
-#ifndef XPLCOMMON_CLIENTSOCKET_H
-#define XPLCOMMON_CLIENTSOCKET_H
-//------------------------------------------------------------------------------
-
-#include "BufferedStream.h"
-
-//------------------------------------------------------------------------------
-
-#if 0 // The public interface of a client socket (i.e. one that
-      // connects to a server socket)
-
-//------------------------------------------------------------------------------
-
-namespace xplcommon {
-
-//------------------------------------------------------------------------------
-
-/**
- * A socket that can be connected to another one.
- */
-class ClientSocket : public BufferedStream
-{
-public:
-    /**
-     * Destroy the socket.
-     */
-    virtual ~ClientSocket();
-
-    /**
-     * Get the connector. Use this object to connect to another socket.
-     */
-    Connector& getConnector();
-};
-
-//------------------------------------------------------------------------------
-
-} /* namespace xplcommon */
-
-//------------------------------------------------------------------------------
-
-#endif // 0, The public interface of a client socket
-
-//------------------------------------------------------------------------------
-
-#include "config.h"
-
-//------------------------------------------------------------------------------
-
-#if TARGET_API_WIN32
-
-//------------------------------------------------------------------------------
-
-#include "win32/ClientSocket.h"
-
-namespace xplcommon { typedef win32::ClientSocket ClientSocket; }
-
-//------------------------------------------------------------------------------
-
-#else // TARGET_API_WIN32
-
-//------------------------------------------------------------------------------
-
-#include "posix/ClientSocket.h"
-
-namespace xplcommon { typedef posix::ClientSocket ClientSocket; }
-
-//------------------------------------------------------------------------------
-
-#endif // TARGET_API_WIN32
-
-//------------------------------------------------------------------------------
-#endif // XPLCOMMON_CLIENTSOCKET_H
-
-// Local Variables:
-// mode: C++
-// c-basic-offset: 4
-// indent-tabs-mode: nil
-// End:
Index: c/xplcommon/Connector.h
===================================================================
--- src/xplcommon/Connector.h	(revision 17)
+++ 	(revision )
@@ -1,112 +1,0 @@
-// Copyright (c) 2012 by István Váradi
-
-// This file is part of libxplcommon, a common utility library for
-// development related to X-Plane
-
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-
-// 1. Redistributions of source code must retain the above copyright notice, this
-//    list of conditions and the following disclaimer.
-// 2. Redistributions in binary form must reproduce the above copyright notice,
-//    this list of conditions and the following disclaimer in the documentation
-//    and/or other materials provided with the distribution.
-
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
-// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// The views and conclusions contained in the software and documentation are those
-// of the authors and should not be interpreted as representing official policies,
-// either expressed or implied, of the FreeBSD Project.
-
-#ifndef XPLCOMMON_CONNECTOR_H
-#define XPLCOMMON_CONNECTOR_H
-//------------------------------------------------------------------------------
-
-#include "Failable.h"
-
-//------------------------------------------------------------------------------
-
-#if 0 // The public interface of a connector for a client socket
-
-//------------------------------------------------------------------------------
-
-namespace xplcommon {
-
-//------------------------------------------------------------------------------
-
-/**
- * Class representing the creation of a connection to some remote
- * entity, like a socket or a pipe. It cannot be created directly,
- * only acquired from a client socket.
- */
-class Connector : public FailableReference<Connector>
-{
-public:
-    /**
-     * Connect to an address properly set up.
-     *
-     * If the connection succeeds immediately, it indicates success.
-     *
-     * If the connection does not succeed, because it would block, it
-     * sets up the socket to wait for the connection to succeed, and
-     * returns failure.
-     *
-     * If the connection fails for another reason, the error code is
-     * set, and false is returned.
-     */
-    bool connect();
-};
-
-//------------------------------------------------------------------------------
-
-} /* namespace xplcommon */
-
-//------------------------------------------------------------------------------
-
-#endif // 0, The public interface of a connector for a client socket
-
-//------------------------------------------------------------------------------
-
-#include "config.h"
-
-//------------------------------------------------------------------------------
-
-#if TARGET_API_WIN32
-
-//------------------------------------------------------------------------------
-
-#include "win32/Connector.h"
-
-namespace xplcommon { typedef win32::Connector Connector; }
-
-//------------------------------------------------------------------------------
-
-#else // TARGET_API_WIN32
-
-//------------------------------------------------------------------------------
-
-#include "posix/Connector.h"
-
-namespace xplcommon { typedef posix::Connector Connector; }
-
-//------------------------------------------------------------------------------
-
-#endif // TARGET_API_WIN32
-
-//------------------------------------------------------------------------------
-#endif // XPLCOMMON_CONNECTOR_H
-
-// Local Variables:
-// mode: C++
-// c-basic-offset: 4
-// indent-tabs-mode: nil
-// End:
Index: src/xplcommon/LocalAcceptor.h
===================================================================
--- src/xplcommon/LocalAcceptor.h	(revision 17)
+++ src/xplcommon/LocalAcceptor.h	(revision 21)
@@ -32,5 +32,5 @@
 //------------------------------------------------------------------------------
 
-#include "Acceptor.h"
+#include "Failable.h"
 
 //------------------------------------------------------------------------------
@@ -48,11 +48,28 @@
  * connection.
  */
-class LocalAcceptor : public Acceptor
+class LocalAcceptor : public FailableReference<LocalAcceptor>
 {
 public:
+
+    /**
+     * Start accepting a connection.
+     *
+     * If a connection is already accepted, but not retrieved yet, it
+     * returns true.
+     *
+     * If a new socket becomes immediately available, it returns true.
+     *
+     * If some error occurs, the acceptor is marked as failed.
+     */
+    bool accept();
+
     /**
      * Get the local socket accepted last. If no socket was accepted,
-     * return 0. The local socket's waiter will be the given one
-     * (which can be 0).
+     * return 0. The local socket's waiter will be the given one. If
+     * the server socket has no waiter, this one should be 0. If the
+     * server socket has a waiter, this one should not be 0. In other
+     * words, if the server socket is non-blocking, the accepted one
+     * should also be non-blocking, if the server socket is blocking,
+     * the accepted one should also be blocking.
      */
     LocalSocket* getSocket(Waiter* waiter,
Index: src/xplcommon/LocalClientSocket.h
===================================================================
--- src/xplcommon/LocalClientSocket.h	(revision 17)
+++ src/xplcommon/LocalClientSocket.h	(revision 21)
@@ -32,5 +32,5 @@
 //------------------------------------------------------------------------------
 
-#include "ClientSocket.h"
+#include "BufferedStream.h"
 
 //------------------------------------------------------------------------------
@@ -44,4 +44,8 @@
 //------------------------------------------------------------------------------
 
+class LocalConnector;
+
+//------------------------------------------------------------------------------
+
 /**
  * Client socket that connects to a server socket locally. On Linux it
@@ -50,5 +54,5 @@
  * The server socket's name should be given.
  */
-class LocalClientSocket : public ClientSocket
+class LocalClientSocket : public BufferedStream
 {
 public:
@@ -65,4 +69,9 @@
                       size_t readingCapacity = DEFAULT_CAPACITY,
                       size_t writingCapacity = DEFAULT_CAPACITY);
+
+    /**
+     * Get the connector. Use this object to connect to another socket.
+     */
+    LocalConnector& getConnector();
 };
 
Index: src/xplcommon/LocalConnector.h
===================================================================
--- src/xplcommon/LocalConnector.h	(revision 21)
+++ src/xplcommon/LocalConnector.h	(revision 21)
@@ -0,0 +1,112 @@
+// Copyright (c) 2012 by István Váradi
+
+// This file is part of libxplcommon, a common utility library for
+// development related to X-Plane
+
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+
+// 1. Redistributions of source code must retain the above copyright notice, this
+//    list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright notice,
+//    this list of conditions and the following disclaimer in the documentation
+//    and/or other materials provided with the distribution.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// The views and conclusions contained in the software and documentation are those
+// of the authors and should not be interpreted as representing official policies,
+// either expressed or implied, of the FreeBSD Project.
+
+#ifndef XPLCOMMON_LOCALCONNECTOR_H
+#define XPLCOMMON_LOCALCONNECTOR_H
+//------------------------------------------------------------------------------
+
+#include "Failable.h"
+
+//------------------------------------------------------------------------------
+
+#if 0 // The public interface of a connector for a local client socket
+
+//------------------------------------------------------------------------------
+
+namespace xplcommon {
+
+//------------------------------------------------------------------------------
+
+/**
+ * Class representing the creation of a connection to some remote
+ * entity, like a socket or a pipe. It cannot be created directly,
+ * only acquired from a client socket.
+ */
+class LocalConnector : public FailableReference<LocalConnector>
+{
+public:
+    /**
+     * Connect to an address properly set up.
+     *
+     * If the connection succeeds immediately, it indicates success.
+     *
+     * If the connection does not succeed, because it would block, it
+     * sets up the socket to wait for the connection to succeed, and
+     * returns failure.
+     *
+     * If the connection fails for another reason, the error code is
+     * set, and false is returned.
+     */
+    bool connect();
+};
+
+//------------------------------------------------------------------------------
+
+} /* namespace xplcommon */
+
+//------------------------------------------------------------------------------
+
+#endif // 0, The public interface of a connector for a local client socket
+
+//------------------------------------------------------------------------------
+
+#include "config.h"
+
+//------------------------------------------------------------------------------
+
+#if TARGET_API_WIN32
+
+//------------------------------------------------------------------------------
+
+#include "win32/LocalConnector.h"
+
+namespace xplcommon { typedef win32::LocalConnector LocalConnector; }
+
+//------------------------------------------------------------------------------
+
+#else // TARGET_API_WIN32
+
+//------------------------------------------------------------------------------
+
+#include "posix/LocalConnector.h"
+
+namespace xplcommon { typedef posix::LocalConnector LocalConnector; }
+
+//------------------------------------------------------------------------------
+
+#endif // TARGET_API_WIN32
+
+//------------------------------------------------------------------------------
+#endif // XPLCOMMON_LOCALCONNECTOR_H
+
+// Local Variables:
+// mode: C++
+// c-basic-offset: 4
+// indent-tabs-mode: nil
+// End:
Index: src/xplcommon/Makefile.am
===================================================================
--- src/xplcommon/Makefile.am	(revision 17)
+++ src/xplcommon/Makefile.am	(revision 21)
@@ -32,9 +32,7 @@
 	ReadingBuffer.h		\
 	WritingBuffer.h		\
-	Acceptor.h		\
 	LocalAcceptor.h		\
 	LocalSocket.h		\
 	LocalServerSocket.h	\
-	Connector.h		\
-	ClientSocket.h		\
+	LocalConnector.h	\
 	LocalClientSocket.h
Index: src/xplcommon/ReadingBuffer.h
===================================================================
--- src/xplcommon/ReadingBuffer.h	(revision 17)
+++ src/xplcommon/ReadingBuffer.h	(revision 21)
@@ -95,7 +95,7 @@
 //------------------------------------------------------------------------------
 
-// #include "win32/ReadingBuffer.h"
+#include "win32/ReadingBuffer.h"
 
-// namespace xplcommon { typedef win32::ReadingBuffer ReadingBuffer; }
+namespace xplcommon { typedef win32::ReadingBuffer ReadingBuffer; }
 
 //------------------------------------------------------------------------------
Index: src/xplcommon/WritingBuffer.h
===================================================================
--- src/xplcommon/WritingBuffer.h	(revision 17)
+++ src/xplcommon/WritingBuffer.h	(revision 21)
@@ -101,7 +101,7 @@
 //------------------------------------------------------------------------------
 
-// #include "win32/WritingBuffer.h"
+#include "win32/WritingBuffer.h"
 
-// namespace xplcommon { typedef win32::WritingBuffer WritingBuffer; }
+namespace xplcommon { typedef win32::WritingBuffer WritingBuffer; }
 
 //------------------------------------------------------------------------------
Index: src/xplcommon/posix/ClientSocket.cc
===================================================================
--- src/xplcommon/posix/ClientSocket.cc	(revision 16)
+++ src/xplcommon/posix/ClientSocket.cc	(revision 21)
@@ -41,22 +41,4 @@
 
 using xplcommon::posix::ClientSocket;
-using xplcommon::posix::Connector;
-
-//------------------------------------------------------------------------------
-
-ClientSocket::~ClientSocket()
-{
-    delete connector;
-}
-
-//------------------------------------------------------------------------------
-
-Connector& ClientSocket::getConnector()
-{
-    if (connector==0) {
-        connector = createConnector();
-    }
-    return *connector;
-}
 
 //------------------------------------------------------------------------------
@@ -64,6 +46,6 @@
 void ClientSocket::handleEvents(short events)
 {
-    if (connector!=0 && connector->connecting && (events&POLLOUT)==POLLOUT) {
-        connector->handleWritable();
+    if (connector.connecting && (events&POLLOUT)==POLLOUT) {
+        connector.handleWritable();
         events &= ~POLLOUT;
     }
Index: src/xplcommon/posix/ClientSocket.h
===================================================================
--- src/xplcommon/posix/ClientSocket.h	(revision 14)
+++ src/xplcommon/posix/ClientSocket.h	(revision 21)
@@ -51,7 +51,7 @@
 private:
     /**
-     * The connector, if any. It is created only, if requested.
+     * The connector.
      */
-    Connector* connector;
+    Connector& connector;
 
 protected:
@@ -59,25 +59,10 @@
      * Construct the socket with the given parameters.
      */
-    ClientSocket(int domain, int type, Waiter* waiter = 0, int protocol = 0,
+    ClientSocket(int domain, int type, Connector& connector,
+                 Waiter* waiter = 0, int protocol = 0,
                  size_t readingCapacity = DEFAULT_CAPACITY,
                  size_t writingCapacity = DEFAULT_CAPACITY);
 
-public:
-    /**
-     * Destroy the socket.
-     */
-    virtual ~ClientSocket();
-
-    /**
-     * Get the connector. Use this object to connect to another socket.
-     */
-    Connector& getConnector();
-
 protected:
-    /**
-     * Create a new connector of the correct type.
-     */
-    virtual Connector* createConnector() = 0;
-
     /**
      * Handle any events on the file descriptor. If a connection is in
@@ -105,9 +90,10 @@
 //------------------------------------------------------------------------------
 
-inline ClientSocket::ClientSocket(int domain, int type, Waiter* waiter,
-                                  int protocol, size_t readingCapacity,
+inline ClientSocket::ClientSocket(int domain, int type, Connector& connector,
+                                  Waiter* waiter, int protocol,
+                                  size_t readingCapacity,
                                   size_t writingCapacity) :
     Socket(domain, type, waiter, protocol, readingCapacity, writingCapacity),
-    connector(0)
+    connector(connector)
 {
 }
Index: src/xplcommon/posix/LocalClientSocket.cc
===================================================================
--- src/xplcommon/posix/LocalClientSocket.cc	(revision 15)
+++ src/xplcommon/posix/LocalClientSocket.cc	(revision 21)
@@ -32,5 +32,5 @@
 #include "LocalClientSocket.h"
 
-#include "Connector.h"
+#include "LocalConnector.h"
 #include "LocalServerSocket.h"
 
@@ -40,49 +40,4 @@
 
 using xplcommon::posix::LocalClientSocket;
-using xplcommon::posix::Connector;
-
-//------------------------------------------------------------------------------
-
-/**
- * The connector class used by the local client.
- */
-class LocalClientSocket::LocalConnector : public Connector
-{
-private:
-    /**
-     * The reference to the corresponding socket's address.
-     */
-    const struct sockaddr_un& address;
-
-public:
-    /**
-     * Create the connector for the given local client socket.
-     */
-    LocalConnector(LocalClientSocket* socket);
-
-protected:
-    /**
-     * Get the address.
-     */
-    virtual const struct sockaddr* getAddress(size_t& addrlen);
-};
-
-//------------------------------------------------------------------------------
-
-inline
-LocalClientSocket::LocalConnector::LocalConnector(LocalClientSocket* socket) :
-    Connector(socket),
-    address(socket->sun)
-{
-}
-
-//------------------------------------------------------------------------------
-
-const struct sockaddr*
-LocalClientSocket::LocalConnector::getAddress(size_t& addrlen)
-{
-    addrlen = sizeof(address);
-    return reinterpret_cast<const struct sockaddr*>(&address);
-}
 
 //------------------------------------------------------------------------------
@@ -92,16 +47,8 @@
                                      size_t readingCapacity,
                                      size_t writingCapacity) :
-    ClientSocket(AF_UNIX, SOCK_STREAM, waiter, 0,
-                 readingCapacity, writingCapacity)
+    ClientSocket(AF_UNIX, SOCK_STREAM, connector, waiter, 0,
+                 readingCapacity, writingCapacity),
+    connector(this, name)
 {
-    sun.sun_family = AF_UNIX;
-    LocalServerSocket::setupPath(sun, name);
-}
-
-//------------------------------------------------------------------------------
-
-Connector* LocalClientSocket::createConnector()
-{
-    return new LocalConnector(this);
 }
 
Index: src/xplcommon/posix/LocalClientSocket.h
===================================================================
--- src/xplcommon/posix/LocalClientSocket.h	(revision 15)
+++ src/xplcommon/posix/LocalClientSocket.h	(revision 21)
@@ -34,5 +34,5 @@
 #include "ClientSocket.h"
 
-#include <sys/un.h>
+#include "LocalConnector.h"
 
 //------------------------------------------------------------------------------
@@ -53,12 +53,7 @@
 private:
     /**
-     * The connector class.
-     */
-    class LocalConnector;
-
-    /**
      * The address to use for connecting.
      */
-    struct sockaddr_un sun;
+    LocalConnector connector;
 
 public:
@@ -76,12 +71,20 @@
                       size_t writingCapacity = DEFAULT_CAPACITY);
 
-protected:
     /**
-     * Create a new connector of the correct type.
+     * Get the connector for this client.
      */
-    virtual Connector* createConnector();
+    LocalConnector& getConnector();
 
     friend class LocalConnector;
 };
+
+//------------------------------------------------------------------------------
+// Inline definitions
+//------------------------------------------------------------------------------
+
+inline LocalConnector& LocalClientSocket::getConnector()
+{
+    return connector;
+}
 
 //------------------------------------------------------------------------------
Index: src/xplcommon/posix/LocalConnector.cc
===================================================================
--- src/xplcommon/posix/LocalConnector.cc	(revision 21)
+++ src/xplcommon/posix/LocalConnector.cc	(revision 21)
@@ -0,0 +1,52 @@
+// Copyright (c) 2012 by István Váradi
+
+// This file is part of libxplcommon, a common utility library for
+// development related to X-Plane
+
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+
+// 1. Redistributions of source code must retain the above copyright notice, this
+//    list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright notice,
+//    this list of conditions and the following disclaimer in the documentation
+//    and/or other materials provided with the distribution.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// The views and conclusions contained in the software and documentation are those
+// of the authors and should not be interpreted as representing official policies,
+// either expressed or implied, of the FreeBSD Project.
+
+//------------------------------------------------------------------------------
+
+#include "LocalConnector.h"
+
+//------------------------------------------------------------------------------
+
+using xplcommon::posix::LocalConnector;
+
+//------------------------------------------------------------------------------
+
+const struct sockaddr* LocalConnector::getAddress(size_t& addrlen)
+{
+    addrlen = sizeof(address);
+    return reinterpret_cast<const struct sockaddr*>(&address);
+}
+
+//------------------------------------------------------------------------------
+
+// Local Variables:
+// mode: C++
+// c-basic-offset: 4
+// indent-tabs-mode: nil
+// End:
Index: src/xplcommon/posix/LocalConnector.h
===================================================================
--- src/xplcommon/posix/LocalConnector.h	(revision 21)
+++ src/xplcommon/posix/LocalConnector.h	(revision 21)
@@ -0,0 +1,90 @@
+// Copyright (c) 2012 by István Váradi
+
+// This file is part of libxplcommon, a common utility library for
+// development related to X-Plane
+
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+
+// 1. Redistributions of source code must retain the above copyright notice, this
+//    list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright notice,
+//    this list of conditions and the following disclaimer in the documentation
+//    and/or other materials provided with the distribution.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// The views and conclusions contained in the software and documentation are those
+// of the authors and should not be interpreted as representing official policies,
+// either expressed or implied, of the FreeBSD Project.
+
+#ifndef XPLCOMMON_POSIX_LOCALCONNECTOR_H
+#define XPLCOMMON_POSIX_LOCALCONNECTOR_H
+//------------------------------------------------------------------------------
+
+#include "Connector.h"
+
+#include "LocalServerSocket.h"
+
+#include <sys/socket.h>
+
+//------------------------------------------------------------------------------
+
+namespace xplcommon { namespace posix {
+
+//------------------------------------------------------------------------------
+
+/**
+ * The connector class used by the local client socket.
+ */
+class LocalConnector : public Connector
+{
+private:
+    /**
+     * The reference to the corresponding socket's address.
+     */
+    struct sockaddr_un address;
+
+public:
+    /**
+     * Create the connector for the given local client socket.
+     */
+    LocalConnector(ClientSocket* socket, const char* name);
+
+protected:
+    /**
+     * Get the address.
+     */
+    virtual const struct sockaddr* getAddress(size_t& addrlen);
+};
+
+//------------------------------------------------------------------------------
+
+inline LocalConnector::LocalConnector(ClientSocket* socket, const char* name) :
+    Connector(socket)
+{
+    address.sun_family = AF_UNIX;
+    LocalServerSocket::setupPath(address, name);
+}
+
+//------------------------------------------------------------------------------
+
+} /* namespace xplcommon::posix */ } /* namespace xplcommon */
+
+//------------------------------------------------------------------------------
+#endif // XPLCOMMON_POSIX_LOCALCONNECTOR_H
+
+// Local Variables:
+// mode: C++
+// c-basic-offset: 4
+// indent-tabs-mode: nil
+// End:
Index: src/xplcommon/posix/Makefile.am
===================================================================
--- src/xplcommon/posix/Makefile.am	(revision 16)
+++ src/xplcommon/posix/Makefile.am	(revision 21)
@@ -15,4 +15,5 @@
 	ClientSocket.cc		\
 	LocalServerSocket.cc	\
+	LocalConnector.cc	\
 	LocalClientSocket.cc
 
@@ -35,3 +36,4 @@
 	LocalAcceptor.h		\
 	LocalServerSocket.h	\
+	LocalConnector.h	\
 	LocalClientSocket.h
Index: src/xplcommon/posix/ReadingBuffer.cc
===================================================================
--- src/xplcommon/posix/ReadingBuffer.cc	(revision 16)
+++ src/xplcommon/posix/ReadingBuffer.cc	(revision 21)
@@ -34,4 +34,6 @@
 #include "BufferedStream.h"
 
+#include <cassert>
+
 #include <poll.h>
 
@@ -60,5 +62,7 @@
     } else {
         stream.events &= ~POLLIN;
-        addLength(result);
+        size_t added = addLength(result);
+        assert(added==result);
+        assert(getLength()==result);
     }
     return result>=0;
Index: src/xplcommon/posix/Waitable.h
===================================================================
--- src/xplcommon/posix/Waitable.h	(revision 14)
+++ src/xplcommon/posix/Waitable.h	(revision 21)
@@ -93,10 +93,4 @@
 
     /**
-     * Indicate if this waitable is valid, i.e. the file descriptor is
-     * non-negative.
-     */
-    bool isValid() const;
-
-    /**
      * Determine if the waitable is ready or not, i.e. if there is no
      * need to wait for it.
@@ -143,11 +137,4 @@
 //------------------------------------------------------------------------------
 
-inline bool Waitable::isValid() const
-{
-    return fd>=0;
-}
-
-//------------------------------------------------------------------------------
-
 inline bool Waitable::ready()
 {
Index: src/xplcommon/win32/BufferedStream.cc
===================================================================
--- src/xplcommon/win32/BufferedStream.cc	(revision 21)
+++ src/xplcommon/win32/BufferedStream.cc	(revision 21)
@@ -0,0 +1,110 @@
+// Copyright (c) 2012 by István Váradi
+
+// This file is part of libxplcommon, a common utility library for
+// development related to X-Plane
+
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+
+// 1. Redistributions of source code must retain the above copyright notice, this
+//    list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright notice,
+//    this list of conditions and the following disclaimer in the documentation
+//    and/or other materials provided with the distribution.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// The views and conclusions contained in the software and documentation are those
+// of the authors and should not be interpreted as representing official policies,
+// either expressed or implied, of the FreeBSD Project.
+
+//------------------------------------------------------------------------------
+
+#include "BufferedStream.h"
+
+#include "ReadingBuffer.h"
+#include "WritingBuffer.h"
+
+//------------------------------------------------------------------------------
+
+using xplcommon::win32::BufferedStream;
+
+//------------------------------------------------------------------------------
+
+BufferedStream::BufferedStream(Waiter* waiter, HANDLE handle,
+                               size_t readingCapacity, size_t writingCapacity) :
+    Overlappable(waiter, handle),
+    readingBuffer( (readingCapacity==0) ? 0 :
+                   new ReadingBuffer(readingCapacity, this)),
+    writingBuffer( (writingCapacity==0) ? 0 :
+                   new WritingBuffer(writingCapacity, this))
+{
+}
+
+//------------------------------------------------------------------------------
+
+BufferedStream::~BufferedStream()
+{
+    delete writingBuffer;
+    delete readingBuffer;
+}
+
+//------------------------------------------------------------------------------
+
+ssize_t BufferedStream::read(void* dest, size_t length, Overlapped* overlapped)
+{
+    DWORD numRead = 0;
+    overlapped->reset();
+    bool result = ReadFile(handle, dest, length, 0, overlapped->get());
+                           // (overlapped==0) ? &numRead : 0,
+                           // (overlapped==0) ? 0 : overlapped->get());
+    DWORD error = GetLastError();
+    if (!result && (overlapped==0 ||
+                    (error!=ERROR_IO_PENDING && error!=ERROR_IO_INCOMPLETE)))
+    {
+        setErrorCode(error);
+        return -1;
+    } else if (overlapped==0 || overlapped->getResult(numRead, handle)) {
+        return numRead;
+    } else {
+        return -1;
+    }
+}
+
+//------------------------------------------------------------------------------
+
+bool BufferedStream::write(const void* src, size_t length,
+                           Overlapped* overlapped)
+{
+    bool result = WriteFile(handle, src, length, 0,
+                            (overlapped==0) ? 0 : overlapped->get());
+    DWORD error = GetLastError();
+    if (!result && (overlapped==0 ||
+                    (error!=ERROR_IO_PENDING && error!=ERROR_IO_INCOMPLETE)))
+    {
+        setErrorCode(error);
+        return false;
+    } else if (overlapped==0) {
+        return result;
+    } else {
+        DWORD numWritten = 0;
+        return overlapped->getResult(numWritten, handle);
+    }
+}
+
+//------------------------------------------------------------------------------
+
+// Local Variables:
+// mode: C++
+// c-basic-offset: 4
+// indent-tabs-mode: nil
+// End:
Index: src/xplcommon/win32/BufferedStream.h
===================================================================
--- src/xplcommon/win32/BufferedStream.h	(revision 21)
+++ src/xplcommon/win32/BufferedStream.h	(revision 21)
@@ -0,0 +1,153 @@
+// Copyright (c) 2012 by István Váradi
+
+// This file is part of libxplcommon, a common utility library for
+// development related to X-Plane
+
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+
+// 1. Redistributions of source code must retain the above copyright notice, this
+//    list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright notice,
+//    this list of conditions and the following disclaimer in the documentation
+//    and/or other materials provided with the distribution.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// The views and conclusions contained in the software and documentation are those
+// of the authors and should not be interpreted as representing official policies,
+// either expressed or implied, of the FreeBSD Project.
+
+#ifndef XPLCOMMON_WIN32_BUFFEREDSTREAM_H
+#define XPLCOMMON_WIN32_BUFFEREDSTREAM_H
+//------------------------------------------------------------------------------
+
+#include "Overlappable.h"
+
+//------------------------------------------------------------------------------
+
+namespace xplcommon { namespace win32 {
+
+//------------------------------------------------------------------------------
+
+class ReadingBuffer;
+class WritingBuffer;
+class Overlapped;
+
+//------------------------------------------------------------------------------
+
+/**
+ * A buffered stream.
+ *
+ * It wraps a HANDLE which can be read and/or written with ReadFile or
+ * WriteFile, respectively.
+ */
+class BufferedStream : public Overlappable
+{
+public:
+    /**
+     * The default capacity.
+     */
+    static const size_t DEFAULT_CAPACITY = 4096;
+
+private:
+    /**
+     * The reading buffer. It may be 0, if no reading buffer is
+     * associated with this waitable.
+     */
+    ReadingBuffer* readingBuffer;
+
+    /**
+     * The writing buffer. It may be 0, if no writing buffer is
+     * associated with this waitable.
+     */
+    WritingBuffer* writingBuffer;
+
+protected:
+    /**
+     * Construct the buffered stream.
+     */
+    BufferedStream(Waiter* waiter = 0, HANDLE handle = 0,
+                   size_t readingCapacity = DEFAULT_CAPACITY,
+                   size_t writingCapacity = DEFAULT_CAPACITY);
+
+public:
+    /**
+     * Destroy the stream.
+     */
+    virtual ~BufferedStream();
+
+    /**
+     * Get the reference of the reading buffer. Note, that it can be a
+     * 0 reference, if the stream has no reading buffer.
+     */
+    ReadingBuffer& getReadingBuffer();
+
+    /**
+     * Get the reference of the writing buffer. Note, that it can be a
+     * 0 reference, if the stream has no writing buffer.
+     */
+    WritingBuffer& getWritingBuffer();
+
+protected:
+    /**
+     * Read using the handle at most the given number of bytes into
+     * the given buffer.
+     *
+     * @return the number of bytes read. If 0, it indicates the end of
+     * the file or connection. If negative, it means either a failure,
+     * or the fact that the operation cannot be completed at this time.
+     */
+    ssize_t read(void* dest, size_t length, Overlapped* overlapped);
+
+    /**
+     * Write using the handle the given number of bytes from the given
+     * buffer.
+     *
+     * @return whether the writing succeeded. If false, it is either a
+     * failure, or an inidication of the fact that the operation could
+     * not be completed.
+     */
+    bool write(const void* src, size_t length, Overlapped* overlapped);
+
+    friend class ReadingBuffer;
+    friend class WritingBuffer;
+};
+
+//------------------------------------------------------------------------------
+// Inline definitions
+//------------------------------------------------------------------------------
+
+inline ReadingBuffer& BufferedStream::getReadingBuffer()
+{
+    return *readingBuffer;
+}
+
+//------------------------------------------------------------------------------
+
+inline WritingBuffer& BufferedStream::getWritingBuffer()
+{
+    return *writingBuffer;
+}
+
+//------------------------------------------------------------------------------
+
+} /* namespace xplcommon::win32 */ } /* namespace xplcommon */
+
+//------------------------------------------------------------------------------
+#endif // XPLCOMMON_WIN32_BUFFEREDSTREAM_H
+
+// Local Variables:
+// mode: C++
+// c-basic-offset: 4
+// indent-tabs-mode: nil
+// End:
Index: src/xplcommon/win32/Completer.h
===================================================================
--- src/xplcommon/win32/Completer.h	(revision 21)
+++ src/xplcommon/win32/Completer.h	(revision 21)
@@ -0,0 +1,148 @@
+// Copyright (c) 2012 by István Váradi
+
+// This file is part of libxplcommon, a common utility library for
+// development related to X-Plane
+
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+
+// 1. Redistributions of source code must retain the above copyright notice, this
+//    list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright notice,
+//    this list of conditions and the following disclaimer in the documentation
+//    and/or other materials provided with the distribution.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// The views and conclusions contained in the software and documentation are those
+// of the authors and should not be interpreted as representing official policies,
+// either expressed or implied, of the FreeBSD Project.
+
+#ifndef XPLCOMMON_WIN32_COMPLETER_H
+#define XPLCOMMON_WIN32_COMPLETER_H
+//------------------------------------------------------------------------------
+
+#include "Overlapped.h"
+#include "Overlappable.h"
+
+//------------------------------------------------------------------------------
+
+namespace xplcommon { namespace win32 {
+
+//------------------------------------------------------------------------------
+
+/**
+ * Base class for objects that handle the completion of some
+ * operation. They are associated with an Overlappable, and if that
+ * overlappable is non-blocking (i.e. has a waiter), an Overlapped
+ * object is created and stored in this object.
+ */
+class Completer
+{
+protected:
+    /**
+     * The overlapped object.
+     */
+    Overlapped* overlapped;
+
+protected:
+    /**
+     * Construct the completer for the given Overlappable.
+     */
+    Completer(Overlappable* overlappable);
+
+    /**
+     * Destroy the completer.
+     */
+    ~Completer();
+
+    /**
+     * Add the overlapped object (if any) to the given waiter.
+     */
+    void addTo(Waiter* waiter);
+
+    /**
+     * Remove the overlapped object (if any) from the waiter it is
+     * associated with.
+     */
+    void removeFromWaiter();
+
+    /**
+     * Determine if there is an overlapped object and it is being
+     * waited for.
+     */
+    bool isWaited() const;
+
+    /**
+     * Get the result of the overlapped operation, if any.
+     *
+     * @see Overlapped::getResult
+     */
+    bool getResult(DWORD& size, HANDLE file);
+};
+
+//------------------------------------------------------------------------------
+// Inline definitions
+//------------------------------------------------------------------------------
+
+inline Completer::Completer(Overlappable* overlappable) :
+    overlapped((overlappable->waiter==0) ? 0 : new Overlapped(*overlappable))
+{
+}
+
+//------------------------------------------------------------------------------
+
+inline Completer::~Completer()
+{
+    delete overlapped;
+}
+
+//------------------------------------------------------------------------------
+
+inline void Completer::addTo(Waiter* waiter)
+{
+    if (overlapped!=0 && waiter!=0) overlapped->addTo(*waiter);
+}
+
+//------------------------------------------------------------------------------
+
+inline void Completer::removeFromWaiter()
+{
+    if (overlapped!=0) overlapped->removeFromWaiter();
+}
+
+//------------------------------------------------------------------------------
+
+inline bool Completer::isWaited() const
+{
+    return overlapped!=0 && overlapped->isWaited();
+}
+
+//------------------------------------------------------------------------------
+
+inline bool Completer::getResult(DWORD& size, HANDLE file)
+{
+    return overlapped!=0 && overlapped->getResult(size, file);
+}
+
+//------------------------------------------------------------------------------
+
+} /* namespace xplcommon::win32 */ } /* namespace xplcommon */
+
+//------------------------------------------------------------------------------
+#endif // XPLCOMMON_WIN32_COMPLETER_H
+
+// Local Variables:
+// mode: C++
+// c-basic-offset: 4
+// indent-tabs-mode: nil
+// End:
Index: src/xplcommon/win32/Event.cc
===================================================================
--- src/xplcommon/win32/Event.cc	(revision 20)
+++ src/xplcommon/win32/Event.cc	(revision 21)
@@ -40,4 +40,19 @@
 //------------------------------------------------------------------------------
 
+bool Event::isFired() const
+{
+    DWORD result = WaitForSingleObject(handle, (waiter==0) ? INFINITE : 0);
+    if (result==WAIT_FAILED) {
+        eventFailable.setErrorCode(GetLastError());
+        return false;
+    } else if (result==WAIT_OBJECT_0) {
+        return true;
+    } else {
+        return false;
+    }
+}
+
+//------------------------------------------------------------------------------
+
 void Event::addTo(Waiter& w)
 {
Index: src/xplcommon/win32/Event.h
===================================================================
--- src/xplcommon/win32/Event.h	(revision 20)
+++ src/xplcommon/win32/Event.h	(revision 21)
@@ -32,5 +32,5 @@
 //------------------------------------------------------------------------------
 
-#include "../Failable.h"
+#include "EventFailable.h"
 
 #include <windows.h>
@@ -49,8 +49,13 @@
  * Wrapper for an event.
  */
-class Event : public ::xplcommon::Failable
+class Event
 {
 private:
     /**
+     * The object receiving the failure codes.
+     */
+    EventFailable& eventFailable;
+
+    /**
      * The handle of the event.
      */
@@ -66,5 +71,5 @@
      * Construct the event.
      */
-    Event();
+    Event(EventFailable& eventFailable);
 
     /**
@@ -96,7 +101,18 @@
 
     /**
+     * Determine if the event is being waited for, i.e. it is
+     * associated with a waiter.
+     */
+    bool isWaited() const;
+
+    /**
      * Set the event.
      */
     void fire();
+
+    /**
+     * Determine if the event is fired or not.
+     */
+    bool isFired() const;
 
     /**
@@ -106,4 +122,10 @@
      */
     bool clear();
+
+protected:
+    /**
+     * Set the error code on the failable object.
+     */
+    void setErrorCode(errorCode_t errorCode);
 };
 
@@ -112,9 +134,10 @@
 //------------------------------------------------------------------------------
 
-inline Event::Event() :
+inline Event::Event(EventFailable& eventFailable) :
+    eventFailable(eventFailable),
     handle(CreateEvent(0, true, false, 0)),
     waiter(0)
 {
-    if (handle==0) setErrorCode(GetLastError());
+    if (handle==0) eventFailable.setErrorCode(GetLastError());
 }
 
@@ -143,8 +166,15 @@
 //------------------------------------------------------------------------------
 
+inline bool Event::isWaited() const
+{
+    return waiter!=0;
+}
+
+//------------------------------------------------------------------------------
+
 inline void Event::fire()
 {
     if (!SetEvent(handle)) {
-        setErrorCode(GetLastError());
+        eventFailable.setErrorCode(GetLastError());
     }
 }
@@ -155,9 +185,16 @@
 {
     if (!ResetEvent(handle)) {
-        setErrorCode(GetLastError());
+        eventFailable.setErrorCode(GetLastError());
         return false;
     } else {
         return true;
     }
+}
+
+//------------------------------------------------------------------------------
+
+inline void Event::setErrorCode(errorCode_t errorCode)
+{
+    eventFailable.setErrorCode(errorCode);
 }
 
Index: src/xplcommon/win32/EventFailable.h
===================================================================
--- src/xplcommon/win32/EventFailable.h	(revision 21)
+++ src/xplcommon/win32/EventFailable.h	(revision 21)
@@ -0,0 +1,68 @@
+// Copyright (c) 2012 by István Váradi
+
+// This file is part of libxplcommon, a common utility library for
+// development related to X-Plane
+
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+
+// 1. Redistributions of source code must retain the above copyright notice, this
+//    list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright notice,
+//    this list of conditions and the following disclaimer in the documentation
+//    and/or other materials provided with the distribution.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// The views and conclusions contained in the software and documentation are those
+// of the authors and should not be interpreted as representing official policies,
+// either expressed or implied, of the FreeBSD Project.
+
+#ifndef XPLCOMMON_WIN32_EVENTFAILABLE_H
+#define XPLCOMMON_WIN32_EVENTFAILABLE_H
+//------------------------------------------------------------------------------
+
+#include "../Failable.h"
+
+//------------------------------------------------------------------------------
+
+namespace xplcommon { namespace win32 {
+
+//------------------------------------------------------------------------------
+
+class Event;
+
+//------------------------------------------------------------------------------
+
+/**
+ * A special subclass of Failable, the instances of which can be given
+ * as a Failable target object to events. If some operation on an
+ * event fails, the error code will be set on such an instance,
+ * associated with the event.
+ */
+class EventFailable : public ::xplcommon::Failable
+{
+    friend class Event;
+};
+
+//------------------------------------------------------------------------------
+
+} /* namespace xplcommon::win32 */ } /* namespace xplcommon */
+
+//------------------------------------------------------------------------------
+#endif // XPLCOMMON_WIN32_EVENTFAILABLE_H
+
+// Local Variables:
+// mode: C++
+// c-basic-offset: 4
+// indent-tabs-mode: nil
+// End:
Index: src/xplcommon/win32/LocalAcceptor.cc
===================================================================
--- src/xplcommon/win32/LocalAcceptor.cc	(revision 21)
+++ src/xplcommon/win32/LocalAcceptor.cc	(revision 21)
@@ -0,0 +1,89 @@
+// Copyright (c) 2012 by István Váradi
+
+// This file is part of libxplcommon, a common utility library for
+// development related to X-Plane
+
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+
+// 1. Redistributions of source code must retain the above copyright notice, this
+//    list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright notice,
+//    this list of conditions and the following disclaimer in the documentation
+//    and/or other materials provided with the distribution.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// The views and conclusions contained in the software and documentation are those
+// of the authors and should not be interpreted as representing official policies,
+// either expressed or implied, of the FreeBSD Project.
+
+//------------------------------------------------------------------------------
+
+#include "LocalAcceptor.h"
+
+//------------------------------------------------------------------------------
+
+using xplcommon::win32::LocalAcceptor;
+
+//------------------------------------------------------------------------------
+
+LocalAcceptor::LocalAcceptor(LocalServerSocketBase* socket, const char* name) :
+    Completer(socket),
+    socket(*socket),
+    accepted(false)
+{
+    LocalSocket::setupName(this->name, name);
+}
+
+//------------------------------------------------------------------------------
+
+bool LocalAcceptor::accept()
+{
+    if (accepted) return true;
+
+    if (isWaited()) {
+        DWORD size = 0;
+        if (getResult(size, socket.handle)) {
+            removeFromWaiter();
+            accepted = true;
+            return true;
+        } else {
+            if (socket.failed()) {
+                removeFromWaiter();
+            }
+            return false;
+        }
+    }
+
+
+    if (!socket.createNamedPipe(name)) {
+        return false;
+    }
+
+    bool result = socket.connectNamedPipe(overlapped);
+    if (result) {
+        accepted = true;
+    } else if (!socket.failed()) {
+        addTo(socket.waiter);
+    }
+
+    return result;
+}
+
+//------------------------------------------------------------------------------
+
+// Local Variables:
+// mode: C++
+// c-basic-offset: 4
+// indent-tabs-mode: nil
+// End:
Index: src/xplcommon/win32/LocalAcceptor.h
===================================================================
--- src/xplcommon/win32/LocalAcceptor.h	(revision 21)
+++ src/xplcommon/win32/LocalAcceptor.h	(revision 21)
@@ -0,0 +1,168 @@
+// Copyright (c) 2012 by István Váradi
+
+// This file is part of libxplcommon, a common utility library for
+// development related to X-Plane
+
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+
+// 1. Redistributions of source code must retain the above copyright notice, this
+//    list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright notice,
+//    this list of conditions and the following disclaimer in the documentation
+//    and/or other materials provided with the distribution.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// The views and conclusions contained in the software and documentation are those
+// of the authors and should not be interpreted as representing official policies,
+// either expressed or implied, of the FreeBSD Project.
+
+#ifndef XPLCOMMON_WIN32_LOCALACCEPTOR_H
+#define XPLCOMMON_WIN32_LOCALACCEPTOR_H
+//------------------------------------------------------------------------------
+
+#include "Completer.h"
+
+#include "LocalServerSocketBase.h"
+#include "LocalSocket.h"
+
+//------------------------------------------------------------------------------
+
+namespace xplcommon { namespace win32 {
+
+//------------------------------------------------------------------------------
+
+/**
+ * Instances of this class are used to accept connection requests to a
+ * local server socket, i.e. named pipe.
+ */
+class LocalAcceptor : public Completer,
+                      public FailableReference<LocalAcceptor>
+{
+private:
+    /**
+     * The local server socket for which we are accepting connections.
+     */
+    LocalServerSocketBase& socket;
+
+    /**
+     * The name of the pipe to accept.
+     */
+    char name[256];
+
+    /**
+     * Indicate if the connection has been accepted.
+     */
+    bool accepted;
+
+protected:
+    /**
+     * Construct the acceptor.
+     */
+    LocalAcceptor(LocalServerSocketBase* socket, const char* name);
+
+public:
+    /**
+     * Try to accept a connection.
+     *
+     * If one is already accepted, but not retrieved yet, return true.
+     *
+     * If a new connection becomes immediately available, return true.
+     *
+     * If a new connection is not yet available, returns false.
+     *
+     * If some error occurs, the acceptor is marked failed and false
+     * is returned.
+     */
+    bool accept();
+
+    /**
+     * Get the local socket accepted last. If no socket was accepted,
+     * return 0. The local socket's waiter will be the given one.
+     */
+    LocalSocket* getSocket(Waiter* waiter,
+                           size_t readingCapacity = LocalSocket::DEFAULT_CAPACITY,
+                           size_t writingCapacity = LocalSocket::DEFAULT_CAPACITY);
+    /**
+     * Get the local socket accepted last. If no socket was accepted,
+     * return 0. The local socket's waiter will be the same as that of
+     * the associated server socket.
+     */
+    LocalSocket* getSocket(size_t readingCapacity = LocalSocket::DEFAULT_CAPACITY,
+                           size_t writingCapacity = LocalSocket::DEFAULT_CAPACITY);
+
+
+private:
+    /**
+     * Get the failable object.
+     */
+    const ::xplcommon::Failable& getFailable() const;
+
+    /**
+     * Get the failable object.
+     */
+    ::xplcommon::Failable& getFailable();
+
+    friend class FailableReference<LocalAcceptor>;
+    friend class LocalServerSocket;
+};
+
+//------------------------------------------------------------------------------
+// Inline definitions
+//------------------------------------------------------------------------------
+
+inline LocalSocket* LocalAcceptor::getSocket(Waiter* waiter,
+                                             size_t readingCapacity,
+                                             size_t writingCapacity)
+{
+    if (!accepted) return 0;
+
+    LocalSocket* s= new LocalSocket(waiter, socket.releaseHandle(),
+                                    readingCapacity, writingCapacity);
+    accepted = false;
+    return s;
+}
+//------------------------------------------------------------------------------
+
+inline LocalSocket* LocalAcceptor::getSocket(size_t readingCapacity,
+                                             size_t writingCapacity)
+{
+    return getSocket(socket.waiter, readingCapacity, writingCapacity);
+}
+
+//------------------------------------------------------------------------------
+
+inline const ::xplcommon::Failable& LocalAcceptor::getFailable() const
+{
+    return socket;
+}
+
+//------------------------------------------------------------------------------
+
+inline ::xplcommon::Failable& LocalAcceptor::getFailable()
+{
+    return socket;
+}
+
+//------------------------------------------------------------------------------
+
+} /* namespace xplcommon::win32 */ } /* namespace xplcommon */
+
+//------------------------------------------------------------------------------
+#endif // XPLCOMMON_WIN32_LOCALACCEPTOR_H
+
+// Local Variables:
+// mode: C++
+// c-basic-offset: 4
+// indent-tabs-mode: nil
+// End:
Index: src/xplcommon/win32/LocalClientSocket.cc
===================================================================
--- src/xplcommon/win32/LocalClientSocket.cc	(revision 21)
+++ src/xplcommon/win32/LocalClientSocket.cc	(revision 21)
@@ -0,0 +1,56 @@
+// Copyright (c) 2012 by István Váradi
+
+// This file is part of libxplcommon, a common utility library for
+// development related to X-Plane
+
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+
+// 1. Redistributions of source code must retain the above copyright notice, this
+//    list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright notice,
+//    this list of conditions and the following disclaimer in the documentation
+//    and/or other materials provided with the distribution.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// The views and conclusions contained in the software and documentation are those
+// of the authors and should not be interpreted as representing official policies,
+// either expressed or implied, of the FreeBSD Project.
+
+//------------------------------------------------------------------------------
+
+#include "LocalClientSocket.h"
+
+//------------------------------------------------------------------------------
+
+using xplcommon::win32::LocalClientSocket;
+
+//------------------------------------------------------------------------------
+
+HANDLE LocalClientSocket::create(const char* name, bool overlapped)
+{
+    char buf[256];
+    setupName(buf, name);
+
+    return CreateFile(buf, GENERIC_READ|GENERIC_WRITE,
+                      0, 0, OPEN_EXISTING,
+                      FILE_FLAG_NO_BUFFERING | FILE_FLAG_OVERLAPPED, 0);
+}
+
+//------------------------------------------------------------------------------
+
+// Local Variables:
+// mode: C++
+// c-basic-offset: 4
+// indent-tabs-mode: nil
+// End:
Index: src/xplcommon/win32/LocalClientSocket.h
===================================================================
--- src/xplcommon/win32/LocalClientSocket.h	(revision 21)
+++ src/xplcommon/win32/LocalClientSocket.h	(revision 21)
@@ -0,0 +1,106 @@
+// Copyright (c) 2012 by István Váradi
+
+// This file is part of libxplcommon, a common utility library for
+// development related to X-Plane
+
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+
+// 1. Redistributions of source code must retain the above copyright notice, this
+//    list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright notice,
+//    this list of conditions and the following disclaimer in the documentation
+//    and/or other materials provided with the distribution.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// The views and conclusions contained in the software and documentation are those
+// of the authors and should not be interpreted as representing official policies,
+// either expressed or implied, of the FreeBSD Project.
+
+#ifndef XPLCOMMON_WIN32_LOCALCLIENTSOCKET_H
+#define XPLCOMMON_WIN32_LOCALCLIENTSOCKET_H
+//------------------------------------------------------------------------------
+
+#include "LocalConnector.h"
+
+//------------------------------------------------------------------------------
+
+namespace xplcommon { namespace win32 {
+
+//------------------------------------------------------------------------------
+
+/**
+ * A client socket that connects to a named server socket locally,
+ * i.e. a named pipe.
+ *
+ * The server socket's name should be given. The name will be used as
+ * described for LocalServerSocket.
+ */
+class LocalClientSocket : public LocalSocket
+{
+private:
+    /**
+     * Create a named pipe for the given user-specified name.
+     */
+    static HANDLE create(const char* name, bool overlapped);
+
+    /**
+     * The local connector.
+     */
+    LocalConnector connector;
+
+public:
+    /**
+     * Construct the client socket with the given name.
+     */
+    LocalClientSocket(const char* name, Waiter* waiter = 0,
+                      size_t readingCapacity = DEFAULT_CAPACITY,
+                      size_t writingCapacity = DEFAULT_CAPACITY);
+
+    /**
+     * Get the connector.
+     */
+    LocalConnector& getConnector();
+};
+
+//------------------------------------------------------------------------------
+// Inline definitions
+//------------------------------------------------------------------------------
+
+inline LocalClientSocket::LocalClientSocket(const char* name, Waiter* waiter,
+                                            size_t readingCapacity,
+                                            size_t writingCapacity) :
+    LocalSocket(waiter, 0, readingCapacity, writingCapacity),
+    connector(this, name)
+{
+}
+
+//------------------------------------------------------------------------------
+
+inline LocalConnector& LocalClientSocket::getConnector()
+{
+    return connector;
+}
+
+//------------------------------------------------------------------------------
+
+} /* namespace xplcommon::win32 */ } /* namespace xplcommon */
+
+//------------------------------------------------------------------------------
+#endif // XPLCOMMON_WIN32_LOCALCLIENTSOCKET_H
+
+// Local Variables:
+// mode: C++
+// c-basic-offset: 4
+// indent-tabs-mode: nil
+// End:
Index: src/xplcommon/win32/LocalConnector.cc
===================================================================
--- src/xplcommon/win32/LocalConnector.cc	(revision 21)
+++ src/xplcommon/win32/LocalConnector.cc	(revision 21)
@@ -0,0 +1,71 @@
+// Copyright (c) 2012 by István Váradi
+
+// This file is part of libxplcommon, a common utility library for
+// development related to X-Plane
+
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+
+// 1. Redistributions of source code must retain the above copyright notice, this
+//    list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright notice,
+//    this list of conditions and the following disclaimer in the documentation
+//    and/or other materials provided with the distribution.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// The views and conclusions contained in the software and documentation are those
+// of the authors and should not be interpreted as representing official policies,
+// either expressed or implied, of the FreeBSD Project.
+
+//------------------------------------------------------------------------------
+
+#include "LocalConnector.h"
+
+#include <cstdio>
+
+//------------------------------------------------------------------------------
+
+using xplcommon::win32::LocalConnector;
+
+//------------------------------------------------------------------------------
+
+bool LocalConnector::connect()
+{
+    printf("LocalConnector::connect0\n");
+    if (connected) return true;
+
+    printf("LocalConnector::connect3\n");
+
+    HANDLE handle = CreateFile(name, GENERIC_READ|GENERIC_WRITE,
+                               0, 0, OPEN_EXISTING,
+                               FILE_FLAG_NO_BUFFERING | FILE_FLAG_OVERLAPPED, 0);
+    printf("LocalConnector::connect4\n");
+    if (handle!=0) {
+        printf("LocalConnector::connect5\n");
+        socket.handle = handle;
+        connected = true;
+        return true;
+    } else {
+        printf("LocalConnector::connect6\n");
+        socket.setErrorCode(GetLastError());
+        return false;
+    }
+}
+
+//------------------------------------------------------------------------------
+
+// Local Variables:
+// mode: C++
+// c-basic-offset: 4
+// indent-tabs-mode: nil
+// End:
Index: src/xplcommon/win32/LocalConnector.h
===================================================================
--- src/xplcommon/win32/LocalConnector.h	(revision 21)
+++ src/xplcommon/win32/LocalConnector.h	(revision 21)
@@ -0,0 +1,135 @@
+// Copyright (c) 2012 by István Váradi
+
+// This file is part of libxplcommon, a common utility library for
+// development related to X-Plane
+
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+
+// 1. Redistributions of source code must retain the above copyright notice, this
+//    list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright notice,
+//    this list of conditions and the following disclaimer in the documentation
+//    and/or other materials provided with the distribution.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// The views and conclusions contained in the software and documentation are those
+// of the authors and should not be interpreted as representing official policies,
+// either expressed or implied, of the FreeBSD Project.
+
+#ifndef XPLCOMMON_WIN32_LOCALCONNECTOR_H
+#define XPLCOMMON_WIN32_LOCALCONNECTOR_H
+//------------------------------------------------------------------------------
+
+#include "Completer.h"
+
+#include "LocalSocket.h"
+
+//------------------------------------------------------------------------------
+
+namespace xplcommon { namespace win32 {
+
+//------------------------------------------------------------------------------
+
+class LocalConnector : public FailableReference<LocalConnector>
+{
+private:
+    /**
+     * The local socket to connect on behalf of which (it should
+     * actually be a LocalClientSocket.
+     */
+    LocalSocket& socket;
+
+    /**
+     * The name of the pipe to connect to.
+     */
+    char name[256];
+
+    /**
+     * Indicate if we are connected.
+     */
+    bool connected;
+
+protected:
+    /**
+     * Construct the connector.
+     */
+    LocalConnector(LocalSocket* socket, const char* name);
+
+public:
+    /**
+     * Connect to an address properly set up.
+     *
+     * If the connection succeeds immediately, it indicates success.
+     *
+     * If the connection does not succeed, because it would block, it
+     * sets up the socket to wait for the connection to succeed, and
+     * returns failure.
+     *
+     * If the connection fails for another reason, the error code is
+     * set, and false is returned.
+     */
+    bool connect();
+
+private:
+    /**
+     * Get the failable object.
+     */
+    const ::xplcommon::Failable& getFailable() const;
+
+    /**
+     * Get the failable object.
+     */
+    ::xplcommon::Failable& getFailable();
+
+    friend class FailableReference<LocalConnector>;
+    friend class LocalClientSocket;
+};
+
+//------------------------------------------------------------------------------
+// Inline definitions
+//------------------------------------------------------------------------------
+
+inline LocalConnector::LocalConnector(LocalSocket* socket, const char* name) :
+    socket(*socket),
+    connected(false)
+{
+    LocalSocket::setupName(this->name, name);
+}
+
+//------------------------------------------------------------------------------
+
+inline const ::xplcommon::Failable& LocalConnector::getFailable() const
+{
+    return socket;
+}
+
+//------------------------------------------------------------------------------
+
+inline ::xplcommon::Failable& LocalConnector::getFailable()
+{
+    return socket;
+}
+
+//------------------------------------------------------------------------------
+
+} /* namespace xplcommon::win32 */ } /* namespace xplcommon */
+
+//------------------------------------------------------------------------------
+#endif // XPLCOMMON_WIN32_LOCALCONNECTOR_H
+
+// Local Variables:
+// mode: C++
+// c-basic-offset: 4
+// indent-tabs-mode: nil
+// End:
Index: src/xplcommon/win32/LocalServerSocket.h
===================================================================
--- src/xplcommon/win32/LocalServerSocket.h	(revision 21)
+++ src/xplcommon/win32/LocalServerSocket.h	(revision 21)
@@ -0,0 +1,98 @@
+// Copyright (c) 2012 by István Váradi
+
+// This file is part of libxplcommon, a common utility library for
+// development related to X-Plane
+
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+
+// 1. Redistributions of source code must retain the above copyright notice, this
+//    list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright notice,
+//    this list of conditions and the following disclaimer in the documentation
+//    and/or other materials provided with the distribution.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// The views and conclusions contained in the software and documentation are those
+// of the authors and should not be interpreted as representing official policies,
+// either expressed or implied, of the FreeBSD Project.
+
+#ifndef XPLCOMMON_WIN32_LOCALSERVERSOCKET_H
+#define XPLCOMMON_WIN32_LOCALSERVERSOCKET_H
+//------------------------------------------------------------------------------
+
+#include "LocalServerSocketBase.h"
+
+#include "LocalAcceptor.h"
+
+//------------------------------------------------------------------------------
+
+namespace xplcommon { namespace win32 {
+
+//------------------------------------------------------------------------------
+
+/**
+ * A server socket that works locally, i.e. a named pipe.
+ *
+ * It is identified by a name that should be unique for a user. The
+ * actual pipe will be created with the name \\.\pipe\<name>.
+ */
+class LocalServerSocket : public LocalServerSocketBase
+{
+private:
+    /**
+     * The acceptor to use.
+     */
+    LocalAcceptor acceptor;
+
+public:
+    /**
+     * Construct the socket.
+     */
+    LocalServerSocket(const char* name, Waiter* waiter = 0);
+
+    /**
+     * Get the acceptor.
+     */
+    LocalAcceptor& getAcceptor();
+};
+
+//------------------------------------------------------------------------------
+// Inline definitions
+//------------------------------------------------------------------------------
+
+inline LocalServerSocket::LocalServerSocket(const char* name, Waiter* waiter) :
+    LocalServerSocketBase(waiter),
+    acceptor(this, name)
+{
+}
+
+//------------------------------------------------------------------------------
+
+inline LocalAcceptor& LocalServerSocket::getAcceptor()
+{
+    return acceptor;
+}
+
+//------------------------------------------------------------------------------
+
+} /* namespace xplcommon::win32 */ } /* namespace xplcommon */
+
+//------------------------------------------------------------------------------
+#endif // XPLCOMMON_WIN32_LOCALSERVERSOCKET_H
+
+// Local Variables:
+// mode: C++
+// c-basic-offset: 4
+// indent-tabs-mode: nil
+// End:
Index: src/xplcommon/win32/LocalServerSocketBase.cc
===================================================================
--- src/xplcommon/win32/LocalServerSocketBase.cc	(revision 21)
+++ src/xplcommon/win32/LocalServerSocketBase.cc	(revision 21)
@@ -0,0 +1,83 @@
+// Copyright (c) 2012 by István Váradi
+
+// This file is part of libxplcommon, a common utility library for
+// development related to X-Plane
+
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+
+// 1. Redistributions of source code must retain the above copyright notice, this
+//    list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright notice,
+//    this list of conditions and the following disclaimer in the documentation
+//    and/or other materials provided with the distribution.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// The views and conclusions contained in the software and documentation are those
+// of the authors and should not be interpreted as representing official policies,
+// either expressed or implied, of the FreeBSD Project.
+
+//------------------------------------------------------------------------------
+
+#include "LocalServerSocketBase.h"
+
+#include "LocalSocket.h"
+
+//------------------------------------------------------------------------------
+
+using xplcommon::win32::LocalServerSocketBase;
+
+//------------------------------------------------------------------------------
+
+bool LocalServerSocketBase::createNamedPipe(const char* name)
+{
+    handle = CreateNamedPipe(name, PIPE_ACCESS_DUPLEX |
+                             ((waiter==0) ? 0 : FILE_FLAG_OVERLAPPED),
+                             PIPE_TYPE_BYTE | PIPE_READMODE_BYTE,
+                             PIPE_UNLIMITED_INSTANCES,
+                             BufferedStream::DEFAULT_CAPACITY,
+                             BufferedStream::DEFAULT_CAPACITY,
+                             0, 0);
+    if (handle==0) {
+        setErrorCode(GetLastError());
+    }
+    return handle!=0;
+}
+
+//------------------------------------------------------------------------------
+
+bool LocalServerSocketBase::connectNamedPipe(Overlapped* overlapped)
+{
+    bool result = LocalSocket::connectNamedPipe(handle, overlapped);
+    if (!result && overlapped==0) {
+        setErrorCode(GetLastError());
+    }
+    return result;
+}
+
+//------------------------------------------------------------------------------
+
+HANDLE LocalServerSocketBase::releaseHandle()
+{
+    HANDLE h = handle;
+    handle = 0;
+    return h;
+}
+
+//------------------------------------------------------------------------------
+
+// Local Variables:
+// mode: C++
+// c-basic-offset: 4
+// indent-tabs-mode: nil
+// End:
Index: src/xplcommon/win32/LocalServerSocketBase.h
===================================================================
--- src/xplcommon/win32/LocalServerSocketBase.h	(revision 21)
+++ src/xplcommon/win32/LocalServerSocketBase.h	(revision 21)
@@ -0,0 +1,106 @@
+// Copyright (c) 2012 by István Váradi
+
+// This file is part of libxplcommon, a common utility library for
+// development related to X-Plane
+
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+
+// 1. Redistributions of source code must retain the above copyright notice, this
+//    list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright notice,
+//    this list of conditions and the following disclaimer in the documentation
+//    and/or other materials provided with the distribution.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// The views and conclusions contained in the software and documentation are those
+// of the authors and should not be interpreted as representing official policies,
+// either expressed or implied, of the FreeBSD Project.
+
+#ifndef XPLCOMMON_WIN32_LOCALSERVERSOCKETBASE_H
+#define XPLCOMMON_WIN32_LOCALSERVERSOCKETBASE_H
+//------------------------------------------------------------------------------
+
+#include "Overlappable.h"
+
+//------------------------------------------------------------------------------
+
+namespace xplcommon { namespace win32 {
+
+//------------------------------------------------------------------------------
+
+class Overlapped;
+
+//------------------------------------------------------------------------------
+
+/**
+ * Base class for a local server socket. This is here only to allow
+ * for a more efficient implementation of LocalAcceptor.
+ */
+class LocalServerSocketBase : public Overlappable
+{
+protected:
+    /**
+     * Construct the server socket base.
+     */
+    LocalServerSocketBase(Waiter* waiter);
+
+    /**
+     * Create a new named pipe with the proper settings. The handle of
+     * this object will be set to the created handle.
+     *
+     * @param name the name of the pipe to create. It should be the
+     * final name, not the user-given one.
+     *
+     * @return whether the pipe could be created
+     */
+    bool createNamedPipe(const char* name);
+
+    /**
+     * Connect the named pipe with the current handle of this object.
+     *
+     * @return whether the connection succeeded. If not, it may be a
+     * failure, which is then indicated, or it may be an overlapped
+     * operation which needs to wait.
+     */
+    bool connectNamedPipe(Overlapped* overlapped);
+
+    /**
+     * Get the handle and clear it.
+     */
+    HANDLE releaseHandle();
+
+    friend class LocalAcceptor;
+};
+
+//------------------------------------------------------------------------------
+// Inline definitions
+//------------------------------------------------------------------------------
+
+inline LocalServerSocketBase::LocalServerSocketBase(Waiter* waiter) :
+    Overlappable(waiter)
+{
+}
+
+//------------------------------------------------------------------------------
+
+} /* namespace xplcommon::win32 */ } /* namespace xplcommon */
+
+//------------------------------------------------------------------------------
+#endif // XPLCOMMON_WIN32_LOCALSERVERSOCKETBASE_H
+
+// Local Variables:
+// mode: C++
+// c-basic-offset: 4
+// indent-tabs-mode: nil
+// End:
Index: src/xplcommon/win32/LocalSocket.h
===================================================================
--- src/xplcommon/win32/LocalSocket.h	(revision 21)
+++ src/xplcommon/win32/LocalSocket.h	(revision 21)
@@ -0,0 +1,156 @@
+// Copyright (c) 2012 by István Váradi
+
+// This file is part of libxplcommon, a common utility library for
+// development related to X-Plane
+
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+
+// 1. Redistributions of source code must retain the above copyright notice, this
+//    list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright notice,
+//    this list of conditions and the following disclaimer in the documentation
+//    and/or other materials provided with the distribution.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// The views and conclusions contained in the software and documentation are those
+// of the authors and should not be interpreted as representing official policies,
+// either expressed or implied, of the FreeBSD Project.
+
+#ifndef XPLCOMMON_WIN32_LOCALSOCKET_H
+#define XPLCOMMON_WIN32_LOCALSOCKET_H
+//------------------------------------------------------------------------------
+
+#include "BufferedStream.h"
+
+#include "Overlapped.h"
+
+#include <cstdio>
+
+//------------------------------------------------------------------------------
+
+namespace xplcommon { namespace win32 {
+
+//------------------------------------------------------------------------------
+
+/**
+ * Basically a different name for a buffered stream.
+ */
+class LocalSocket : public BufferedStream
+{
+public:
+    /**
+     * Create a concrete pipe name from the given user-specified name.
+     *
+     * @param dest the destination buffer, which should be at least
+     * 256 bytes long.
+     */
+    static void setupName(char* dest, const char* name);
+
+    /**
+     * Create a new named pipe with the proper settings. The handle
+     * will be returned on successful creation.
+     *
+     * @param name the name of the pipe to create. It should be the
+     * final name, not the user-given one.
+     *
+     * @return the handle if the pipe could be created.
+     */
+    static HANDLE createNamedPipe(const char* name, bool overlapped);
+
+    /**
+     * Connect the named pipe with the given handle.
+     *
+     * @return true if the connection is established. If overlapped is
+     * 0 and false is returned, it has failed. If overlapped is not 0,
+     * the failer status of the Failable associated with the
+     * Overlapped instance provides failure information.
+     */
+    static bool connectNamedPipe(HANDLE handle, Overlapped* overlapped);
+
+protected:
+    /**
+     * Construct the local socket
+     */
+    LocalSocket(Waiter* waiter = 0, HANDLE handle = 0,
+                size_t readingCapacity = DEFAULT_CAPACITY,
+                size_t writingCapacity = DEFAULT_CAPACITY);
+
+
+protected:
+    /**
+     * Connect the named pipe with the current handle of this object.
+     *
+     * @return whether the connection succeeded. If not, it may be a
+     * failure, which is then indicated, or it may be an overlapped
+     * operation which needs to wait.
+     */
+    bool connect(Overlapped* overlapped);
+
+    friend class LocalAcceptor;
+    friend class LocalConnector;
+};
+
+//------------------------------------------------------------------------------
+// Inline definitions
+//------------------------------------------------------------------------------
+
+inline void LocalSocket::setupName(char* dest, const char* name)
+{
+    snprintf(dest, 256, "\\\\.\\pipe\\%s", name);
+}
+
+//------------------------------------------------------------------------------
+
+inline bool LocalSocket::connectNamedPipe(HANDLE handle, Overlapped* overlapped)
+{
+    OVERLAPPED* ol = (overlapped==0) ? 0 : overlapped->get();
+    bool result = ConnectNamedPipe(handle, ol);
+    if (overlapped!=0) {
+        DWORD dummy = 0;
+        result = overlapped->getResult(dummy, handle);
+    }
+    return result;
+}
+
+//------------------------------------------------------------------------------
+
+inline LocalSocket::LocalSocket(Waiter* waiter, HANDLE handle,
+                                size_t readingCapacity, size_t writingCapacity):
+    BufferedStream(waiter, handle, readingCapacity, writingCapacity)
+{
+}
+
+//------------------------------------------------------------------------------
+
+inline bool LocalSocket::connect(Overlapped* overlapped)
+{
+    bool result = connectNamedPipe(handle, overlapped);
+    if (!result && overlapped==0) {
+        setErrorCode(GetLastError());
+    }
+    return result;
+}
+
+//------------------------------------------------------------------------------
+
+} /* namespace xplcommon::win32 */ } /* namespace xplcommon */
+
+//------------------------------------------------------------------------------
+#endif // XPLCOMMON_WIN32_LOCALSOCKET_H
+
+// Local Variables:
+// mode: C++
+// c-basic-offset: 4
+// indent-tabs-mode: nil
+// End:
Index: src/xplcommon/win32/Makefile.am
===================================================================
--- src/xplcommon/win32/Makefile.am	(revision 20)
+++ src/xplcommon/win32/Makefile.am	(revision 21)
@@ -6,11 +6,30 @@
 	Overlapped.cc		\
 	Waiter.cc		\
-	WaitableEvent.cc
+	BufferedStream.cc	\
+	ReadingBuffer.cc	\
+	WritingBuffer.cc	\
+	LocalAcceptor.cc	\
+	LocalServerSocketBase.cc\
+	LocalConnector.cc	\
+	LocalClientSocket.cc
 
 include_xplcommon_win32dir=$(includedir)/xplcommon/win32
 include_xplcommon_win32_HEADERS=\
 	Thread.h		\
+	EventFailable.h		\
 	Event.h			\
 	Overlapped.h		\
 	Waiter.h		\
-	WaitableEvent.h
+	WaitableEvent.h		\
+	Overlappable.h		\
+	Completer.h		\
+	StreamBuffer.h		\
+	BufferedStream.h	\
+	ReadingBuffer.h		\
+	WritingBuffer.h		\
+	LocalSocket.h		\
+	LocalAcceptor.h		\
+	LocalServerSocketBase.h	\
+	LocalServerSocket.h	\
+	LocalConnector.h	\
+	LocalClientSocket.h
Index: src/xplcommon/win32/Overlappable.h
===================================================================
--- src/xplcommon/win32/Overlappable.h	(revision 21)
+++ src/xplcommon/win32/Overlappable.h	(revision 21)
@@ -0,0 +1,133 @@
+// Copyright (c) 2012 by István Váradi
+
+// This file is part of libxplcommon, a common utility library for
+// development related to X-Plane
+
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+
+// 1. Redistributions of source code must retain the above copyright notice, this
+//    list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright notice,
+//    this list of conditions and the following disclaimer in the documentation
+//    and/or other materials provided with the distribution.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// The views and conclusions contained in the software and documentation are those
+// of the authors and should not be interpreted as representing official policies,
+// either expressed or implied, of the FreeBSD Project.
+
+#ifndef XPLCOMMON_WIN32_OVERLAPPABLE_H
+#define XPLCOMMON_WIN32_OVERLAPPABLE_H
+//------------------------------------------------------------------------------
+
+#include "EventFailable.h"
+
+#include <windows.h>
+
+//------------------------------------------------------------------------------
+
+namespace xplcommon { namespace win32 {
+
+//------------------------------------------------------------------------------
+
+class Waiter;
+
+//------------------------------------------------------------------------------
+
+/**
+ * Base class for classes that maintain a handle and may be subject to
+ * overlapped I/O operations whose completion is waited for in a
+ * Waiter.
+ */
+class Overlappable : public EventFailable
+{
+protected:
+    /**
+     * The waiter to be used for waiting for events.
+     */
+    Waiter* waiter;
+
+    /**
+     * The handle to use.
+     */
+    HANDLE handle;
+
+protected:
+    /**
+     * Construct the object.
+     */
+    Overlappable(Waiter* waiter = 0, HANDLE handle = 0);
+
+public:
+    /**
+     * Destroy the object.
+     */
+    virtual ~Overlappable();
+
+    /**
+     * Get the waiter.
+     */
+    Waiter* getWaiter();
+
+    /**
+     * Determine if the overlappable has a waiter.
+     */
+    bool hasWaiter() const;
+
+    friend class Completer;
+};
+
+//------------------------------------------------------------------------------
+// Inline definitions
+//------------------------------------------------------------------------------
+
+inline Overlappable::Overlappable(Waiter* waiter, HANDLE handle) :
+    waiter(waiter),
+    handle(handle)
+{
+}
+
+//------------------------------------------------------------------------------
+
+inline Overlappable::~Overlappable()
+{
+    if (handle!=0) CloseHandle(handle);
+}
+
+//------------------------------------------------------------------------------
+
+inline Waiter* Overlappable::getWaiter()
+{
+    return waiter;
+}
+
+//------------------------------------------------------------------------------
+
+inline bool Overlappable::hasWaiter() const
+{
+    return waiter != 0;
+}
+
+//------------------------------------------------------------------------------
+
+} /* namespace xplcommon::win32 */ } /* namespace xplcommon */
+
+//------------------------------------------------------------------------------
+#endif // XPLCOMMON_WIN32_OVERLAPPABLE_H
+
+// Local Variables:
+// mode: C++
+// c-basic-offset: 4
+// indent-tabs-mode: nil
+// End:
Index: src/xplcommon/win32/Overlapped.cc
===================================================================
--- src/xplcommon/win32/Overlapped.cc	(revision 20)
+++ src/xplcommon/win32/Overlapped.cc	(revision 21)
@@ -46,4 +46,21 @@
 //------------------------------------------------------------------------------
 
+bool Overlapped::getResult(DWORD& size, HANDLE file)
+{
+    bool result = GetOverlappedResult(file, &overlapped, &size, FALSE);
+    if (!result) {
+        DWORD error = GetLastError();
+        if (error!=ERROR_IO_PENDING && error!=ERROR_IO_INCOMPLETE) {
+            reset();
+            setErrorCode(error);
+        }
+    } else {
+        reset();
+    }
+    return result;
+}
+
+//------------------------------------------------------------------------------
+
 // Local Variables:
 // mode: C++
Index: src/xplcommon/win32/Overlapped.h
===================================================================
--- src/xplcommon/win32/Overlapped.h	(revision 20)
+++ src/xplcommon/win32/Overlapped.h	(revision 21)
@@ -59,5 +59,5 @@
      * 0, and the event handle will be set.
      */
-    Overlapped();
+    Overlapped(EventFailable& eventFailable);
 
     /**
@@ -75,4 +75,20 @@
      */
     const OVERLAPPED* get() const;
+
+    /**
+     * Get the result of the overlapped operation.
+     *
+     * If the operation has completed, the event will be cleared.
+     *
+     * @param size on successful return, it will contain the number of
+     * bytes read or written, which may be 0 for an end-of-file
+     * condition
+     * @param file the handle of the file on which the operation in
+     * question was performed
+     *
+     * @return true if the operation has completed, or false if it has
+     * not, or a failure has occured.
+     */
+    bool getResult(DWORD& size, HANDLE file);
 };
 
@@ -81,5 +97,6 @@
 //------------------------------------------------------------------------------
 
-inline Overlapped::Overlapped()
+inline Overlapped::Overlapped(EventFailable& eventFailable) :
+    Event(eventFailable)
 {
     reset();
Index: src/xplcommon/win32/ReadingBuffer.cc
===================================================================
--- src/xplcommon/win32/ReadingBuffer.cc	(revision 21)
+++ src/xplcommon/win32/ReadingBuffer.cc	(revision 21)
@@ -0,0 +1,86 @@
+// Copyright (c) 2012 by István Váradi
+
+// This file is part of libxplcommon, a common utility library for
+// development related to X-Plane
+
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+
+// 1. Redistributions of source code must retain the above copyright notice, this
+//    list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright notice,
+//    this list of conditions and the following disclaimer in the documentation
+//    and/or other materials provided with the distribution.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// The views and conclusions contained in the software and documentation are those
+// of the authors and should not be interpreted as representing official policies,
+// either expressed or implied, of the FreeBSD Project.
+
+//------------------------------------------------------------------------------
+
+#include "ReadingBuffer.h"
+
+#include <cstdio>
+
+//------------------------------------------------------------------------------
+
+using xplcommon::win32::ReadingBuffer;
+
+//------------------------------------------------------------------------------
+
+bool ReadingBuffer::read()
+{
+    if (failed()) return false;
+
+    if (getLength()>0) {
+        return true;
+    }
+
+    if (isWaited()) {
+        DWORD size = 0;
+        if (getResult(size, stream.handle)) {
+            removeFromWaiter();
+            overlapped->clear();
+            addLength(size);
+            return true;
+        } else {
+            if (stream.failed()) {
+                overlapped->clear();
+                removeFromWaiter();
+            }
+            return false;
+        }
+    }
+
+    ssize_t result = stream.read(getData(), getCapacity(), overlapped);
+    if (result<0) {
+        if (!stream.failed()) {
+            addTo(stream.getWaiter());
+        } else {
+            overlapped->reset();
+        }
+    } else {
+        overlapped->reset();
+        addLength(result);
+    }
+    return result>=0;
+}
+
+//------------------------------------------------------------------------------
+
+// Local Variables:
+// mode: C++
+// c-basic-offset: 4
+// indent-tabs-mode: nil
+// End:
Index: src/xplcommon/win32/ReadingBuffer.h
===================================================================
--- src/xplcommon/win32/ReadingBuffer.h	(revision 21)
+++ src/xplcommon/win32/ReadingBuffer.h	(revision 21)
@@ -0,0 +1,102 @@
+// Copyright (c) 2012 by István Váradi
+
+// This file is part of libxplcommon, a common utility library for
+// development related to X-Plane
+
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+
+// 1. Redistributions of source code must retain the above copyright notice, this
+//    list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright notice,
+//    this list of conditions and the following disclaimer in the documentation
+//    and/or other materials provided with the distribution.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// The views and conclusions contained in the software and documentation are those
+// of the authors and should not be interpreted as representing official policies,
+// either expressed or implied, of the FreeBSD Project.
+
+#ifndef XPLCOMMON_WIN32_READINGBUFFER_H
+#define XPLCOMMON_WIN32_READINGBUFFER_H
+//------------------------------------------------------------------------------
+
+#include "StreamBuffer.h"
+
+//------------------------------------------------------------------------------
+
+namespace xplcommon { namespace win32 {
+
+//------------------------------------------------------------------------------
+
+/**
+ * A buffer used for reading from a stream buffer.
+ *
+ * It should be made empty, and then the function read() should be
+ * called on it. If it returns true, some data could be read. If the
+ * amount of data in the buffer is then 0, that indicates and
+ * end-of-file condition.
+ */
+class ReadingBuffer : public StreamBuffer
+{
+protected:
+    /**
+     * Construct the buffer.
+     */
+    ReadingBuffer(size_t capacity, BufferedStream* stream);
+
+public:
+    /**
+     * Read into the buffer using the buffered stream if possible.
+     *
+     * If the buffer contains data, this function returns immediately
+     * with success, so the buffer should be reset before reading.
+     *
+     * If some data can be read immediately, that is stored in the
+     * buffer, and success is indicated. Success is indicated even if
+     * the amount of data read is 0, allowing for signalling the
+     * end-of-file or end-of-connection condition.
+     *
+     * If the reading operation would block, the stream is set up so
+     * that it would read, and failure is returned.
+     *
+     * Otherwise, if the reading operation fails for some other
+     * reason, the buffer's error code is set, so it should always be
+     * checked on a failure!
+     */
+    bool read();
+
+    friend class BufferedStream;
+};
+
+//------------------------------------------------------------------------------
+// Inline definitions
+//------------------------------------------------------------------------------
+
+inline ReadingBuffer::ReadingBuffer(size_t capacity, BufferedStream* stream) :
+    StreamBuffer(capacity, stream)
+{
+}
+
+//------------------------------------------------------------------------------
+
+} /* namespace xplcommon::win32 */ } /* namespace xplcommon */
+
+//------------------------------------------------------------------------------
+#endif // XPLCOMMON_WIN32_READINGBUFFER_H
+
+// Local Variables:
+// mode: C++
+// c-basic-offset: 4
+// indent-tabs-mode: nil
+// End:
Index: src/xplcommon/win32/StreamBuffer.h
===================================================================
--- src/xplcommon/win32/StreamBuffer.h	(revision 21)
+++ src/xplcommon/win32/StreamBuffer.h	(revision 21)
@@ -0,0 +1,115 @@
+// Copyright (c) 2012 by István Váradi
+
+// This file is part of libxplcommon, a common utility library for
+// development related to X-Plane
+
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+
+// 1. Redistributions of source code must retain the above copyright notice, this
+//    list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright notice,
+//    this list of conditions and the following disclaimer in the documentation
+//    and/or other materials provided with the distribution.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// The views and conclusions contained in the software and documentation are those
+// of the authors and should not be interpreted as representing official policies,
+// either expressed or implied, of the FreeBSD Project.
+
+#ifndef XPLCOMMON_WIN32_STREAMBUFFER_H
+#define XPLCOMMON_WIN32_STREAMBUFFER_H
+//------------------------------------------------------------------------------
+
+#include "../Buffer.h"
+#include "Completer.h"
+#include "../Failable.h"
+
+#include "BufferedStream.h"
+
+//------------------------------------------------------------------------------
+
+namespace xplcommon { namespace win32 {
+
+//------------------------------------------------------------------------------
+
+/**
+ * Base class for stream reading and writing buffers.
+ */
+class StreamBuffer : public ::xplcommon::Buffer, public Completer,
+                     public ::xplcommon::FailableReference<StreamBuffer>
+{
+protected:
+    /**
+     * The buffered stream this stream buffer belongs to.
+     */
+    BufferedStream& stream;
+
+protected:
+    /**
+     * Construct the stream buffer with the given capacity and for the
+     * given stream.
+     */
+    StreamBuffer(size_t capacity, BufferedStream* stream);
+
+private:
+    /**
+     * Get the failable object.
+     */
+    const ::xplcommon::Failable& getFailable() const;
+
+    /**
+     * Get the failable object.
+     */
+    ::xplcommon::Failable& getFailable();
+
+    friend class FailableReference<StreamBuffer>;
+};
+
+//------------------------------------------------------------------------------
+// Inline definitions
+//------------------------------------------------------------------------------
+
+inline StreamBuffer::StreamBuffer(size_t capacity, BufferedStream* stream) :
+    Buffer(capacity),
+    Completer(stream),
+    stream(*stream)
+{
+}
+
+//------------------------------------------------------------------------------
+
+inline const ::xplcommon::Failable& StreamBuffer::getFailable() const
+{
+    return stream;
+}
+
+//------------------------------------------------------------------------------
+
+inline ::xplcommon::Failable& StreamBuffer::getFailable()
+{
+    return stream;
+}
+
+//------------------------------------------------------------------------------
+
+} /* namespace xplcommon::win32 */ } /* namespace xplcommon */
+
+//------------------------------------------------------------------------------
+#endif // XPLCOMMON_WIN32_STREAMBUFFER_H
+
+// Local Variables:
+// mode: C++
+// c-basic-offset: 4
+// indent-tabs-mode: nil
+// End:
Index: c/xplcommon/win32/WaitableEvent.cc
===================================================================
--- src/xplcommon/win32/WaitableEvent.cc	(revision 20)
+++ 	(revision )
@@ -1,61 +1,0 @@
-// Copyright (c) 2012 by István Váradi
-
-// This file is part of libxplcommon, a common utility library for
-// development related to X-Plane
-
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-
-// 1. Redistributions of source code must retain the above copyright notice, this
-//    list of conditions and the following disclaimer.
-// 2. Redistributions in binary form must reproduce the above copyright notice,
-//    this list of conditions and the following disclaimer in the documentation
-//    and/or other materials provided with the distribution.
-
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
-// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// The views and conclusions contained in the software and documentation are those
-// of the authors and should not be interpreted as representing official policies,
-// either expressed or implied, of the FreeBSD Project.
-
-//------------------------------------------------------------------------------
-
-#include "WaitableEvent.h"
-
-//------------------------------------------------------------------------------
-
-using xplcommon::win32::WaitableEvent;
-
-//------------------------------------------------------------------------------
-
-bool WaitableEvent::check()
-{
-    DWORD result = WaitForSingleObject(getHandle(),
-                                       (getWaiter()==0) ? INFINITE : 0);
-    if (result==WAIT_FAILED) {
-        setErrorCode(GetLastError());
-        return false;
-    } else if (result==WAIT_OBJECT_0) {
-        clear();
-        return true;
-    } else {
-        return false;
-    }
-}
-
-//------------------------------------------------------------------------------
-
-// Local Variables:
-// mode: C++
-// c-basic-offset: 4
-// indent-tabs-mode: nil
-// End:
Index: src/xplcommon/win32/WaitableEvent.h
===================================================================
--- src/xplcommon/win32/WaitableEvent.h	(revision 20)
+++ src/xplcommon/win32/WaitableEvent.h	(revision 21)
@@ -33,4 +33,5 @@
 
 #include "Event.h"
+#include "EventFailable.h"
 
 //------------------------------------------------------------------------------
@@ -43,5 +44,5 @@
  * An event which can be waited for.
  */
-class WaitableEvent : public Event
+class WaitableEvent : public Event, public EventFailable
 {
 public:
@@ -62,7 +63,20 @@
 //------------------------------------------------------------------------------
 
-inline WaitableEvent::WaitableEvent(Waiter* waiter)
+inline WaitableEvent::WaitableEvent(Waiter* waiter) :
+    Event(static_cast<EventFailable&>(*this))
 {
     if (waiter!=0) addTo(*waiter);
+}
+
+//------------------------------------------------------------------------------
+
+inline bool WaitableEvent::check()
+{
+    if (isFired()) {
+        clear();
+        return true;
+    } else {
+        return false;
+    }
 }
 
Index: src/xplcommon/win32/WritingBuffer.cc
===================================================================
--- src/xplcommon/win32/WritingBuffer.cc	(revision 21)
+++ src/xplcommon/win32/WritingBuffer.cc	(revision 21)
@@ -0,0 +1,80 @@
+// Copyright (c) 2012 by István Váradi
+
+// This file is part of libxplcommon, a common utility library for
+// development related to X-Plane
+
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+
+// 1. Redistributions of source code must retain the above copyright notice, this
+//    list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright notice,
+//    this list of conditions and the following disclaimer in the documentation
+//    and/or other materials provided with the distribution.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// The views and conclusions contained in the software and documentation are those
+// of the authors and should not be interpreted as representing official policies,
+// either expressed or implied, of the FreeBSD Project.
+
+//------------------------------------------------------------------------------
+
+#include "WritingBuffer.h"
+
+//------------------------------------------------------------------------------
+
+using xplcommon::win32::WritingBuffer;
+
+//------------------------------------------------------------------------------
+
+bool WritingBuffer::write()
+{
+    if (failed()) return false;
+
+    if (getLength()==0) {
+        return true;
+    }
+
+    if (isWaited()) {
+        DWORD size = 0;
+        if (getResult(size, stream.handle)) {
+            removeFromWaiter();
+            overlapped->clear();
+            reset();
+            return true;
+        } else {
+            if (stream.failed()) {
+                removeFromWaiter();
+                overlapped->clear();
+            }
+            return false;
+        }
+    }
+
+    bool result = stream.write(getData(), getLength(), overlapped);
+    if (result) {
+        reset();
+    } else if (!stream.failed()) {
+        addTo(stream.getWaiter());
+    }
+
+    return result;
+}
+
+//------------------------------------------------------------------------------
+
+// Local Variables:
+// mode: C++
+// c-basic-offset: 4
+// indent-tabs-mode: nil
+// End:
Index: src/xplcommon/win32/WritingBuffer.h
===================================================================
--- src/xplcommon/win32/WritingBuffer.h	(revision 21)
+++ src/xplcommon/win32/WritingBuffer.h	(revision 21)
@@ -0,0 +1,102 @@
+// Copyright (c) 2012 by István Váradi
+
+// This file is part of libxplcommon, a common utility library for
+// development related to X-Plane
+
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+
+// 1. Redistributions of source code must retain the above copyright notice, this
+//    list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright notice,
+//    this list of conditions and the following disclaimer in the documentation
+//    and/or other materials provided with the distribution.
+
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// The views and conclusions contained in the software and documentation are those
+// of the authors and should not be interpreted as representing official policies,
+// either expressed or implied, of the FreeBSD Project.
+
+#ifndef XPLCOMMON_WIN32_WRITINGBUFFER_H
+#define XPLCOMMON_WIN32_WRITINGBUFFER_H
+//------------------------------------------------------------------------------
+
+#include "StreamBuffer.h"
+
+//------------------------------------------------------------------------------
+
+namespace xplcommon { namespace win32 {
+
+//------------------------------------------------------------------------------
+
+/**
+ * A buffer used for writing into a buffered stream.
+ *
+ * The data to write should be stored in the buffer. Then write()
+ * should be called. If it returns true, it indicates that all data
+ * has been written. In that case the buffer is automatically emptied.
+ */
+class WritingBuffer : public StreamBuffer
+{
+protected:
+    /**
+     * Construct the buffer.
+     */
+    WritingBuffer(size_t capacity, BufferedStream* stream);
+
+public:
+    /**
+     * Write the contents of the buffer using the associated buffered
+     * stream.
+     *
+     * If the buffer is empty, the function returns indicating
+     * success.
+     *
+     * If the complete remaining contents could be written, it also indicates
+     * success, and the buffer is reset, ready to be used again.
+     *
+     * If not everything can be written and the write operation
+     * indicates that it would block, this function returns failure
+     * after the stream has been set up  to handle the corresponding
+     * poll events.
+     *
+     * Otherwise, if the writing operation fails for some other
+     * reason, the buffer's error code is set to the error's code and
+     * false is returned.
+     */
+    bool write();
+
+    friend class BufferedStream;
+};
+
+//------------------------------------------------------------------------------
+// Inline definitions
+//------------------------------------------------------------------------------
+
+inline WritingBuffer::WritingBuffer(size_t capacity, BufferedStream* stream) :
+    StreamBuffer(capacity, stream)
+{
+}
+
+//------------------------------------------------------------------------------
+
+} /* namespace xplcommon::win32 */ } /* namespace xplcommon */
+
+//------------------------------------------------------------------------------
+#endif // XPLCOMMON_WIN32_WRITINGBUFFER_H
+
+// Local Variables:
+// mode: C++
+// c-basic-offset: 4
+// indent-tabs-mode: nil
+// End:
Index: test/testlocsock.cc
===================================================================
--- test/testlocsock.cc	(revision 19)
+++ test/testlocsock.cc	(revision 21)
@@ -36,5 +36,5 @@
 #include <xplcommon/LocalSocket.h>
 #include <xplcommon/LocalClientSocket.h>
-#include <xplcommon/Connector.h>
+#include <xplcommon/LocalConnector.h>
 #include <xplcommon/ReadingBuffer.h>
 #include <xplcommon/WritingBuffer.h>
@@ -57,5 +57,5 @@
 using xplcommon::LocalSocket;
 using xplcommon::LocalClientSocket;
-using xplcommon::Connector;
+using xplcommon::LocalConnector;
 using xplcommon::ReadingBuffer;
 using xplcommon::WritingBuffer;
@@ -66,5 +66,5 @@
 //------------------------------------------------------------------------------
 
-void communicate(ReadingBuffer& readingBuffer, WritingBuffer& writingBuffer,
+void communicate(ReadingBuffer* readingBuffer, WritingBuffer* writingBuffer,
                  Waiter& waiter, unsigned seed, const char* prefix,
                  WaitableEvent* quitEvent = 0)
@@ -74,7 +74,7 @@
     static const size_t rangeToWrite = maxToWrite - minToWrite;
 
-    static const size_t reportingInterval = 100000;
-
-    static const int sleepThreshold = static_cast<int>(RAND_MAX * 0.95);
+    static const size_t reportingInterval = 10000;
+
+    static const int sleepThreshold = static_cast<int>(RAND_MAX * 0.99);
     static const int sleepRemainder = RAND_MAX - sleepThreshold;
     static const unsigned minSleep = 10;
@@ -93,14 +93,22 @@
 
     while(!toQuit) {
+#if TARGET_API_POSIX
         int r = rand_r(&seed);
+#endif
+#if TARGET_API_WIN32
+        int r = rand();
+#endif
         size_t toWrite = minToWrite +
             static_cast<size_t>( static_cast<double>(r) *
                                  rangeToWrite / RAND_MAX );
 
+        size_t lastWriteLength = 0;
+        if (writingBuffer!=0) {
+            lastWriteLength = min(writingBuffer->getCapacity(), toWrite);
+            writingBuffer->reset();
+            writingBuffer->addLength(lastWriteLength);
+        }
+
         while(toWrite>0) {
-            writingBuffer.reset();
-            size_t length = min(writingBuffer.getCapacity(), toWrite);
-            writingBuffer.addLength(length);
-
             if (quitEvent!=0 && quitEvent->check()) {
                 toQuit = true;
@@ -108,44 +116,98 @@
             }
 
-            if (writingBuffer.write()) {
-                numBytesWritten += length;
-                toWrite -= length;
-                length = 0;
-
-                if (numBytesWritten>=nextReportWritten) {
-                    printf("%s: written %zu bytes with %zu blocking and %zu ms sleeping\n",
-                           prefix, numBytesWritten, numWriteBlocked,
-                           numMillisSlept);
-                    nextReportWritten += reportingInterval;
+            bool hasPending = false;
+
+            if (writingBuffer!=0) {
+                size_t loopCount = 0;
+                while(toWrite>0) {
+                    ++loopCount;
+                    if (writingBuffer->write()) {
+                        numBytesWritten += lastWriteLength;
+                        toWrite -= lastWriteLength;
+
+                        if (numBytesWritten>=nextReportWritten) {
+                            printf("%s: written %lu bytes with %lu blocking and %lu ms sleeping\n",
+                                   prefix,
+                                   static_cast<unsigned long>(numBytesWritten),
+                                   static_cast<unsigned long>(numWriteBlocked),
+                                   static_cast<unsigned long>(numMillisSlept));
+                            nextReportWritten += reportingInterval;
+                        }
+
+                        if (toWrite>0) {
+                            if (quitEvent!=0 && quitEvent->check()) {
+                                toQuit = true;
+                                break;
+                            } else {
+                                lastWriteLength = min(writingBuffer->getCapacity(), toWrite);
+                                writingBuffer->addLength(lastWriteLength);
+                                if (loopCount>10) {
+                                    break;
+                                }
+                            }
+                        }
+                    } else if (writingBuffer->failed()) {
+                        printf("%s: writing failed with error: %lu\n",
+                               prefix,
+                               static_cast<unsigned long>(writingBuffer->getErrorCode()));
+                        toQuit = true;
+                        break;
+                    } else {
+                        ++numWriteBlocked;
+                        hasPending = true;
+                        break;
+                    }
                 }
-            } else if (writingBuffer.failed()) {
-                printf("%s: writing failed with error: %lu\n",
-                       prefix,
-                       static_cast<unsigned long>(writingBuffer.getErrorCode()));
-                toQuit = true;
-                break;
-            } else {
-                ++numWriteBlocked;
+                if (toQuit) break;
             }
 
-            if (readingBuffer.read()) {
-                numBytesRead += readingBuffer.getLength();
-                if (numBytesRead>=nextReportRead) {
-                    printf("%s: read %zu bytes with %zu blocking and %zu ms sleeping\n",
-                           prefix, numBytesRead, numReadBlocked, numMillisSlept);
-                    nextReportRead += reportingInterval;
+            if (readingBuffer!=0) {
+                size_t loopCount = 0;
+                while(true) {
+                    ++loopCount;
+                    if (readingBuffer->read()) {
+                        size_t l = readingBuffer->getLength();
+                        if (l==0) {
+                            printf("%s: reading encountered end of file\n", prefix);
+                            toQuit = true;
+                            break;
+                        }
+                        numBytesRead += l;
+                        if (numBytesRead>=nextReportRead) {
+                            printf("%s: read %lu bytes with %lu blocking and %lu ms sleeping\n",
+                                   prefix,
+                                   static_cast<unsigned long>(numBytesRead),
+                                   static_cast<unsigned long>(numReadBlocked),
+                                   static_cast<unsigned long>(numMillisSlept));
+                            nextReportRead += reportingInterval;
+                        }
+                        readingBuffer->reset();
+                        if (quitEvent!=0 && quitEvent->check()) {
+                            toQuit = true;
+                            break;
+                        } else if (loopCount>10) {
+                            break;
+                        }
+                    } else if (readingBuffer->failed()) {
+                        printf("%s: reading failed with error: %lu\n",
+                               prefix,
+                               static_cast<unsigned long>(readingBuffer->getErrorCode()));
+                        toQuit = true;
+                        break;
+                    } else {
+                        ++numReadBlocked;
+                        hasPending = true;
+                        break;
+                    }
                 }
-                readingBuffer.reset();
-            } else if (readingBuffer.failed()) {
-                printf("%s: reading failed with error: %lu\n",
-                       prefix,
-                       static_cast<unsigned long>(readingBuffer.getErrorCode()));
-                toQuit = true;
-                break;
-            } else {
-                ++numReadBlocked;
+                if (toQuit) break;
             }
 
+#if TARGET_API_POSIX
             r = rand_r(&seed);
+#endif
+#if TARGET_API_WIN32
+            r = rand();
+#endif
             if (r>=sleepThreshold) {
                 unsigned toSleep = minSleep +
@@ -158,5 +220,5 @@
             }
 
-            if (length!=0) {
+            if (toWrite>0 && hasPending) {
                 waiter.wait();
                 if (waiter.failed()) {
@@ -171,9 +233,14 @@
     }
 
-    printf("%s: written %zu bytes with %zu blocking\n",
-           prefix, numBytesWritten, numWriteBlocked);
-    printf("%s: read %zu bytes with %zu blocking\n",
-           prefix, numBytesRead, numReadBlocked);
-    printf("%s: slept %zu ms\n", prefix, numMillisSlept);
+    printf("%s: written %lu bytes with %lu blocking\n",
+           prefix,
+           static_cast<unsigned long>(numBytesWritten),
+           static_cast<unsigned long>(numWriteBlocked));
+    printf("%s: read %lu bytes with %lu blocking\n",
+           prefix,
+           static_cast<unsigned long>(numBytesRead),
+           static_cast<unsigned long>(numReadBlocked));
+    printf("%s: slept %lu ms\n", prefix,
+           static_cast<unsigned long>(numMillisSlept));
 }
 
@@ -219,7 +286,11 @@
     LocalAcceptor& acceptor = serverSocket.getAcceptor();
 
+    bool eventFired = false;
     while(!acceptor.accept()) {
+        eventFired = event.check();
+        if (eventFired) break;
         if (acceptor.failed()) {
-            printf("ServerThread::run: acceptor failed...\n");
+            printf("ServerThread::run: acceptor failed...: %lu\n",
+                   (unsigned long)acceptor.getErrorCode());
             return;
         }
@@ -228,8 +299,13 @@
     }
 
+    if (eventFired) {
+        printf("ServerThread::run: waiting done, quitting\n");
+        return;
+    }
+
     printf("ServerThread::run: waiting done, received connection\n");
     LocalSocket* socket = acceptor.getSocket();
 
-    communicate(socket->getReadingBuffer(), socket->getWritingBuffer(),
+    communicate(&socket->getReadingBuffer(), &socket->getWritingBuffer(),
                 waiter, seed, "ServerThread", &event);
 
@@ -243,7 +319,30 @@
 class ClientThread : public Thread
 {
+private:
+    Waiter waiter;
+
+    WaitableEvent event;
+
 public:
+    ClientThread();
+
+    void signal();
+
     virtual void run();
 };
+
+//------------------------------------------------------------------------------
+
+ClientThread::ClientThread() :
+    event(&waiter)
+{
+}
+
+//------------------------------------------------------------------------------
+
+void ClientThread::signal()
+{
+    event.fire();
+}
 
 //------------------------------------------------------------------------------
@@ -258,9 +357,7 @@
     printf("ClientThread::run: connecting\n");
 
-    Waiter waiter;
-
     LocalClientSocket socket("test", &waiter);
 
-    Connector& connector = socket.getConnector();
+    LocalConnector& connector = socket.getConnector();
 
     while(!connector.connect()) {
@@ -275,6 +372,6 @@
     printf("ClientThread::run: connected\n");
 
-    communicate(socket.getReadingBuffer(), socket.getWritingBuffer(),
-                waiter, seed, "ClientThread");
+    communicate(&socket.getReadingBuffer(), &socket.getWritingBuffer(),
+                waiter, seed, "ClientThread", &event);
 }
 
@@ -284,5 +381,7 @@
 int main()
 {
+#if TARGET_API_POSIX
     signal(SIGPIPE, SIG_IGN);
+#endif
 
     ServerThread serverThread;
@@ -294,5 +393,8 @@
 
     Thread::sleep(60000);
-    serverThread.signal();
+    //Thread::sleep(5000);
+    printf("Signalling the server thread\n");
+    //serverThread.signal();
+    clientThread.signal();
     printf("Signalled the server thread\n");
 
