| 1735 | #endif // !defined(WIN_NT) |
| 1736 | |
| 1737 | static void disconnect(rem_port* port) |
| 1738 | { |
| 1739 | /************************************** |
| 1740 | * |
| 1741 | * d i s c o n n e c t |
| 1742 | * |
| 1743 | ************************************** |
| 1744 | * |
| 1745 | * Functional description |
| 1746 | * Break a remote connection. |
| 1747 | * |
| 1748 | **************************************/ |
| 1749 | |
| 1750 | // SO_LINGER was turned off on the initial bind when the server was started. |
| 1751 | // This will force a reset to be sent to the client when the socket is closed. |
| 1752 | // We only want this behavior in the case of the server terminating |
| 1753 | // abnormally and not on an orderly shut down. Because of this, turn the |
| 1754 | // SO_LINGER option back on for the socket. The result of setsockopt isn't |
| 1755 | // too important at this stage since we are closing the socket anyway. This |
| 1756 | // is an attempt to return the socket to a state where a graceful shutdown can |
| 1757 | // occur. |
| 1758 | |
| 1759 | if (port->port_linger.l_onoff) |
| 1760 | { |
| 1761 | setsockopt(port->port_handle, SOL_SOCKET, SO_LINGER, |
| 1762 | (SCHAR*) &port->port_linger, sizeof(port->port_linger)); |
| 1763 | } |
| 1764 | |
| 1765 | if (port->port_handle != INVALID_SOCKET) |
| 1766 | { |
| 1767 | shutdown(port->port_handle, 2); |
| 1768 | } |
| 1769 | |
| 1770 | MutexLockGuard guard(port_mutex, FB_FUNCTION); |
| 1771 | if (port->port_state == rem_port::DISCONNECTED) |
| 1772 | return; |
| 1773 | |
| 1774 | port->port_state = rem_port::DISCONNECTED; |
| 1775 | port->port_flags &= ~PORT_connecting; |
| 1776 | |
| 1777 | if (port->port_async) |
| 1778 | { |
| 1779 | disconnect(port->port_async); |
| 1780 | port->port_async = NULL; |
| 1781 | } |
| 1782 | port->port_context = NULL; |
| 1783 | |
| 1784 | // hvlad: delay closing of the server sockets to prevent its reuse |
| 1785 | // by another (newly accepted) port until next select() call. See |
| 1786 | // also select_wait() function. |
| 1787 | const bool delayClose = (port->port_server_flags && port->port_parent); |
| 1788 | |
| 1789 | // If this is a sub-port, unlink it from its parent |
| 1790 | port->unlinkParent(); |
| 1791 | |
| 1792 | inet_ports->unRegisterPort(port); |
| 1793 | |
| 1794 | if (delayClose) |
no test coverage detected