re-merged rt18194 after fixing problems

This commit is contained in:
Evan Hunt
2008-07-03 00:15:09 +00:00
parent 3367fe8dc6
commit c6159a2ae8
4 changed files with 61 additions and 94 deletions
+15 -3
View File
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: dispatch.c,v 1.101.2.6.2.26 2008/06/26 22:19:00 jinmei Exp $ */
/* $Id: dispatch.c,v 1.101.2.6.2.27 2008/07/03 00:15:08 each Exp $ */
#include <config.h>
@@ -799,6 +799,8 @@ destroy_dispsocket(dns_dispatch_t *disp, dispsocket_t **dispsockp) {
*/
static void
deactivate_dispsocket(dns_dispatch_t *disp, dispsocket_t *dispsock) {
isc_result_t result;
/*
* The dispatch must be locked.
*/
@@ -811,8 +813,18 @@ deactivate_dispsocket(dns_dispatch_t *disp, dispsocket_t *dispsock) {
if (disp->nsockets > DNS_DISPATCH_POOLSOCKS)
destroy_dispsocket(disp, &dispsock);
else {
isc_socket_close(dispsock->socket);
ISC_LIST_APPEND(disp->inactivesockets, dispsock, link);
result = isc_socket_close(dispsock->socket);
if (result == ISC_R_SUCCESS)
ISC_LIST_APPEND(disp->inactivesockets, dispsock, link);
else {
/*
* If the underlying system does not allow this
* optimization, destroy this temporary structure (and
* create a new one for a new transaction).
*/
INSIST(result == ISC_R_NOTIMPLEMENTED);
destroy_dispsocket(disp, &dispsock);
}
}
}
+10 -4
View File
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: socket.h,v 1.54.12.9 2008/06/25 23:45:37 tbox Exp $ */
/* $Id: socket.h,v 1.54.12.10 2008/07/03 00:15:08 each Exp $ */
#ifndef ISC_SOCKET_H
#define ISC_SOCKET_H 1
@@ -314,7 +314,8 @@ isc_socket_open(isc_socket_t *sock);
* avoid overhead of destroying and creating sockets when many short-lived
* sockets are frequently opened and closed. When the efficiency is not an
* issue, it should be safer to detach the unused socket and re-create a new
* one.
* one. This optimization may not be available for some systems, in which
* case this function will return ISC_R_NOTIMPLEMENTED and must not be used.
*
* Requires:
*
@@ -324,15 +325,18 @@ isc_socket_open(isc_socket_t *sock);
*
* Returns:
* Same as isc_socket_create().
* \li ISC_R_NOTIMPLEMENTED
*/
void
isc_result_t
isc_socket_close(isc_socket_t *sock);
/*
* Close a socket file descriptor of the given socket structure. This function
* is provided as an alternative to destroying an unused socket when overhead
* destroying/re-creating sockets can be significant, and is expected to be
* used with isc_socket_open().
* used with isc_socket_open(). This optimization may not be available for some
* systems, in which case this function will return ISC_R_NOTIMPLEMENTED and
* must not be used.
*
* Requires:
*
@@ -342,6 +346,8 @@ isc_socket_close(isc_socket_t *sock);
*
* \li There must be no pending I/O requests.
*
* Returns:
* \li #ISC_R_NOTIMPLEMENTED
*/
isc_result_t
+4 -2
View File
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: socket.c,v 1.207.2.19.2.39 2008/06/25 23:45:37 tbox Exp $ */
/* $Id: socket.c,v 1.207.2.19.2.40 2008/07/03 00:15:09 each Exp $ */
#include <config.h>
@@ -2068,7 +2068,7 @@ isc_socket_detach(isc_socket_t **socketp) {
*socketp = NULL;
}
void
isc_result_t
isc_socket_close(isc_socket_t *sock) {
int fd;
@@ -2102,6 +2102,8 @@ isc_socket_close(isc_socket_t *sock) {
isc_sockaddr_any(&sock->address);
closesocket(sock->manager, sock->type, fd);
return (ISC_R_SUCCESS);
}
/*
+32 -85
View File
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: socket.c,v 1.5.2.13.2.27 2008/07/01 05:40:13 jinmei Exp $ */
/* $Id: socket.c,v 1.5.2.13.2.28 2008/07/03 00:15:09 each Exp $ */
/* This code has been rewritten to take advantage of Windows Sockets
* I/O Completion Ports and Events. I/O Completion Ports is ONLY
@@ -1166,7 +1166,7 @@ build_msghdr_send(isc_socket_t *sock, isc_socketevent_t *dev,
memset(msg, 0, sizeof(*msg));
if (!sock->connected) {
if (sock->type == isc_sockettype_udp) {
msg->msg_name = (void *)&dev->address.type.sa;
msg->msg_namelen = dev->address.length;
} else {
@@ -1855,8 +1855,16 @@ free_socket(isc_socket_t **socketp) {
*socketp = NULL;
}
static isc_result_t
internal_open(isc_socketmgr_t *manager, isc_socket_t *sock) {
/*
* Create a new 'type' socket managed by 'manager'. Events
* will be posted to 'task' and when dispatched 'action' will be
* called with 'arg' as the arg value. The new socket is returned
* in 'socketp'.
*/
isc_result_t
isc_socket_create(isc_socketmgr_t *manager, int pf, isc_sockettype_t type,
isc_socket_t **socketp) {
isc_socket_t *sock = NULL;
isc_result_t result;
#if defined(USE_CMSG)
int on = 1;
@@ -1864,9 +1872,17 @@ internal_open(isc_socketmgr_t *manager, isc_socket_t *sock) {
int socket_errno;
char strbuf[ISC_STRERRORSIZE];
switch (sock->type) {
REQUIRE(VALID_MANAGER(manager));
REQUIRE(socketp != NULL && *socketp == NULL);
result = allocate_socket(manager, type, &sock);
if (result != ISC_R_SUCCESS)
return (result);
sock->pf = pf;
switch (type) {
case isc_sockettype_udp:
sock->fd = socket(sock->pf, SOCK_DGRAM, IPPROTO_UDP);
sock->fd = socket(pf, SOCK_DGRAM, IPPROTO_UDP);
if (sock->fd != INVALID_SOCKET) {
result = connection_reset_fix(sock->fd);
if (result != ISC_R_SUCCESS) {
@@ -1877,12 +1893,13 @@ internal_open(isc_socketmgr_t *manager, isc_socket_t *sock) {
}
break;
case isc_sockettype_tcp:
sock->fd = socket(sock->pf, SOCK_STREAM, IPPROTO_TCP);
sock->fd = socket(pf, SOCK_STREAM, IPPROTO_TCP);
break;
}
if (sock->fd == INVALID_SOCKET) {
socket_errno = WSAGetLastError();
free_socket(&sock);
switch (socket_errno) {
case WSAEMFILE:
@@ -1910,17 +1927,18 @@ internal_open(isc_socketmgr_t *manager, isc_socket_t *sock) {
result = make_nonblock(sock->fd);
if (result != ISC_R_SUCCESS) {
closesocket(sock->fd);
free_socket(&sock);
return (result);
}
#if defined(USE_CMSG)
if (sock->type == isc_sockettype_udp) {
if (type == isc_sockettype_udp) {
#if defined(ISC_PLATFORM_HAVEIPV6)
#ifdef IPV6_RECVPKTINFO
/* 2292bis */
if ((sock->pf == AF_INET6)
if ((pf == AF_INET6)
&& (setsockopt(sock->fd, IPPROTO_IPV6, IPV6_RECVPKTINFO,
(void *)&on, sizeof(on)) < 0)) {
isc__strerror(WSAGetLastError(), strbuf, sizeof(strbuf));
@@ -1935,7 +1953,7 @@ internal_open(isc_socketmgr_t *manager, isc_socket_t *sock) {
}
#else
/* 2292 */
if ((sock->pf == AF_INET6)
if ((pf == AF_INET6)
&& (setsockopt(sock->fd, IPPROTO_IPV6, IPV6_PKTINFO,
(void *)&on, sizeof(on)) < 0)) {
isc__strerror(WSAGetLastError(), strbuf, sizeof(strbuf));
@@ -1951,7 +1969,7 @@ internal_open(isc_socketmgr_t *manager, isc_socket_t *sock) {
#endif /* IPV6_RECVPKTINFO */
#ifdef IPV6_USE_MIN_MTU /*2292bis, not too common yet*/
/* use minimum MTU */
if (sock->pf == AF_INET6) {
if (pf == AF_INET6) {
(void)setsockopt(sock->fd, IPPROTO_IPV6,
IPV6_USE_MIN_MTU,
(void *)&on, sizeof(on));
@@ -1962,36 +1980,6 @@ internal_open(isc_socketmgr_t *manager, isc_socket_t *sock) {
}
#endif /* USE_CMSG */
return (ISC_R_SUCCESS);
}
/*
* Create a new 'type' socket managed by 'manager'. Events
* will be posted to 'task' and when dispatched 'action' will be
* called with 'arg' as the arg value. The new socket is returned
* in 'socketp'.
*/
isc_result_t
isc_socket_create(isc_socketmgr_t *manager, int pf, isc_sockettype_t type,
isc_socket_t **socketp) {
isc_socket_t *sock = NULL;
isc_result_t result;
REQUIRE(VALID_MANAGER(manager));
REQUIRE(socketp != NULL && *socketp == NULL);
result = allocate_socket(manager, type, &sock);
if (result != ISC_R_SUCCESS)
return (result);
sock->pf = pf;
result = internal_open(manager, sock);
if (result != ISC_R_SUCCESS) {
free_socket(&sock);
return (result);
}
sock->references = 1;
*socketp = sock;
@@ -2013,25 +2001,9 @@ isc_socket_create(isc_socketmgr_t *manager, int pf, isc_sockettype_t type,
isc_result_t
isc_socket_open(isc_socket_t *sock) {
isc_result_t result;
REQUIRE(VALID_SOCKET(sock));
LOCK(&sock->lock);
REQUIRE(sock->references == 1);
UNLOCK(&sock->lock);
/*
* We don't need to retain the lock hereafter, since no one else has
* this socket.
*/
REQUIRE(sock->fd == -1);
result = internal_open(sock->manager, sock);
if (result != ISC_R_SUCCESS)
sock->fd = -1;
return (result);
return (ISC_R_NOTIMPLEMENTED);
}
/*
@@ -2075,36 +2047,11 @@ isc_socket_detach(isc_socket_t **socketp) {
*socketp = NULL;
}
void
isc_result_t
isc_socket_close(isc_socket_t *sock) {
REQUIRE(VALID_SOCKET(sock));
LOCK(&sock->lock);
REQUIRE(sock->references == 1);
UNLOCK(&sock->lock);
/*
* We don't need to retain the lock hereafter, since no one else has
* this socket.
*/
REQUIRE(sock->fd >= 0);
INSIST(!sock->connecting);
INSIST(!sock->pending_recv);
INSIST(!sock->pending_send);
INSIST(!sock->pending_accept);
INSIST(ISC_LIST_EMPTY(sock->recv_list));
INSIST(ISC_LIST_EMPTY(sock->send_list));
INSIST(ISC_LIST_EMPTY(sock->accept_list));
INSIST(sock->connect_ev == NULL);
sock->fd = -1;
sock->listener = 0;
sock->connected = 0;
sock->connecting = 0;
sock->bound = 0;
isc_sockaddr_any(&sock->address);
socket_close(sock);
return (ISC_R_NOTIMPLEMENTED);
}
/*