Index: src/xplcommon/.copyright
===================================================================
--- src/xplcommon/.copyright	(revision 0)
+++ src/xplcommon/.copyright	(revision 1)
@@ -1,5 +1,2 @@
-// Copyright (c) 2013, István Váradi
-// All rights reserved.
-
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are met:
Index: src/xplcommon/Makefile.am
===================================================================
--- src/xplcommon/Makefile.am	(revision 0)
+++ src/xplcommon/Makefile.am	(revision 1)
@@ -2,10 +2,14 @@
 
 libxplcommon_la_SOURCES=\
-	POSIXThread.cc	\
-	Win32Thread.cc
+	POSIXThread.cc		\
+	Win32Thread.cc		\
+	POSIXWaitable.cc	\
+	POSIXWaiter.cc
 
 include_xplcommondir=$(includedir)/xplcommon
 include_xplcommon_HEADERS=\
-	POSIXThread.h	\
-	Win32Thread.h	\
-	Thread.h
+	POSIXThread.h		\
+	Win32Thread.h		\
+	Thread.h		\
+	POSIXWaitable.h		\
+	POSIXWaiter.h
Index: src/xplcommon/POSIXThread.cc
===================================================================
--- src/xplcommon/POSIXThread.cc	(revision 0)
+++ src/xplcommon/POSIXThread.cc	(revision 1)
@@ -1,10 +1,6 @@
-// -*- coding: utf-8 -*-
-// Copyright (c) 2012 by István Váradi
+// Copyright (c) 2013 by István Váradi
 
 // This file is part of libxplcommon, a common utility library for
 // development related to X-Plane
-
-// Copyright (c) 2013, István Váradi
-// All rights reserved.
 
 // Redistribution and use in source and binary forms, with or without
Index: src/xplcommon/POSIXThread.h
===================================================================
--- src/xplcommon/POSIXThread.h	(revision 0)
+++ src/xplcommon/POSIXThread.h	(revision 1)
@@ -1,10 +1,6 @@
-// -*- coding: utf-8 -*-
-// Copyright (c) 2012 by István Váradi
+// Copyright (c) 2013 by István Váradi
 
 // This file is part of libxplcommon, a common utility library for
 // development related to X-Plane
-
-// Copyright (c) 2013, István Váradi
-// All rights reserved.
 
 // Redistribution and use in source and binary forms, with or without
@@ -39,4 +35,5 @@
 
 #ifdef HAVE_PTHREAD_H
+
 //------------------------------------------------------------------------------
 
Index: src/xplcommon/POSIXWaitable.cc
===================================================================
--- src/xplcommon/POSIXWaitable.cc	(revision 1)
+++ src/xplcommon/POSIXWaitable.cc	(revision 1)
@@ -0,0 +1,69 @@
+// 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 "config.h"
+#ifdef HAVE_POLL_H
+
+//------------------------------------------------------------------------------
+
+#include "POSIXWaitable.h"
+
+#include "POSIXWaiter.h"
+
+//------------------------------------------------------------------------------
+
+using xplcommon::POSIXWaitable;
+
+//------------------------------------------------------------------------------
+
+POSIXWaitable::POSIXWaitable(POSIXWaiter* waiter, int fd, short events) :
+    waiter(waiter),
+    fd(fd),
+    events(events)
+{
+    if (waiter!=0) waiter->add(this);
+}
+
+//------------------------------------------------------------------------------
+
+POSIXWaitable::~POSIXWaitable()
+{
+    if (waiter!=0) waiter->remove(this);
+}
+
+//------------------------------------------------------------------------------
+#endif // HAVE_POLL_H
+
+// Local Variables:
+// mode: C++
+// c-basic-offset: 4
+// indent-tabs-mode: nil
+// End:
Index: src/xplcommon/POSIXWaitable.h
===================================================================
--- src/xplcommon/POSIXWaitable.h	(revision 1)
+++ src/xplcommon/POSIXWaitable.h	(revision 1)
@@ -0,0 +1,118 @@
+// Copyright (c) 2013 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_POSIXWAITABLE_H
+#define XPLCOMMON_POSIXWAITABLE_H
+//------------------------------------------------------------------------------
+
+#include "config.h"
+
+#ifdef HAVE_POLL_H
+
+//------------------------------------------------------------------------------
+
+namespace xplcommon {
+
+//------------------------------------------------------------------------------
+
+class POSIXWaiter;
+
+//------------------------------------------------------------------------------
+
+/**
+ * Base class of objects for which one can wait in a POSIXWaiter.
+ *
+ * It is basically a file descriptor.
+ */
+class POSIXWaitable
+{
+protected:
+    /**
+     * The waiter this waitable belongs to, if any.
+     */
+    POSIXWaiter* waiter;
+
+    /**
+     * The file descriptor
+     */
+    int fd;
+
+    /**
+     * The events this waitable is interested in.
+     */
+    short events;
+
+protected:
+    /**
+     * Construct the waitable.
+     */
+    POSIXWaitable(POSIXWaiter* waiter, int fd = -1, short events = 0);
+
+public:
+    /**
+     * Destroy the waitable. It will be removed from the waiter.
+     */
+    virtual ~POSIXWaitable();
+
+    /**
+     * Indicate if the waitable is ready, i.e. there is no need to
+     * wait for it.
+     *
+     * Calling this function should not deleted the ready
+     * indication. It should be deleted by actually processing the data.
+     */
+    virtual bool ready() = 0;
+
+protected:
+    /**
+     * Handle the given events.
+     */
+    virtual void handleEvents(short events) = 0;
+
+    friend class POSIXWaiter;
+};
+
+//------------------------------------------------------------------------------
+
+typedef POSIXWaitable Waitable;
+
+//------------------------------------------------------------------------------
+
+} /* namespace xplcommon */
+
+//------------------------------------------------------------------------------
+#endif // HAVE_POLL_H
+
+#endif // XPLCOMMON_POSIXWAITABLE_H
+
+// Local Variables:
+// mode: C++
+// c-basic-offset: 4
+// indent-tabs-mode: nil
+// End:
Index: src/xplcommon/POSIXWaiter.cc
===================================================================
--- src/xplcommon/POSIXWaiter.cc	(revision 1)
+++ src/xplcommon/POSIXWaiter.cc	(revision 1)
@@ -0,0 +1,158 @@
+// 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 "config.h"
+#ifdef HAVE_POLL_H
+
+//------------------------------------------------------------------------------
+
+#include "POSIXWaiter.h"
+#include "POSIXWaitable.h"
+
+#include <cassert>
+#include <cstdio>
+
+//------------------------------------------------------------------------------
+
+using xplcommon::POSIXWaiter;
+
+//------------------------------------------------------------------------------
+
+inline bool POSIXWaiter::hasReady() const
+{
+    for(waitables_t::const_iterator i = waitables.begin(); i!=waitables.end();
+        ++i)
+    {
+        POSIXWaitable* waitable = i->second;
+        if (waitable->ready()) return true;
+    }
+    return false;
+}
+
+//------------------------------------------------------------------------------
+
+inline size_t POSIXWaiter::setupPollFDs(pollfd* pollFDs)
+{
+    size_t numValid = 0;
+
+    for(waitables_t::const_iterator i = waitables.begin(); i!=waitables.end();
+        ++i)
+    {
+        POSIXWaitable* waitable = i->second;
+        if (waitable->events==0) continue;
+
+        pollfd& pollFD = pollFDs[numValid++];
+
+        pollFD.fd = waitable->fd;
+        pollFD.events = waitable->events;
+        pollFD.revents = 0;
+    }
+
+    return numValid;
+}
+
+//------------------------------------------------------------------------------
+
+inline void POSIXWaiter::processPollFDs(const pollfd* pollFDs, size_t size)
+{
+    for(size_t i = 0; i<size; ++i) {
+        const pollfd& pollFD = pollFDs[i];
+        if (pollFD.revents!=0) {
+            waitables_t::iterator j = waitables.find(pollFD.fd);
+            assert(j!=waitables.end());
+            POSIXWaitable* waitable = j->second;
+            waitable->handleEvents(pollFD.revents);
+        }
+    }
+}
+
+//------------------------------------------------------------------------------
+
+POSIXWaiter::~POSIXWaiter()
+{
+    for(waitables_t::iterator i = waitables.begin(); i!=waitables.end(); ++i)
+    {
+        POSIXWaitable* waitable = i->second;
+        waitable->waiter = 0;
+    }
+}
+
+//------------------------------------------------------------------------------
+
+bool POSIXWaiter::wait(int timeout)
+{
+    if (hasReady()) return true;
+
+    pollfd pollFDs[numWaitables];
+    size_t numValid = setupPollFDs(pollFDs);
+
+    int result = poll(pollFDs, numValid, timeout);
+
+    if (result<0) {
+        perror("POSIXWaiter::wait: poll");
+        return false;
+    } else if (result>0) {
+        processPollFDs(pollFDs, numValid);
+    }
+
+    return hasReady();
+}
+
+//------------------------------------------------------------------------------
+
+void POSIXWaiter::add(POSIXWaitable* waitable)
+{
+    assert(waitable->fd>=0);
+    assert(waitables.find(waitable->fd)==waitables.end());
+    waitables[waitable->fd] = waitable;
+    ++numWaitables;
+}
+
+//------------------------------------------------------------------------------
+
+void POSIXWaiter::remove(POSIXWaitable* waitable)
+{
+    assert(numWaitables>0);
+    assert(waitables.find(waitable->fd)!=waitables.end());
+    assert(waitables[waitable->fd]==waitable);
+    waitables.erase(waitable->fd);
+    --numWaitables;
+}
+
+
+//------------------------------------------------------------------------------
+#endif // HAVE_POLL_H
+
+// Local Variables:
+// mode: C++
+// c-basic-offset: 4
+// indent-tabs-mode: nil
+// End:
Index: src/xplcommon/POSIXWaiter.h
===================================================================
--- src/xplcommon/POSIXWaiter.h	(revision 1)
+++ src/xplcommon/POSIXWaiter.h	(revision 1)
@@ -0,0 +1,165 @@
+// Copyright (c) 2013 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_POSIXWAITER_H
+#define XPLCOMMON_POSIXWAITER_H
+//------------------------------------------------------------------------------
+
+#include "config.h"
+
+#ifdef HAVE_POLL_H
+
+//------------------------------------------------------------------------------
+
+#include <map>
+
+#include <cstdlib>
+
+#include <poll.h>
+
+//------------------------------------------------------------------------------
+
+namespace xplcommon {
+
+//------------------------------------------------------------------------------
+
+class POSIXWaitable;
+
+//------------------------------------------------------------------------------
+
+/**
+ * Class that can be used to register waitable objects and then wait
+ * for them.
+ */
+class POSIXWaiter
+{
+private:
+    /**
+     * Type for the set of waitables.
+     */
+    typedef std::map<int, POSIXWaitable*> waitables_t;
+
+    /**
+     * The set of waitables belonging to this waiter.
+     */
+    waitables_t waitables;
+
+    /**
+     * The number of waitables.
+     */
+    size_t numWaitables;
+
+public:
+    /**
+     * Construct the waiter.
+     */
+    POSIXWaiter();
+
+    /**
+     * Destroy the waiter. All waitables that still exists will be
+     * modified to point to no waiter.
+     */
+    ~POSIXWaiter();
+
+    /**
+     * Wait for any if the waitables to become ready or until a
+     * timeout expires.
+     *
+     * If any of the waitables are ready, the function returns immediately.
+     *
+     * @return true if any of the waitables has become ready, false if
+     * the timeout occurs.
+     */
+    bool wait(int timeout = -1);
+
+protected:
+    /**
+     * Add a waitable.
+     */
+    void add(POSIXWaitable* waitable);
+
+    /**
+     * Remove a waitable.
+     */
+    void remove(POSIXWaitable* waitable);
+
+private:
+    /**
+     * Determine if any of the waitables is ready.
+     */
+    bool hasReady() const;
+
+    /**
+     * Fill the given array of poll descriptors with those file
+     * descriptors that wait for an event.
+     *
+     * @param pollFDs the file descriptor array to fill. It should
+     * contain at least as many elements as the number of waitables.
+     *
+     * @return the number of valid poll file descriptors.
+     */
+    size_t setupPollFDs(pollfd* pollFDs);
+
+    /**
+     * Process the given array of poll descriptors. For each
+     * descriptor, if its events are not 0, the handleEvents()
+     * function of the corresponding waitable is called.
+     */
+    void processPollFDs(const pollfd* pollFDs, size_t size);
+
+    friend class POSIXWaitable;
+};
+
+//------------------------------------------------------------------------------
+
+typedef POSIXWaiter Waiter;
+
+//------------------------------------------------------------------------------
+// Inline definitions
+//------------------------------------------------------------------------------
+
+inline POSIXWaiter::POSIXWaiter() :
+    numWaitables(0)
+{
+}
+
+//------------------------------------------------------------------------------
+
+} /* namespace xplcommon */
+
+//------------------------------------------------------------------------------
+#endif // HAVE_POLL_H
+
+#endif // XPLCOMMON_POSIXWAITABLE_H
+
+// Local Variables:
+// mode: C++
+// c-basic-offset: 4
+// indent-tabs-mode: nil
+// End:
Index: src/xplcommon/Thread.h
===================================================================
--- src/xplcommon/Thread.h	(revision 0)
+++ src/xplcommon/Thread.h	(revision 1)
@@ -1,9 +1,6 @@
-// Copyright (c) 2012 by István Váradi
+// Copyright (c) 2013 by István Váradi
 
 // This file is part of libxplcommon, a common utility library for
 // development related to X-Plane
-
-// Copyright (c) 2013, István Váradi
-// All rights reserved.
 
 // Redistribution and use in source and binary forms, with or without
Index: src/xplcommon/Win32Thread.cc
===================================================================
--- src/xplcommon/Win32Thread.cc	(revision 0)
+++ src/xplcommon/Win32Thread.cc	(revision 1)
@@ -1,10 +1,6 @@
-// -*- coding: utf-8 -*-
-// Copyright (c) 2012 by István Váradi
+// Copyright (c) 2013 by István Váradi
 
 // This file is part of libxplcommon, a common utility library for
 // development related to X-Plane
-
-// Copyright (c) 2013, István Váradi
-// All rights reserved.
 
 // Redistribution and use in source and binary forms, with or without
Index: src/xplcommon/Win32Thread.h
===================================================================
--- src/xplcommon/Win32Thread.h	(revision 0)
+++ src/xplcommon/Win32Thread.h	(revision 1)
@@ -1,11 +1,6 @@
-// -*- coding: utf-8 -*-
-
-// Copyright (c) 2012 by István Váradi
+// Copyright (c) 2013 by István Váradi
 
 // This file is part of libxplcommon, a common utility library for
 // development related to X-Plane
-
-// Copyright (c) 2013, István Váradi
-// All rights reserved.
 
 // Redistribution and use in source and binary forms, with or without
Index: src/xplcommon/config.h.in
===================================================================
--- src/xplcommon/config.h.in	(revision 0)
+++ src/xplcommon/config.h.in	(revision 1)
@@ -9,4 +9,7 @@
 /* Define to 1 if you have the <memory.h> header file. */
 #undef HAVE_MEMORY_H
+
+/* Define to 1 if you have the <poll.h> header file. */
+#undef HAVE_POLL_H
 
 /* Define to 1 if you have the <pthread.h> header file. */
