// 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 "ServerThread.h" #include "RequestQueue.h" #include "Protocol.h" #include "GetDataRefTask.h" #include "TaskRequest.h" #include #include //------------------------------------------------------------------------------ using xplra::ServerThread; using xplcommon::LocalAcceptor; using xplcommon::Mutex; using xplcommon::Util; using std::string; //------------------------------------------------------------------------------ Mutex ServerThread::instancesMutex; ServerThread::instances_t ServerThread::instances; //------------------------------------------------------------------------------ void ServerThread::quitAll() { instancesMutex.lock(); for(instances_t::iterator i = instances.begin(); i!=instances.end(); ++i) { (*i)->quit(); } instancesMutex.unlock(); } //------------------------------------------------------------------------------ ServerThread::ServerThread(RequestQueue& requestQueue, LocalAcceptor& acceptor) : Thread(true), requestQueue(requestQueue), bufferedStream(acceptor.getSocket(&waiter)), stream(*bufferedStream) { instancesMutex.lock(); instances.insert(this); instancesMutex.unlock(); } //------------------------------------------------------------------------------ ServerThread::~ServerThread() { delete bufferedStream; instancesMutex.lock(); instances.erase(this); instancesMutex.unlock(); } //------------------------------------------------------------------------------ void ServerThread::quit() { stream.interrupt(); } //------------------------------------------------------------------------------ void ServerThread::run() { Util::debug("hu.varadiistvan.xplra.ServerThread[%p]::run\n", this); while(stream) { uint8_t command = stream.readU8(); if (!stream) continue; // Util::debug("hu.varadiistvan.xplra.ServerThread[%p]::run: command=0x%02x\n", // this, command); if (command==Protocol::COMMAND_GET_SINGLE) { if (!handleGetSingle(stream)) break; } else { stream.writeU8(Protocol::RESULT_INVALID_COMMAND); } stream.flush(); } Util::debug("hu.varadiistvan.xplra.ServerThread[%p]::run: quitting\n", this); } //------------------------------------------------------------------------------ bool ServerThread::handleGetSingle(xplcommon::DataStream& stream) { uint8_t result = Protocol::RESULT_OK; GetDataRefTask* task = GetDataRefTask::create(result, stream); if (!stream) return false; else if (task==0) { stream.writeU8(Protocol::RESULT_INVALID_TYPE); return true; } TaskRequest request(task); if (!requestQueue.execute(&request)) return false; if (task->isValid()) { stream.writeU8(Protocol::RESULT_OK); task->writeValue(stream); } else { stream.writeU8(Protocol::RESULT_UNKNOWN_DATAREF); } return true; } //------------------------------------------------------------------------------ // Local Variables: // mode: C++ // c-basic-offset: 4 // indent-tabs-mode: nil // End: