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 222 : 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 442 : 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 361 : ConnectionPtr PipeConnection::acceptSync()
204 : {
205 361 : _connected.waitEQ( true );
206 361 : return _sibling;
207 : }
208 :
209 66 : }
|