Line data Source code
1 :
2 : /* Copyright (c) 2005-2012, Stefan Eilemann <eile@equalizergraphics.com>
3 : *
4 : * This file is part of Collage <https://github.com/Eyescale/Collage>
5 : *
6 : * This library is free software; you can redistribute it and/or modify it under
7 : * the terms of the GNU Lesser General Public License version 2.1 as published
8 : * by the Free Software Foundation.
9 : *
10 : * This library is distributed in the hope that it will be useful, but WITHOUT
11 : * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 : * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
13 : * details.
14 : *
15 : * You should have received a copy of the GNU Lesser General Public License
16 : * along with this library; if not, write to the Free Software Foundation, Inc.,
17 : * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 : */
19 :
20 : #include "fdConnection.h"
21 :
22 : #include "connectionDescription.h"
23 : #include "exception.h"
24 : #include "global.h"
25 : #include "log.h"
26 :
27 : #include <lunchbox/os.h>
28 :
29 : #include <errno.h>
30 : #include <poll.h>
31 :
32 : namespace co
33 : {
34 354 : FDConnection::FDConnection()
35 : : _readFD( 0 ),
36 354 : _writeFD( 0 )
37 354 : {}
38 :
39 37 : int FDConnection::_getTimeOut()
40 : {
41 37 : const uint32_t timeout = Global::getTimeout();
42 37 : return timeout == LB_TIMEOUT_INDEFINITE ? -1 : int( timeout );
43 : }
44 :
45 : //----------------------------------------------------------------------
46 : // read
47 : //----------------------------------------------------------------------
48 2744999 : int64_t FDConnection::readSync( void* buffer, const uint64_t bytes, const bool )
49 : {
50 2744999 : if( _readFD < 1 )
51 0 : return -1;
52 :
53 2744999 : ssize_t bytesRead = ::read( _readFD, buffer, bytes );
54 2744999 : if( bytesRead > 0 )
55 2744962 : return bytesRead;
56 :
57 : //LBINFO << "1st " << bytesRead << " " << strerror( errno ) << std::endl;
58 37 : if( bytesRead == 0 || errno == EWOULDBLOCK || errno == EAGAIN )
59 : {
60 : struct pollfd fds[1];
61 37 : fds[0].fd = _readFD;
62 37 : fds[0].events = POLLIN;
63 :
64 37 : const int res = poll( fds, 1, _getTimeOut( ));
65 37 : if( res < 0 )
66 : {
67 0 : LBWARN << "Error during read : " << strerror( errno ) << std::endl;
68 0 : return -1;
69 : }
70 :
71 37 : if( res == 0 )
72 0 : throw Exception( Exception::TIMEOUT_READ );
73 :
74 37 : bytesRead = ::read( _readFD, buffer, bytes );
75 : //LBINFO << "2nd " << bytesRead << " " << strerror(errno) << std::endl;
76 : }
77 :
78 37 : if( bytesRead > 0 )
79 0 : return bytesRead;
80 :
81 37 : if( bytesRead == 0 ) // EOF
82 : {
83 185 : LBINFO << "Got EOF, closing " << getDescription()->toString()
84 148 : << std::endl;
85 37 : close();
86 37 : return -1;
87 : }
88 :
89 0 : LBASSERT( bytesRead == -1 ); // error
90 :
91 0 : if( errno == EINTR ) // if interrupted, try again
92 0 : return 0;
93 :
94 0 : LBWARN << "Error during read: " << strerror( errno ) << ", " << bytes
95 0 : << "b on fd " << _readFD << std::endl;
96 0 : return -1;
97 : }
98 :
99 : //----------------------------------------------------------------------
100 : // write
101 : //----------------------------------------------------------------------
102 2768375 : int64_t FDConnection::write( const void* buffer, const uint64_t bytes )
103 : {
104 2768375 : if( !isConnected() || _writeFD < 1 )
105 0 : return -1;
106 :
107 2769528 : ssize_t bytesWritten = ::write( _writeFD, buffer, bytes );
108 2770494 : if( bytesWritten > 0 )
109 2770494 : return bytesWritten;
110 :
111 0 : if( bytesWritten == 0 || errno == EWOULDBLOCK || errno == EAGAIN )
112 : {
113 : struct pollfd fds[1];
114 0 : fds[0].fd = _writeFD;
115 0 : fds[0].events = POLLOUT;
116 0 : const int res = poll( fds, 1, _getTimeOut( ));
117 0 : if (res < 0)
118 : {
119 0 : LBWARN << "Write error: " << lunchbox::sysError << std::endl;
120 0 : return -1;
121 : }
122 :
123 0 : if( res == 0)
124 0 : throw Exception( Exception::TIMEOUT_WRITE );
125 :
126 0 : bytesWritten = ::write( _writeFD, buffer, bytes );
127 : }
128 :
129 0 : if( bytesWritten > 0 )
130 0 : return bytesWritten;
131 :
132 0 : if( bytesWritten == -1 ) // error
133 : {
134 0 : if( errno == EINTR ) // if interrupted, try again
135 0 : return 0;
136 :
137 0 : LBWARN << "Error during write: " << lunchbox::sysError << std::endl;
138 0 : return -1;
139 : }
140 :
141 0 : return bytesWritten;
142 : }
143 60 : }
|