Skip to content

Commit fd6399b

Browse files
committed
time out when audio server fails accept connection
1 parent 7e6efe9 commit fd6399b

3 files changed

Lines changed: 71 additions & 63 deletions

File tree

src/OpenCOVER/audio/Player.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,14 @@ Player *Player::createPlayer(Listener *listener, const std::string &type, bool i
130130
// config file and parse it itself.
131131
std::string host = coCoviseConfig::getEntry("value", "COVER.Audio.Host", "localhost");
132132
int port = coCoviseConfig::getInt("port", "COVER.Audio.Host", 31231);
133-
return new PlayerAServer(listener, host, port, isMa);
133+
auto player = new PlayerAServer(listener, host, port, isMa);
134+
if (!player->isConnected())
135+
{
136+
std::cerr << "PlayerAServer: could not connect to audio server at " << host << ":" << port << endl;
137+
delete player;
138+
return nullptr;
139+
}
140+
return player;
134141
}
135142
else if (boost::iequals(type, "openal"))
136143
{

src/OpenCOVER/audio/PlayerAServer.cpp

Lines changed: 62 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,9 @@ using namespace opencover::audio;
3232

3333
#define MAX_BUFLEN 1024
3434

35-
inline int errno_sys()
35+
namespace {
36+
37+
int errno_sys()
3638
{
3739
#ifdef _WIN32
3840
return WSAGetLastError();
@@ -41,6 +43,15 @@ inline int errno_sys()
4143
#endif
4244
}
4345

46+
#ifdef _WIN32
47+
int close(int fd)
48+
{
49+
return closesocket(fd);
50+
}
51+
#endif
52+
53+
}
54+
4455
PlayerAServer::PlayerAServer(const Listener *listener, const std::string &host, int port, bool isMaster)
4556
: Player(listener,isMaster)
4657
, asFd(-1)
@@ -80,44 +91,22 @@ void PlayerAServer::connect()
8091
return;
8192
}
8293

83-
asFd = (int)socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
94+
asFd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
8495
if (asFd == -1)
8596
{
8697
CERR << "opening socket failed" << endl;
8798
return;
8899
}
89100

90-
struct sockaddr_in hostaddr;
91-
memset(&hostaddr, 0, sizeof(hostaddr));
92-
hostaddr.sin_family = AF_INET;
93-
int sourceport = 31431;
94-
hostaddr.sin_port = htons(sourceport);
95-
hostaddr.sin_addr.s_addr = INADDR_ANY;
96-
while (bind(asFd, (struct sockaddr *)&hostaddr, sizeof(hostaddr)) < 0)
101+
if (fcntl(asFd, F_SETFL, O_NONBLOCK) == -1)
97102
{
98-
#ifndef _WIN32
99-
if (errno == EADDRINUSE)
100-
#else
101-
if (GetLastError() == WSAEADDRINUSE)
102-
#endif
103-
{
104-
sourceport++;
105-
hostaddr.sin_port = htons(sourceport);
106-
}
107-
else
108-
{
109-
110-
#ifdef WIN32
111-
closesocket(asFd);
112-
#else
113-
close(asFd);
114-
#endif
115-
CERR << "binding socket failed: " << strerror(errno_sys()) << endl;
116-
asFd = -1;
117-
return;
118-
}
103+
CERR << "making socket non-blocking failed" << endl;
104+
close(asFd);
105+
asFd = -1;
106+
return;
119107
}
120108

109+
struct sockaddr_in hostaddr;
121110
memset(&hostaddr, 0, sizeof(hostaddr));
122111
hostaddr.sin_family = AF_INET;
123112
hostaddr.sin_port = htons((unsigned short)asPort);
@@ -134,22 +123,48 @@ void PlayerAServer::connect()
134123

135124
if (::connect(asFd, (struct sockaddr *)&hostaddr, sizeof(hostaddr)) == -1)
136125
{
126+
auto error = errno_sys();
127+
if (error != EINPROGRESS
137128
#ifdef WIN32
138-
int error = WSAGetLastError();
139-
// cerr << "error:" <<error << endl;
140-
if (error != WSAEISCONN) // this is a weird Windows specific necessity!
129+
|| error != WSAEISCONN // this is a weird Windows specific necessity!
130+
#endif
131+
)
141132
{
142-
// closesocket(asFd);
143-
#else
144-
close(asFd);
133+
CERR << "connecting socket failed: " << strerror(errno_sys()) << endl;
134+
close(asFd);
135+
asFd = -1;
136+
return;
137+
}
138+
}
145139

146-
CERR << "connecting socket failed: " << strerror(errno_sys()) << endl;
147-
asFd = -1;
148-
return;
149-
#endif
150-
#ifdef WIN32
140+
fd_set fdset;
141+
FD_ZERO(&fdset);
142+
FD_SET(asFd, &fdset);
143+
struct timeval tv;
144+
tv.tv_sec = 3;
145+
tv.tv_usec = 0;
146+
147+
if (select(asFd + 1, NULL, &fdset, NULL, &tv) == 1)
148+
{
149+
int so_error;
150+
socklen_t len = sizeof so_error;
151+
152+
getsockopt(asFd, SOL_SOCKET, SO_ERROR, &so_error, &len);
153+
154+
if (so_error != 0) {
155+
CERR << "connecting socket failed: " << strerror(errno_sys()) << endl;
156+
close(asFd);
157+
asFd = -1;
158+
return;
159+
}
160+
161+
if (fcntl(asFd, F_SETFL, 0) == -1)
162+
{
163+
CERR << "making socket blocking again failed" << endl;
164+
close(asFd);
165+
asFd = -1;
166+
return;
151167
}
152-
#endif
153168
}
154169

155170
cerr << " ok." << endl;
@@ -160,14 +175,15 @@ void PlayerAServer::connect()
160175
PlayerAServer::~PlayerAServer()
161176
{
162177
if (asFd != -1)
163-
#ifdef WIN32
164-
closesocket(asFd);
165-
#else
166178
close(asFd);
167-
#endif
168179
asFd = -1;
169180
}
170181

182+
bool PlayerAServer::isConnected() const
183+
{
184+
return asFd != -1;
185+
}
186+
171187
int PlayerAServer::send_cmd(const char *cmd) const
172188
{
173189
// fprintf(stderr, "AudioServer: %s\n", cmd);
@@ -264,11 +280,7 @@ int PlayerAServer::send_data(const char *data, int size, bool swapped) const
264280

265281
if (written != size)
266282
{
267-
#ifdef WIN32
268-
closesocket(asFd);
269-
#else
270283
close(asFd);
271-
#endif
272284
// CERR << "asFd reset1: " << asFd<< endl;
273285
asFd = -1;
274286
return -1;
@@ -293,22 +305,14 @@ int PlayerAServer::read_answer(char *buf, int maxsize) const
293305
if (ret < 0)
294306
{
295307
CERR << "select failed: " << strerror(errno_sys()) << endl;
296-
#ifdef WIN32
297-
closesocket(asFd);
298-
#else
299308
close(asFd);
300-
#endif
301309
asFd = -1;
302310
return -1;
303311
}
304312
if (ret == 0)
305313
{
306314
CERR << "timed out" << endl;
307-
#ifdef WIN32
308-
closesocket(asFd);
309-
#else
310315
close(asFd);
311-
#endif
312316
asFd = -1;
313317
return -1;
314318
}
@@ -324,11 +328,7 @@ int PlayerAServer::read_answer(char *buf, int maxsize) const
324328

325329
if (n < 0)
326330
{
327-
#ifdef WIN32
328-
closesocket(asFd);
329-
#else
330331
close(asFd);
331-
#endif
332332
asFd = -1;
333333
return -1;
334334
}

src/OpenCOVER/audio/PlayerAServer.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ class COVRAUDIOEXPORT PlayerAServer : public Player
2525
virtual int send_cmd(const char *cmd) const;
2626
virtual int send_data(const char *data, int size, bool swapped = false) const;
2727
virtual int read_answer(char *buf, int maxsize) const;
28+
bool isConnected() const;
2829

2930
protected:
3031
void connect();

0 commit comments

Comments
 (0)