| 282 | } |
| 283 | |
| 284 | static Result ConnectSocket(HPool pool, Connection* connection, dmSocket::Address address, uint16_t port, int timeout, dmSocket::Socket* socket, dmSocket::Result* sr) |
| 285 | { |
| 286 | *sr = dmSocket::New(address.m_family, dmSocket::TYPE_STREAM, dmSocket::PROTOCOL_TCP, socket); |
| 287 | if (*sr != dmSocket::RESULT_OK) { |
| 288 | return RESULT_SOCKET_ERROR; |
| 289 | } |
| 290 | |
| 291 | // Publish the raw socket as soon as it exists so pool shutdown can interrupt both |
| 292 | // an in-flight TCP connect and a subsequent SSL handshake. If shutdown already claimed |
| 293 | // the slot before we could publish, abort immediately instead of continuing with an |
| 294 | // untracked socket. |
| 295 | if (!PublishInProgressSocket(pool, connection, socket)) |
| 296 | { |
| 297 | *sr = dmSocket::RESULT_CONNABORTED; |
| 298 | CloseInProgressSocket(pool, connection, socket); |
| 299 | return RESULT_SHUT_DOWN; |
| 300 | } |
| 301 | |
| 302 | if( timeout > 0 ) |
| 303 | { |
| 304 | *sr = dmSocket::SetBlocking(*socket, false); |
| 305 | if (*sr != dmSocket::RESULT_OK) { |
| 306 | CloseInProgressSocket(pool, connection, socket); |
| 307 | return RESULT_SOCKET_ERROR; |
| 308 | } |
| 309 | |
| 310 | *sr = dmSocket::Connect(*socket, address, port); |
| 311 | if (*sr != dmSocket::RESULT_OK) { |
| 312 | CloseInProgressSocket(pool, connection, socket); |
| 313 | return RESULT_SOCKET_ERROR; |
| 314 | } |
| 315 | |
| 316 | dmSocket::Selector selector; |
| 317 | dmSocket::SelectorZero(&selector); |
| 318 | dmSocket::SelectorSet(&selector, dmSocket::SELECTOR_KIND_WRITE, *socket); |
| 319 | |
| 320 | *sr = dmSocket::Select(&selector, timeout); |
| 321 | if( *sr == dmSocket::RESULT_WOULDBLOCK ) |
| 322 | { |
| 323 | CloseInProgressSocket(pool, connection, socket); |
| 324 | return RESULT_SOCKET_ERROR; |
| 325 | } |
| 326 | |
| 327 | *sr = dmSocket::SetBlocking(*socket, true); |
| 328 | if (*sr != dmSocket::RESULT_OK) { |
| 329 | CloseInProgressSocket(pool, connection, socket); |
| 330 | return RESULT_SOCKET_ERROR; |
| 331 | } |
| 332 | } |
| 333 | else |
| 334 | { |
| 335 | *sr = dmSocket::Connect(*socket, address, port); |
| 336 | if (*sr != dmSocket::RESULT_OK) { |
| 337 | CloseInProgressSocket(pool, connection, socket); |
| 338 | return RESULT_SOCKET_ERROR; |
| 339 | } |
| 340 | } |
| 341 |
no test coverage detected