• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

OpenLightingProject / ola / 17141553775

21 Aug 2025 11:23PM UTC coverage: 45.72% (-0.02%) from 45.742%
17141553775

push

github

web-flow
Merge pull request #2014 from peternewman/mac-be

Tidy the Mac OS Endian behaviour

7586 of 17462 branches covered (43.44%)

22424 of 49046 relevant lines covered (45.72%)

53.43 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

85.45
/common/network/AdvancedTCPConnector.cpp
1
/*
2
 * This library is free software; you can redistribute it and/or
3
 * modify it under the terms of the GNU Lesser General Public
4
 * License as published by the Free Software Foundation; either
5
 * version 2.1 of the License, or (at your option) any later version.
6
 *
7
 * This library is distributed in the hope that it will be useful,
8
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
10
 * Lesser General Public License for more details.
11
 *
12
 * You should have received a copy of the GNU Lesser General Public
13
 * License along with this library; if not, write to the Free Software
14
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
15
 *
16
 * AdvancedTCPConnector.cpp
17
 * Copyright (C) 2012 Simon Newton
18
 */
19

20
#include <ola/Callback.h>
21
#include <ola/Logging.h>
22
#include <ola/io/SelectServerInterface.h>
23
#include <ola/network/AdvancedTCPConnector.h>
24
#include <ola/network/TCPConnector.h>
25

26

27
namespace ola {
28
namespace network {
29

30
using std::pair;
31

32
AdvancedTCPConnector::AdvancedTCPConnector(
6✔
33
    ola::io::SelectServerInterface *ss,
34
    TCPSocketFactoryInterface *socket_factory,
35
    const ola::TimeInterval &connection_timeout)
6✔
36
    : m_socket_factory(socket_factory),
6✔
37
      m_ss(ss),
6✔
38
      m_connector(ss),
6✔
39
      m_connection_timeout(connection_timeout) {
6✔
40
}
6✔
41

42
AdvancedTCPConnector::~AdvancedTCPConnector() {
6✔
43
  ConnectionMap::iterator iter = m_connections.begin();
6✔
44
  for (; iter != m_connections.end(); ++iter) {
8✔
45
    AbortConnection(iter->second);
2✔
46
    delete iter->second;
2✔
47
  }
48
  m_connections.clear();
6✔
49
}
6✔
50

51

52
void AdvancedTCPConnector::AddEndpoint(const IPV4SocketAddress &endpoint,
5✔
53
                                       BackOffPolicy *backoff_policy,
54
                                       bool paused) {
55
  IPPortPair key(endpoint.Host(), endpoint.Port());
5✔
56
  ConnectionMap::iterator iter = m_connections.find(key);
5✔
57
  if (iter != m_connections.end())
5✔
58
    return;
×
59

60
  // new ip:port
61
  ConnectionInfo *state = new ConnectionInfo;
5✔
62
  state->state = paused ? PAUSED : DISCONNECTED;
5✔
63
  state->failed_attempts = 0;
5✔
64
  state->retry_timeout = ola::thread::INVALID_TIMEOUT;
5✔
65
  state->connection_id = 0;
5✔
66
  state->policy = backoff_policy;
5✔
67
  state->reconnect = true;
5✔
68

69
  m_connections[key] = state;
5✔
70

71
  if (!paused)
5✔
72
    AttemptConnection(key, state);
4✔
73
}
74

75
void AdvancedTCPConnector::RemoveEndpoint(const IPV4SocketAddress &endpoint) {
3✔
76
  IPPortPair key(endpoint.Host(), endpoint.Port());
3✔
77
  ConnectionMap::iterator iter = m_connections.find(key);
3✔
78
  if (iter == m_connections.end())
3✔
79
    return;
×
80

81
  AbortConnection(iter->second);
3✔
82
  delete iter->second;
3✔
83
  m_connections.erase(iter);
3✔
84
}
85

86
bool AdvancedTCPConnector::GetEndpointState(
10✔
87
    const IPV4SocketAddress &endpoint,
88
    ConnectionState *connected,
89
    unsigned int *failed_attempts) const {
90
  IPPortPair key(endpoint.Host(), endpoint.Port());
10✔
91
  ConnectionMap::const_iterator iter = m_connections.find(key);
10✔
92
  if (iter == m_connections.end())
10✔
93
    return false;
94

95
  *connected = iter->second->state;
10✔
96
  *failed_attempts = iter->second->failed_attempts;
10✔
97
  return true;
10✔
98
}
99

100
void AdvancedTCPConnector::Disconnect(const IPV4SocketAddress &endpoint,
2✔
101
                                      bool pause) {
102
  IPPortPair key(endpoint.Host(), endpoint.Port());
2✔
103
  ConnectionMap::iterator iter = m_connections.find(key);
2✔
104
  if (iter == m_connections.end())
2✔
105
    return;
×
106

107
  if (iter->second->state != CONNECTED)
2✔
108
    return;
109

110
  iter->second->failed_attempts = 0;
2✔
111

112
  if (pause) {
2✔
113
    iter->second->state = PAUSED;
2✔
114
  } else {
115
    // schedule a retry as if this endpoint failed once
116
    iter->second->state = DISCONNECTED;
×
117
    iter->second->retry_timeout = m_ss->RegisterSingleTimeout(
×
118
        iter->second->policy->BackOffTime(1),
×
119
        ola::NewSingleCallback(
×
120
          this,
121
          &AdvancedTCPConnector::RetryTimeout,
122
          iter->first));
×
123
  }
124
}
125

126
void AdvancedTCPConnector::Resume(const IPV4SocketAddress &endpoint) {
1✔
127
  IPPortPair key(endpoint.Host(), endpoint.Port());
1✔
128
  ConnectionMap::iterator iter = m_connections.find(key);
1✔
129
  if (iter == m_connections.end())
1✔
130
    return;
×
131

132
  if (iter->second->state == PAUSED) {
1✔
133
    iter->second->state = DISCONNECTED;
1✔
134
    AttemptConnection(iter->first, iter->second);
1✔
135
  }
136
}
137

138
/**
139
 * Schedule the re-try attempt for this connection
140
 */
141
void AdvancedTCPConnector::ScheduleRetry(const IPPortPair &key,
2✔
142
                                         ConnectionInfo *info) {
143
  info->retry_timeout = m_ss->RegisterSingleTimeout(
4✔
144
      info->policy->BackOffTime(info->failed_attempts),
2✔
145
      ola::NewSingleCallback(
2✔
146
        this,
147
        &AdvancedTCPConnector::RetryTimeout,
148
        key));
149
}
2✔
150

151

152
/**
153
 * Called when it's time to retry
154
 */
155
void AdvancedTCPConnector::RetryTimeout(IPPortPair key) {
1✔
156
  ConnectionMap::iterator iter = m_connections.find(key);
1✔
157
  if (iter == m_connections.end()) {
1✔
158
    OLA_FATAL << "Re-connect timer expired but unable to find state entry for "
×
159
      << key.first << ":" << key.second;
×
160
    return;
×
161
  }
162
  iter->second->retry_timeout = ola::thread::INVALID_TIMEOUT;
1✔
163
  AttemptConnection(key, iter->second);
1✔
164
}
165

166

167
/**
168
 * Called by the TCPConnector when a connection is ready or it times out.
169
 */
170
void AdvancedTCPConnector::ConnectionResult(IPPortPair key, int fd, int) {
6✔
171
  if (fd != -1) {
6✔
172
    OLA_INFO << "TCP Connection established to " << key.first << ":" <<
6✔
173
      key.second;
3✔
174
  }
175

176
  ConnectionMap::iterator iter = m_connections.find(key);
6✔
177
  if (iter == m_connections.end()) {
6✔
178
    OLA_FATAL << "Unable to find state for " << key.first << ":" <<
×
179
      key.second << ", leaking sockets";
×
180
    return;
×
181
  }
182
  ConnectionInfo *info = iter->second;
6✔
183

184
  info->connection_id = 0;
6✔
185
  if (fd != -1) {
6✔
186
    // ok
187
    info->state = CONNECTED;
3✔
188
    m_socket_factory->NewTCPSocket(fd);
3✔
189
  } else {
190
    // error
191
    info->failed_attempts++;
3✔
192
    if (info->reconnect) {
3✔
193
      ScheduleRetry(key, info);
2✔
194
    }
195
  }
196
}
197

198

199
/**
200
 * Initiate a connection to this ip:port pair
201
 */
202
void AdvancedTCPConnector::AttemptConnection(const IPPortPair &key,
6✔
203
                                             ConnectionInfo *state) {
204
  state->connection_id = m_connector.Connect(
6✔
205
      IPV4SocketAddress(key.first, key.second),
12✔
206
      m_connection_timeout,
6✔
207
      ola::NewSingleCallback(this,
6✔
208
                             &AdvancedTCPConnector::ConnectionResult,
209
                             key));
210
}
6✔
211

212

213
/**
214
 * Abort and clean up a pending connection
215
 * @param state the ConnectionInfo to cleanup.
216
 */
217
void AdvancedTCPConnector::AbortConnection(ConnectionInfo *state) {
5✔
218
  if (state->connection_id) {
5✔
219
    state->reconnect = false;
1✔
220
    if (!m_connector.Cancel(state->connection_id))
1✔
221
      OLA_WARN << "Failed to cancel connection " << state->connection_id;
×
222
  }
223
  if (state->retry_timeout != ola::thread::INVALID_TIMEOUT)
5✔
224
    m_ss->RemoveTimeout(state->retry_timeout);
1✔
225
}
5✔
226
}  // namespace network
227
}  // namespace ola
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc