[[using maybe_locked(m_GlobControlLock, if called from breakSocket_LOCKED, usually from GC)]] [[using maybe_locked(m_parent->m_ControlLock, if called from srt_close())]]
| 6460 | // [[using maybe_locked(m_GlobControlLock, if called from breakSocket_LOCKED, usually from GC)]] |
| 6461 | // [[using maybe_locked(m_parent->m_ControlLock, if called from srt_close())]] |
| 6462 | bool srt::CUDT::closeInternal() ATR_NOEXCEPT |
| 6463 | { |
| 6464 | // NOTE: this function is called from within the garbage collector thread. |
| 6465 | |
| 6466 | if (!m_bOpened) |
| 6467 | { |
| 6468 | return false; |
| 6469 | } |
| 6470 | |
| 6471 | // IMPORTANT: |
| 6472 | // This function may block indefinitely, if called for a socket |
| 6473 | // that has m_bBroken == false or m_bConnected == true. |
| 6474 | // If it is intended to forcefully close the socket, make sure |
| 6475 | // that it's in response to a broken connection. |
| 6476 | HLOGC(smlog.Debug, log << CONID() << "closing socket"); |
| 6477 | |
| 6478 | if (m_config.Linger.l_onoff != 0) |
| 6479 | { |
| 6480 | const steady_clock::time_point entertime = steady_clock::now(); |
| 6481 | |
| 6482 | HLOGC(smlog.Debug, log << CONID() << "... (linger)"); |
| 6483 | while (!m_bBroken && m_bConnected && (m_pSndBuffer->getCurrBufSize() > 0) && |
| 6484 | (steady_clock::now() - entertime < seconds_from(m_config.Linger.l_linger))) |
| 6485 | { |
| 6486 | // linger has been checked by previous close() call and has expired |
| 6487 | if (m_tsLingerExpiration >= entertime) |
| 6488 | break; |
| 6489 | |
| 6490 | if (!m_config.bSynSending) |
| 6491 | { |
| 6492 | // if this socket enables asynchronous sending, return immediately and let GC to close it later |
| 6493 | if (is_zero(m_tsLingerExpiration)) |
| 6494 | m_tsLingerExpiration = entertime + seconds_from(m_config.Linger.l_linger); |
| 6495 | |
| 6496 | HLOGC(smlog.Debug, |
| 6497 | log << CONID() << "CUDT::close: linger-nonblocking, setting expire time T=" |
| 6498 | << FormatTime(m_tsLingerExpiration)); |
| 6499 | |
| 6500 | return false; |
| 6501 | } |
| 6502 | |
| 6503 | #ifndef _WIN32 |
| 6504 | timespec ts; |
| 6505 | ts.tv_sec = 0; |
| 6506 | ts.tv_nsec = 1000000; |
| 6507 | nanosleep(&ts, NULL); |
| 6508 | #else |
| 6509 | Sleep(1); |
| 6510 | #endif |
| 6511 | } |
| 6512 | } |
| 6513 | |
| 6514 | // remove this socket from the snd queue |
| 6515 | if (m_bConnected) |
| 6516 | m_pSndQueue->m_pSndUList->remove(this); |
| 6517 | |
| 6518 | /* |
| 6519 | * update_events below useless |
no test coverage detected