| 716 | } |
| 717 | |
| 718 | void begin_accept(pni_acceptor_t *acceptor, accept_result_t *result) |
| 719 | { |
| 720 | // flag to divide this routine's logic into locked/unlocked mp portions |
| 721 | bool mp = acceptor->listen_sock->is_mp; |
| 722 | bool created = false; |
| 723 | |
| 724 | if (acceptor->listen_sock->closing) { |
| 725 | if (result) { |
| 726 | if (mp && result->new_sock && result->new_sock->socket != INVALID_SOCKET) |
| 727 | closesocket(result->new_sock->socket); |
| 728 | free(result); |
| 729 | acceptor->accept_queue_size--; |
| 730 | } |
| 731 | if (acceptor->accept_queue_size == 0) |
| 732 | acceptor->signalled = true; |
| 733 | return; |
| 734 | } |
| 735 | |
| 736 | if (result) { |
| 737 | if (!mp) |
| 738 | reset_accept_result(result); |
| 739 | } else { |
| 740 | if (acceptor->accept_queue_size < IOCP_MAX_ACCEPTS && (mp || |
| 741 | pn_list_size(acceptor->accepts) == acceptor->accept_queue_size )) { |
| 742 | result = accept_result(acceptor->listen_sock); |
| 743 | acceptor->accept_queue_size++; |
| 744 | created = true; |
| 745 | } else { |
| 746 | // an async accept is still pending or max concurrent accepts already hit |
| 747 | return; |
| 748 | } |
| 749 | } |
| 750 | |
| 751 | if (created || !mp) |
| 752 | result->new_sock = create_same_type_socket(acceptor->listen_sock); |
| 753 | if (result->new_sock) { |
| 754 | // Not yet connected. |
| 755 | result->new_sock->read_closed = true; |
| 756 | result->new_sock->write_closed = true; |
| 757 | |
| 758 | bool success = acceptor->fn_accept_ex(acceptor->listen_sock->socket, result->new_sock->socket, |
| 759 | result->address_buffer, 0, IOCP_SOCKADDRMAXLEN, IOCP_SOCKADDRMAXLEN, |
| 760 | &result->unused, (LPOVERLAPPED) result); |
| 761 | if (!success) { |
| 762 | DWORD err = WSAGetLastError(); |
| 763 | if (err != ERROR_IO_PENDING) { |
| 764 | if (err == WSAECONNRESET) { |
| 765 | // other side gave up. Ignore and try again. |
| 766 | begin_accept(acceptor, result); |
| 767 | return; |
| 768 | } |
| 769 | else { |
| 770 | iocpdesc_fail(acceptor->listen_sock, err, "AcceptEX call failure"); |
| 771 | return; |
| 772 | } |
| 773 | } |
| 774 | acceptor->listen_sock->ops_in_progress++; |
| 775 | // This socket is equally involved in the async operation. |
no test coverage detected