Index: src/xplra/Makefile.am
===================================================================
--- src/xplra/Makefile.am	(revision 8)
+++ src/xplra/Makefile.am	(revision 9)
@@ -33,5 +33,6 @@
 	SetDataRefTask.cc		\
 	MultiTaskRequest.cc		\
-	GetMultiDataRefRequest.cc
+	GetMultiDataRefRequest.cc	\
+	SetMultiDataRefRequest.cc
 
 libxplra_la_LIBADD=$(LIBXPLCOMMON_LIBS)
@@ -49,3 +50,4 @@
 	SetDataRefTask.h		\
 	MultiTaskRequest.h		\
-	GetMultiDataRefRequest.h
+	GetMultiDataRefRequest.h	\
+	SetMultiDataRefRequest.h
Index: src/xplra/Protocol.h
===================================================================
--- src/xplra/Protocol.h	(revision 8)
+++ src/xplra/Protocol.h	(revision 9)
@@ -65,4 +65,19 @@
      */
     static const uint8_t COMMAND_EXECUTE_GET_MULTI = 0x13;
+
+    /**
+     * Command: register a multiple-data update request
+     */
+    static const uint8_t COMMAND_REGISTER_SET_MULTI = 0x21;
+
+    /**
+     * Command: unregister a multiple-data update request
+     */
+    static const uint8_t COMMAND_UNREGISTER_SET_MULTI = 0x22;
+
+    /**
+     * Command: execute a registered multiple-data update request
+     */
+    static const uint8_t COMMAND_EXECUTE_SET_MULTI = 0x23;
 
     /**
Index: src/xplra/ServerThread.cc
===================================================================
--- src/xplra/ServerThread.cc	(revision 8)
+++ src/xplra/ServerThread.cc	(revision 9)
@@ -37,4 +37,5 @@
 #include "TaskRequest.h"
 #include "GetMultiDataRefRequest.h"
+#include "SetMultiDataRefRequest.h"
 
 #include <xplcommon/Util.h>
@@ -76,5 +77,6 @@
     bufferedStream(acceptor.getSocket(&waiter)),
     stream(*bufferedStream),
-    nextGetMultiRequestID(1)
+    nextGetMultiRequestID(1),
+    nextSetMultiRequestID(1)
 {
     instancesMutex.lock();
@@ -91,4 +93,10 @@
     for(getMultiRequests_t::iterator i = getMultiRequests.begin();
         i!=getMultiRequests.end(); ++i)
+    {
+        delete i->second;
+    }
+
+    for(setMultiRequests_t::iterator i = setMultiRequests.begin();
+        i!=setMultiRequests.end(); ++i)
     {
         delete i->second;
@@ -129,4 +137,10 @@
         } else if (command==Protocol::COMMAND_EXECUTE_GET_MULTI) {
             if (!handleExecuteGetMulti()) break;
+        } else if (command==Protocol::COMMAND_REGISTER_SET_MULTI) {
+            if (!handleRegisterSetMulti()) break;
+        } else if (command==Protocol::COMMAND_UNREGISTER_SET_MULTI) {
+            if (!handleUnregisterSetMulti()) break;
+        } else if (command==Protocol::COMMAND_EXECUTE_SET_MULTI) {
+            if (!handleExecuteSetMulti()) break;
         } else {
             stream.writeU8(Protocol::RESULT_INVALID_COMMAND);
@@ -177,4 +191,10 @@
         stream.writeU8(result);
         return true;
+    }
+
+    task->readValue(stream);
+    if (!stream) {
+        delete task;
+        return false;
     }
 
@@ -258,4 +278,66 @@
 //------------------------------------------------------------------------------
 
+bool ServerThread::handleRegisterSetMulti()
+{
+    uint8_t result = Protocol::RESULT_OK;
+    SetMultiDataRefRequest* request =
+        new SetMultiDataRefRequest(result, stream);
+    if (result!=Protocol::RESULT_OK || !stream) {
+        delete request;
+        stream.writeU8(result);
+        return stream;
+    }
+
+    size_t id = nextSetMultiRequestID++;
+    setMultiRequests[id] = request;
+
+    stream.writeU8(Protocol::RESULT_OK);
+    stream.writeU32(id);
+
+    return true;
+}
+
+//------------------------------------------------------------------------------
+
+bool ServerThread::handleUnregisterSetMulti()
+{
+    uint32_t id = stream.readU32();
+    if (!stream) return false;
+
+    setMultiRequests_t::iterator i = setMultiRequests.find(id);
+    if (i==setMultiRequests.end()) {
+        stream.writeU8(Protocol::RESULT_INVALID_ID);
+    } else {
+        SetMultiDataRefRequest* request = i->second;
+        setMultiRequests.erase(i);
+        delete request;
+        stream.writeU8(Protocol::RESULT_OK);
+    }
+
+    return true;
+}
+
+//------------------------------------------------------------------------------
+
+bool ServerThread::handleExecuteSetMulti()
+{
+    uint32_t id = stream.readU32();
+    if (!stream) return false;
+
+    setMultiRequests_t::iterator i = setMultiRequests.find(id);
+    if (i==setMultiRequests.end()) {
+        stream.writeU8(Protocol::RESULT_INVALID_ID);
+    } else {
+        SetMultiDataRefRequest* request = i->second;
+        request->readValues(stream);
+        if (!stream || !requestQueue.execute(request)) return false;
+        request->writeResult(stream);
+    }
+
+    return true;
+}
+
+//------------------------------------------------------------------------------
+
 // Local Variables:
 // mode: C++
Index: src/xplra/ServerThread.h
===================================================================
--- src/xplra/ServerThread.h	(revision 8)
+++ src/xplra/ServerThread.h	(revision 9)
@@ -52,4 +52,5 @@
 
 class GetMultiDataRefRequest;
+class SetMultiDataRefRequest;
 
 //------------------------------------------------------------------------------
@@ -67,9 +68,14 @@
 
     /**
-     * Type for the registered multiple-data requests.
+     * Type for the registered multiple-data query requests.
      */
     typedef std::map<size_t, GetMultiDataRefRequest*> getMultiRequests_t;
 
     /**
+     * Type for the registered multiple-data update requests.
+     */
+    typedef std::map<size_t, SetMultiDataRefRequest*> setMultiRequests_t;
+
+    /**
      * A mutex to protect the collection of server threads.
      */
@@ -117,4 +123,14 @@
      */
     getMultiRequests_t getMultiRequests;
+
+    /**
+     * The ID of the next multiple-data update request.
+     */
+    size_t nextSetMultiRequestID;
+
+    /**
+     * The registered multiple-data query requests.
+     */
+    setMultiRequests_t setMultiRequests;
 
 public:
@@ -176,4 +192,25 @@
      */
     bool handleExecuteGetMulti();
+
+    /**
+     * Handle the COMMAND_REGISTER_SET_MULTI command
+     *
+     * @return true, if we can continue, false if the thread should quit
+     */
+    bool handleRegisterSetMulti();
+
+    /**
+     * Handle the COMMAND_UNREGISTER_SET_MULTI command
+     *
+     * @return true, if we can continue, false if the thread should quit
+     */
+    bool handleUnregisterSetMulti();
+
+    /**
+     * Handle the COMMAND_EXECUTE_SET_MULTI command
+     *
+     * @return true, if we can continue, false if the thread should quit
+     */
+    bool handleExecuteSetMulti();
 };
 
Index: src/xplra/SetDataRefTask.cc
===================================================================
--- src/xplra/SetDataRefTask.cc	(revision 7)
+++ src/xplra/SetDataRefTask.cc	(revision 9)
@@ -55,12 +55,9 @@
 
     if (type==Protocol::TYPE_INT) {
-        int value = stream.readS32();
-        if (stream) return new SetIntDataRefTask(name, value);
+        return new SetIntDataRefTask(name);
     } else if (type==Protocol::TYPE_FLOAT) {
-        float value = stream.readFloat();
-        if (stream) return new SetFloatDataRefTask(name, value);
+        return new SetFloatDataRefTask(name);
     } else if (type==Protocol::TYPE_DOUBLE) {
-        double value = stream.readDouble();
-        if (stream) return new SetDoubleDataRefTask(name, value);
+        return new SetDoubleDataRefTask(name);
     } else if (type==Protocol::TYPE_FLOAT_ARRAY ||
                type==Protocol::TYPE_INT_ARRAY ||
@@ -79,19 +76,10 @@
         }
 
-        SetDataRefTask* task = 0;
         if (type==Protocol::TYPE_INT_ARRAY) {
-            task = new SetIntArrayDataRefTask(name, length, offset);
+            return new SetIntArrayDataRefTask(name, length, offset);
         } else if (type==Protocol::TYPE_FLOAT_ARRAY) {
-            task = new SetFloatArrayDataRefTask(name, length, offset);
+            return new SetFloatArrayDataRefTask(name, length, offset);
         } else {
-            task = new SetByteArrayDataRefTask(name, length, offset);
-        }
-
-        task->readValue(stream);
-
-        if (stream) {
-            return task;
-        } else {
-            delete task;
+            return new SetByteArrayDataRefTask(name, length, offset);
         }
     } else {
Index: src/xplra/SetDataRefTask.h
===================================================================
--- src/xplra/SetDataRefTask.h	(revision 7)
+++ src/xplra/SetDataRefTask.h	(revision 9)
@@ -107,5 +107,5 @@
      * dataref with the given name.
      */
-    SetScalarDataRefTask(const std::string& name, T value);
+    SetScalarDataRefTask(const std::string& name);
 
     /**
@@ -113,5 +113,5 @@
      * dataref.
      */
-    SetScalarDataRefTask(XPLMDataRef dataRef, T value);
+    SetScalarDataRefTask(XPLMDataRef dataRef);
 
 protected:
@@ -140,10 +140,10 @@
      * Construct the task for the dataref with the given name.
      */
-    SetIntDataRefTask(const std::string& name, int value);
+    SetIntDataRefTask(const std::string& name);
 
     /**
      * Construct the task for the given dataref.
      */
-    SetIntDataRefTask(XPLMDataRef dataRef, int value);
+    SetIntDataRefTask(XPLMDataRef dataRef);
 
     /**
@@ -171,10 +171,10 @@
      * Construct the task for the dataref with the given name.
      */
-    SetFloatDataRefTask(const std::string& name, float value);
+    SetFloatDataRefTask(const std::string& name);
 
     /**
      * Construct the task for the given dataref.
      */
-    SetFloatDataRefTask(XPLMDataRef dataRef, float value);
+    SetFloatDataRefTask(XPLMDataRef dataRef);
 
     /**
@@ -202,10 +202,10 @@
      * Construct the task for the dataref with the given name.
      */
-    SetDoubleDataRefTask(const std::string& name, double value);
+    SetDoubleDataRefTask(const std::string& name);
 
     /**
      * Construct the task for the given dataref.
      */
-    SetDoubleDataRefTask(XPLMDataRef dataRef, double value);
+    SetDoubleDataRefTask(XPLMDataRef dataRef);
 
     /**
@@ -365,7 +365,6 @@
 template <typename T, class ConcreteClass>
 inline SetScalarDataRefTask<T, ConcreteClass>::
-SetScalarDataRefTask(const std::string& name, T value) :
-    SetDataRefTask(name),
-    value(value)
+SetScalarDataRefTask(const std::string& name) :
+    SetDataRefTask(name)
 {
 }
@@ -375,7 +374,6 @@
 template <typename T, class ConcreteClass>
 inline SetScalarDataRefTask<T, ConcreteClass>::
-SetScalarDataRefTask(XPLMDataRef dataRef, T value) :
-    SetDataRefTask(dataRef),
-    value(value)
+SetScalarDataRefTask(XPLMDataRef dataRef) :
+    SetDataRefTask(dataRef)
 {
 }
@@ -465,13 +463,13 @@
 //------------------------------------------------------------------------------
 
-inline SetIntDataRefTask::SetIntDataRefTask(const std::string& name, int value) :
-    SetScalarDataRefTask<int, SetIntDataRefTask>(name, value)
-{
-}
-
-//------------------------------------------------------------------------------
-
-inline SetIntDataRefTask::SetIntDataRefTask(XPLMDataRef dataRef, int value) :
-    SetScalarDataRefTask<int, SetIntDataRefTask>(dataRef, value)
+inline SetIntDataRefTask::SetIntDataRefTask(const std::string& name) :
+    SetScalarDataRefTask<int, SetIntDataRefTask>(name)
+{
+}
+
+//------------------------------------------------------------------------------
+
+inline SetIntDataRefTask::SetIntDataRefTask(XPLMDataRef dataRef) :
+    SetScalarDataRefTask<int, SetIntDataRefTask>(dataRef)
 {
 }
@@ -487,15 +485,13 @@
 //------------------------------------------------------------------------------
 
-inline SetFloatDataRefTask::SetFloatDataRefTask(const std::string& name,
-                                                float value) :
-    SetScalarDataRefTask<float, SetFloatDataRefTask>(name, value)
-{
-}
-
-//------------------------------------------------------------------------------
-
-inline SetFloatDataRefTask::SetFloatDataRefTask(XPLMDataRef dataRef,
-                                                float value) :
-    SetScalarDataRefTask<float, SetFloatDataRefTask>(dataRef, value)
+inline SetFloatDataRefTask::SetFloatDataRefTask(const std::string& name) :
+    SetScalarDataRefTask<float, SetFloatDataRefTask>(name)
+{
+}
+
+//------------------------------------------------------------------------------
+
+inline SetFloatDataRefTask::SetFloatDataRefTask(XPLMDataRef dataRef) :
+    SetScalarDataRefTask<float, SetFloatDataRefTask>(dataRef)
 {
 }
@@ -511,15 +507,13 @@
 //------------------------------------------------------------------------------
 
-inline SetDoubleDataRefTask::SetDoubleDataRefTask(const std::string& name,
-                                                  double value) :
-    SetScalarDataRefTask<double, SetDoubleDataRefTask>(name, value)
-{
-}
-
-//------------------------------------------------------------------------------
-
-inline SetDoubleDataRefTask::SetDoubleDataRefTask(XPLMDataRef dataRef,
-                                                  double value) :
-    SetScalarDataRefTask<double, SetDoubleDataRefTask>(dataRef, value)
+inline SetDoubleDataRefTask::SetDoubleDataRefTask(const std::string& name) :
+    SetScalarDataRefTask<double, SetDoubleDataRefTask>(name)
+{
+}
+
+//------------------------------------------------------------------------------
+
+inline SetDoubleDataRefTask::SetDoubleDataRefTask(XPLMDataRef dataRef) :
+    SetScalarDataRefTask<double, SetDoubleDataRefTask>(dataRef)
 {
 }
Index: src/xplra/SetMultiDataRefRequest.cc
===================================================================
--- src/xplra/SetMultiDataRefRequest.cc	(revision 9)
+++ src/xplra/SetMultiDataRefRequest.cc	(revision 9)
@@ -0,0 +1,96 @@
+// Copyright (c) 2013 by István Váradi
+
+// This file is part of XPLRA, a remote-access plugin for 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 "SetMultiDataRefRequest.h"
+
+#include "Protocol.h"
+
+//------------------------------------------------------------------------------
+
+using xplra::SetMultiDataRefRequest;
+
+using xplcommon::DataStream;
+
+//------------------------------------------------------------------------------
+
+SetMultiDataRefRequest::SetMultiDataRefRequest(uint8_t& result,
+                                               DataStream& stream)
+{
+    result = Protocol::RESULT_OK;
+
+    uint32_t numTasks = stream.readU32();
+    if (!stream) return;
+    if (numTasks==0 || numTasks>Protocol::MAX_MULTI_COUNT) {
+        result = Protocol::RESULT_INVALID_COUNT;
+        return;
+    }
+
+    for(size_t i = 0;
+        i<numTasks && result==Protocol::RESULT_OK && stream; ++i) {
+        SetDataRefTask* task = SetDataRefTask::create(result, stream);
+        if (task!=0) addTask(task);
+    }
+}
+
+//------------------------------------------------------------------------------
+
+void SetMultiDataRefRequest::readValues(DataStream& stream)
+{
+    size_t numTasks = getNumTasks();
+    for(size_t i = 0; i<numTasks && stream; ++i) {
+        SetDataRefTask* task = getTask(i);
+        task->readValue(stream);
+    }
+}
+
+//------------------------------------------------------------------------------
+
+void SetMultiDataRefRequest::writeResult(DataStream& stream) const
+{
+    size_t numTasks = getNumTasks();
+    for(size_t i = 0; i<numTasks; ++i) {
+        SetDataRefTask* task = getTask(i);
+        if (!task->isValid()) {
+            stream.writeU8(Protocol::RESULT_UNKNOWN_DATAREF);
+            stream.writeU32(i);
+            return;
+        }
+    }
+
+    stream.writeU8(Protocol::RESULT_OK);
+}
+
+//------------------------------------------------------------------------------
+
+// Local Variables:
+// mode: C++
+// c-basic-offset: 4
+// indent-tabs-mode: nil
+// End:
Index: src/xplra/SetMultiDataRefRequest.h
===================================================================
--- src/xplra/SetMultiDataRefRequest.h	(revision 9)
+++ src/xplra/SetMultiDataRefRequest.h	(revision 9)
@@ -0,0 +1,82 @@
+// Copyright (c) 2013 by István Váradi
+
+// This file is part of XPLRA, a remote-access plugin for 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 XPLRA_SETMULTIDATAREFREQUEST_H
+#define XPLRA_SETMULTIDATAREFREQUEST_H
+//------------------------------------------------------------------------------
+
+#include "MultiTaskRequest.h"
+#include "SetDataRefTask.h"
+
+//------------------------------------------------------------------------------
+
+namespace xplra {
+
+//------------------------------------------------------------------------------
+
+/**
+ * A request containing several dataref update tasks.
+ */
+class SetMultiDataRefRequest : public MultiTaskRequestTemplate<SetDataRefTask>
+{
+public:
+    /**
+     * Construct the request by reading the task specifications from
+     * the given stream.
+     */
+    SetMultiDataRefRequest(uint8_t& result, xplcommon::DataStream& stream);
+
+    /**
+     * Read the values of all tasks.
+     */
+    void readValues(xplcommon::DataStream& stream);
+
+    /**
+     * Write the result of an execution.
+     *
+     * If there is at least one invalid dataref, the result will be
+     * RESULT_UNKNOWN_DATAREF followed by a 32-bit unsigned value with
+     * the index of the first unknown dataref.
+     *
+     * Otherwise the result is RESULT_OK.
+     */
+    void writeResult(xplcommon::DataStream& stream) const;
+};
+
+//------------------------------------------------------------------------------
+
+} /* namespace xplra */
+
+//------------------------------------------------------------------------------
+#endif // XPLRA_SETMULTIDATAREFREQUEST_H
+
+// Local Variables:
+// mode: C++
+// c-basic-offset: 4
+// indent-tabs-mode: nil
+// End:
Index: src/xplra/plugin.cc
===================================================================
--- src/xplra/plugin.cc	(revision 1)
+++ src/xplra/plugin.cc	(revision 9)
@@ -32,4 +32,5 @@
 
 #include <xplcommon/Util.h>
+#include <xplcommon/config.h>
 
 #include <XPLMDefs.h>
@@ -40,4 +41,8 @@
 #include <cstring>
 #include <cstdarg>
+
+#if TARGET_API_POSIX
+#include <signal.h>
+#endif
 
 //------------------------------------------------------------------------------
@@ -64,4 +69,8 @@
     strcpy(outSignature, "hu.varadiistvan.xplra");
     strcpy(outDescription, "Provides remote access to datarefs");
+
+#if TARGET_API_POSIX
+    signal(SIGPIPE, SIG_IGN);
+#endif
 
     return 1;
