LCOV - code coverage report
Current view: top level - co - pipeConnection.cpp (source / functions) Hit Total Coverage
Test: Collage Lines: 43 52 82.7 %
Date: 2018-01-09 16:37:03 Functions: 9 9 100.0 %

          Line data    Source code
       1             : 
       2             : /* Copyright (c) 2007-2012, Stefan Eilemann <eile@equalizergraphics.com>
       3             :  *                    2011, Daniel Nachbaur <danielnachbaur@gmail.com>
       4             :  *
       5             :  * This file is part of Collage <https://github.com/Eyescale/Collage>
       6             :  *
       7             :  * This library is free software; you can redistribute it and/or modify it under
       8             :  * the terms of the GNU Lesser General Public License version 2.1 as published
       9             :  * by the Free Software Foundation.
      10             :  *
      11             :  * This library is distributed in the hope that it will be useful, but WITHOUT
      12             :  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
      13             :  * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
      14             :  * details.
      15             :  *
      16             :  * You should have received a copy of the GNU Lesser General Public License
      17             :  * along with this library; if not, write to the Free Software Foundation, Inc.,
      18             :  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
      19             :  */
      20             : 
      21             : #include "pipeConnection.h"
      22             : 
      23             : #include "connectionDescription.h"
      24             : #include "node.h"
      25             : #ifdef _WIN32
      26             : #include "namedPipeConnection.h"
      27             : #endif
      28             : 
      29             : #include <lunchbox/log.h>
      30             : #include <lunchbox/thread.h>
      31             : 
      32             : #include <errno.h>
      33             : 
      34             : namespace co
      35             : {
      36         214 : PipeConnection::PipeConnection()
      37             : {
      38         428 :     ConnectionDescriptionPtr description = _getDescription();
      39         214 :     description->type = CONNECTIONTYPE_PIPE;
      40         214 :     description->bandwidth = 1024000;
      41         214 : }
      42             : 
      43         624 : PipeConnection::~PipeConnection()
      44             : {
      45         208 :     _close();
      46         416 : }
      47             : 
      48             : //----------------------------------------------------------------------
      49             : // connect
      50             : //----------------------------------------------------------------------
      51         107 : bool PipeConnection::connect()
      52             : {
      53         107 :     LBASSERT(getDescription()->type == CONNECTIONTYPE_PIPE);
      54             : 
      55         107 :     if (!isClosed())
      56           0 :         return false;
      57             : 
      58         107 :     _setState(STATE_CONNECTING);
      59         107 :     _sibling = new PipeConnection;
      60         107 :     _sibling->_sibling = this;
      61             : 
      62         107 :     if (!_createPipes())
      63             :     {
      64           0 :         close();
      65           0 :         return false;
      66             :     }
      67             : 
      68         107 :     _setState(STATE_CONNECTED);
      69         107 :     _sibling->_setState(STATE_CONNECTED);
      70         107 :     _connected = true;
      71         107 :     return true;
      72             : }
      73             : 
      74             : #ifdef _WIN32
      75             : 
      76             : Connection::Notifier PipeConnection::getNotifier() const
      77             : {
      78             :     if (!_namedPipe)
      79             :         return 0;
      80             :     return _namedPipe->getNotifier();
      81             : }
      82             : 
      83             : bool PipeConnection::_createPipes()
      84             : {
      85             :     std::stringstream pipeName;
      86             :     pipeName << "\\\\.\\pipe\\Collage." << servus::make_UUID();
      87             : 
      88             :     ConnectionDescriptionPtr desc = new ConnectionDescription;
      89             :     desc->type = CONNECTIONTYPE_NAMEDPIPE;
      90             :     desc->setFilename(pipeName.str());
      91             : 
      92             :     ConnectionPtr connection = Connection::create(desc);
      93             :     _namedPipe = static_cast<NamedPipeConnection*>(connection.get());
      94             :     if (!_namedPipe->listen())
      95             :         return false;
      96             :     _namedPipe->acceptNB();
      97             : 
      98             :     connection = Connection::create(desc);
      99             :     _sibling->_namedPipe = static_cast<NamedPipeConnection*>(connection.get());
     100             :     if (!_sibling->_namedPipe->connect())
     101             :     {
     102             :         _sibling->_namedPipe = 0;
     103             :         return false;
     104             :     }
     105             : 
     106             :     connection = _namedPipe->acceptSync();
     107             :     _namedPipe = static_cast<NamedPipeConnection*>(connection.get());
     108             :     return true;
     109             : }
     110             : 
     111             : void PipeConnection::_close()
     112             : {
     113             :     if (isClosed())
     114             :         return;
     115             : 
     116             :     _connected = false;
     117             :     _namedPipe->close();
     118             :     _namedPipe = 0;
     119             :     _sibling = 0;
     120             : 
     121             :     _setState(STATE_CLOSED);
     122             : }
     123             : 
     124             : void PipeConnection::readNB(void* buffer, const uint64_t bytes)
     125             : {
     126             :     if (isClosed())
     127             :         return;
     128             :     _namedPipe->readNB(buffer, bytes);
     129             : }
     130             : 
     131             : int64_t PipeConnection::readSync(void* buffer, const uint64_t bytes,
     132             :                                  const bool ignored)
     133             : {
     134             :     if (isClosed())
     135             :         return -1;
     136             : 
     137             :     const int64_t bytesRead = _namedPipe->readSync(buffer, bytes, ignored);
     138             : 
     139             :     if (bytesRead == -1)
     140             :         close();
     141             : 
     142             :     return bytesRead;
     143             : }
     144             : 
     145             : int64_t PipeConnection::write(const void* buffer, const uint64_t bytes)
     146             : {
     147             :     if (!isConnected())
     148             :         return -1;
     149             : 
     150             :     return _namedPipe->write(buffer, bytes);
     151             : }
     152             : 
     153             : #else  // !_WIN32
     154             : 
     155         107 : bool PipeConnection::_createPipes()
     156             : {
     157             :     int pipeFDs[2];
     158         107 :     if (::pipe(pipeFDs) == -1)
     159             :     {
     160           0 :         LBERROR << "Could not create pipe: " << strerror(errno);
     161           0 :         close();
     162           0 :         return false;
     163             :     }
     164             : 
     165         107 :     _readFD = pipeFDs[0];
     166         107 :     _sibling->_writeFD = pipeFDs[1];
     167             : 
     168         107 :     if (::pipe(pipeFDs) == -1)
     169             :     {
     170           0 :         LBERROR << "Could not create pipe: " << strerror(errno);
     171           0 :         close();
     172           0 :         return false;
     173             :     }
     174             : 
     175         107 :     _sibling->_readFD = pipeFDs[0];
     176         107 :     _writeFD = pipeFDs[1];
     177         107 :     return true;
     178             : }
     179             : 
     180         369 : void PipeConnection::_close()
     181             : {
     182         369 :     if (isClosed())
     183         161 :         return;
     184             : 
     185         208 :     if (_writeFD > 0)
     186             :     {
     187         208 :         ::close(_writeFD);
     188         208 :         _writeFD = 0;
     189             :     }
     190         208 :     if (_readFD > 0)
     191             :     {
     192         208 :         ::close(_readFD);
     193         208 :         _readFD = 0;
     194             :     }
     195             : 
     196         208 :     _connected = false;
     197         208 :     _setState(STATE_CLOSED);
     198         208 :     _sibling = 0;
     199             : }
     200             : #endif // else _WIN32
     201             : 
     202         342 : ConnectionPtr PipeConnection::acceptSync()
     203             : {
     204         342 :     _connected.waitEQ(true);
     205         342 :     return _sibling;
     206             : }
     207          63 : }

Generated by: LCOV version 1.11