LCOV - code coverage report
Current view: top level - co - pipeConnection.cpp (source / functions) Hit Total Coverage
Test: Collage Lines: 43 52 82.7 %
Date: 2016-12-14 01:26:48 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             : 
      37         222 : PipeConnection::PipeConnection()
      38             : {
      39         443 :     ConnectionDescriptionPtr description = _getDescription();
      40         222 :     description->type = CONNECTIONTYPE_PIPE;
      41         222 :     description->bandwidth = 1024000;
      42         222 : }
      43             : 
      44         648 : PipeConnection::~PipeConnection()
      45             : {
      46         216 :     _close();
      47         432 : }
      48             : 
      49             : //----------------------------------------------------------------------
      50             : // connect
      51             : //----------------------------------------------------------------------
      52         110 : bool PipeConnection::connect()
      53             : {
      54         110 :     LBASSERT( getDescription()->type == CONNECTIONTYPE_PIPE );
      55             : 
      56         111 :     if( !isClosed( ))
      57           0 :         return false;
      58             : 
      59         111 :     _setState( STATE_CONNECTING );
      60         111 :     _sibling = new PipeConnection;
      61         111 :     _sibling->_sibling = this;
      62             : 
      63         111 :     if( !_createPipes( ))
      64             :     {
      65           0 :         close();
      66           0 :         return false;
      67             :     }
      68             : 
      69         111 :     _setState( STATE_CONNECTED );
      70         111 :     _sibling->_setState( STATE_CONNECTED );
      71         111 :     _connected = true;
      72         111 :     return true;
      73             : }
      74             : 
      75             : #ifdef _WIN32
      76             : 
      77             : Connection::Notifier PipeConnection::getNotifier() const
      78             : {
      79             :     if( !_namedPipe )
      80             :         return 0;
      81             :     return _namedPipe->getNotifier();
      82             : }
      83             : 
      84             : bool PipeConnection::_createPipes()
      85             : {
      86             :     std::stringstream pipeName;
      87             :     pipeName << "\\\\.\\pipe\\Collage." << servus::make_UUID();
      88             : 
      89             :     ConnectionDescriptionPtr desc = new ConnectionDescription;
      90             :     desc->type = CONNECTIONTYPE_NAMEDPIPE;
      91             :     desc->setFilename( pipeName.str( ));
      92             : 
      93             :     ConnectionPtr connection = Connection::create( desc );
      94             :     _namedPipe = static_cast< NamedPipeConnection* >( connection.get( ));
      95             :     if( !_namedPipe->listen( ))
      96             :         return false;
      97             :     _namedPipe->acceptNB();
      98             : 
      99             :     connection = Connection::create( desc );
     100             :     _sibling->_namedPipe = static_cast<NamedPipeConnection*>(connection.get());
     101             :     if( !_sibling->_namedPipe->connect( ))
     102             :     {
     103             :         _sibling->_namedPipe = 0;
     104             :         return false;
     105             :     }
     106             : 
     107             :     connection = _namedPipe->acceptSync();
     108             :     _namedPipe = static_cast< NamedPipeConnection* >(connection.get( ));
     109             :     return true;
     110             : }
     111             : 
     112             : void PipeConnection::_close()
     113             : {
     114             :     if( isClosed( ))
     115             :         return;
     116             : 
     117             :     _connected = false;
     118             :     _namedPipe->close();
     119             :     _namedPipe = 0;
     120             :     _sibling = 0;
     121             : 
     122             :     _setState( STATE_CLOSED );
     123             : }
     124             : 
     125             : void PipeConnection::readNB( void* buffer, const uint64_t bytes )
     126             : {
     127             :     if( isClosed( ))
     128             :         return;
     129             :     _namedPipe->readNB( buffer, bytes );
     130             : }
     131             : 
     132             : int64_t PipeConnection::readSync( void* buffer, const uint64_t bytes,
     133             :                                        const bool ignored )
     134             : {
     135             :     if( isClosed( ))
     136             :         return -1;
     137             : 
     138             :     const int64_t bytesRead = _namedPipe->readSync( buffer, bytes, ignored );
     139             : 
     140             :     if( bytesRead == -1 )
     141             :         close();
     142             : 
     143             :     return bytesRead;
     144             : }
     145             : 
     146             : int64_t PipeConnection::write( const void* buffer, const uint64_t bytes )
     147             : {
     148             :     if( !isConnected( ))
     149             :         return -1;
     150             : 
     151             :     return _namedPipe->write( buffer, bytes );
     152             : }
     153             : 
     154             : #else // !_WIN32
     155             : 
     156         111 : bool PipeConnection::_createPipes()
     157             : {
     158             :     int pipeFDs[2];
     159         111 :     if( ::pipe( pipeFDs ) == -1 )
     160             :     {
     161           0 :         LBERROR << "Could not create pipe: " << strerror( errno );
     162           0 :         close();
     163           0 :         return false;
     164             :     }
     165             : 
     166         111 :     _readFD  = pipeFDs[0];
     167         111 :     _sibling->_writeFD = pipeFDs[1];
     168             : 
     169         111 :     if( ::pipe( pipeFDs ) == -1 )
     170             :     {
     171           0 :         LBERROR << "Could not create pipe: " << strerror( errno );
     172           0 :         close();
     173           0 :         return false;
     174             :     }
     175             : 
     176         111 :     _sibling->_readFD  = pipeFDs[0];
     177         111 :     _writeFD = pipeFDs[1];
     178         111 :     return true;
     179             : }
     180             : 
     181         329 : void PipeConnection::_close()
     182             : {
     183         329 :     if( isClosed( ))
     184         113 :         return;
     185             : 
     186         216 :     if( _writeFD > 0 )
     187             :     {
     188         216 :         ::close( _writeFD );
     189         216 :         _writeFD = 0;
     190             :     }
     191         216 :     if( _readFD > 0 )
     192             :     {
     193         216 :         ::close( _readFD );
     194         216 :         _readFD  = 0;
     195             :     }
     196             : 
     197         216 :     _connected = false;
     198         216 :     _setState( STATE_CLOSED );
     199         216 :     _sibling = 0;
     200             : }
     201             : #endif // else _WIN32
     202             : 
     203         359 : ConnectionPtr PipeConnection::acceptSync()
     204             : {
     205         359 :     _connected.waitEQ( true );
     206         359 :     return _sibling;
     207             : }
     208             : 
     209          66 : }

Generated by: LCOV version 1.11