mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-09-01 23:25:38 +00:00
snapshot
This commit is contained in:
@@ -12,6 +12,7 @@
|
|||||||
#include <isc/thread.h>
|
#include <isc/thread.h>
|
||||||
#include <isc/result.h>
|
#include <isc/result.h>
|
||||||
#include <isc/socket.h>
|
#include <isc/socket.h>
|
||||||
|
#include <isc/timer.h>
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
@@ -21,8 +22,7 @@
|
|||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
|
|
||||||
isc_memctx_t mctx = NULL;
|
isc_memctx_t mctx = NULL;
|
||||||
|
int sockets_active = 0;
|
||||||
volatile int tasks_done = 0;
|
|
||||||
|
|
||||||
static isc_boolean_t my_send(isc_task_t task, isc_event_t event);
|
static isc_boolean_t my_send(isc_task_t task, isc_event_t event);
|
||||||
static isc_boolean_t my_recv(isc_task_t task, isc_event_t event);
|
static isc_boolean_t my_recv(isc_task_t task, isc_event_t event);
|
||||||
@@ -51,7 +51,6 @@ my_shutdown(isc_task_t task, isc_event_t event)
|
|||||||
return (ISC_TRUE);
|
return (ISC_TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static isc_boolean_t
|
static isc_boolean_t
|
||||||
my_recv(isc_task_t task, isc_event_t event)
|
my_recv(isc_task_t task, isc_event_t event)
|
||||||
{
|
{
|
||||||
@@ -75,6 +74,10 @@ my_recv(isc_task_t task, isc_event_t event)
|
|||||||
|
|
||||||
isc_event_free(&event);
|
isc_event_free(&event);
|
||||||
|
|
||||||
|
sockets_active--;
|
||||||
|
if (sockets_active == 0)
|
||||||
|
return (1);
|
||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -190,6 +193,8 @@ my_listen(isc_task_t task, isc_event_t event)
|
|||||||
char *name = event->arg;
|
char *name = event->arg;
|
||||||
isc_socket_newconnev_t dev;
|
isc_socket_newconnev_t dev;
|
||||||
struct isc_region region;
|
struct isc_region region;
|
||||||
|
isc_socket_t oldsock;
|
||||||
|
int ret;
|
||||||
|
|
||||||
dev = (isc_socket_newconnev_t)event;
|
dev = (isc_socket_newconnev_t)event;
|
||||||
|
|
||||||
@@ -197,6 +202,8 @@ my_listen(isc_task_t task, isc_event_t event)
|
|||||||
name, task, event->sender, dev->newsocket, dev->result);
|
name, task, event->sender, dev->newsocket, dev->result);
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
|
|
||||||
|
ret = 0;
|
||||||
|
|
||||||
if (dev->result == ISC_R_SUCCESS) {
|
if (dev->result == ISC_R_SUCCESS) {
|
||||||
/*
|
/*
|
||||||
* queue another listen on this socket
|
* queue another listen on this socket
|
||||||
@@ -211,15 +218,33 @@ my_listen(isc_task_t task, isc_event_t event)
|
|||||||
*/
|
*/
|
||||||
isc_socket_recv(dev->newsocket, ®ion, ISC_FALSE,
|
isc_socket_recv(dev->newsocket, ®ion, ISC_FALSE,
|
||||||
task, my_recv, event->arg);
|
task, my_recv, event->arg);
|
||||||
|
sockets_active++;
|
||||||
} else {
|
} else {
|
||||||
/*
|
printf("detaching from socket %p\n", event->sender);
|
||||||
* Do something useful here
|
oldsock = event->sender;
|
||||||
*/
|
|
||||||
|
isc_socket_detach(&oldsock);
|
||||||
|
|
||||||
|
sockets_active--;
|
||||||
|
ret = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
isc_event_free(&event);
|
isc_event_free(&event);
|
||||||
|
|
||||||
return 0;
|
return (ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
static isc_boolean_t
|
||||||
|
timeout(isc_task_t task, isc_event_t event)
|
||||||
|
{
|
||||||
|
isc_socket_t sock = event->arg;
|
||||||
|
|
||||||
|
printf("Timeout, canceling IO on socket %p\n", sock);
|
||||||
|
|
||||||
|
isc_socket_cancel(sock, NULL, ISC_SOCKCANCEL_ALL);
|
||||||
|
isc_timer_detach((isc_timer_t *)&event->sender);
|
||||||
|
|
||||||
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
@@ -227,12 +252,17 @@ main(int argc, char *argv[])
|
|||||||
{
|
{
|
||||||
isc_taskmgr_t manager = NULL;
|
isc_taskmgr_t manager = NULL;
|
||||||
isc_task_t t1 = NULL, t2 = NULL;
|
isc_task_t t1 = NULL, t2 = NULL;
|
||||||
|
isc_timermgr_t timgr = NULL;
|
||||||
|
struct isc_time expires, now;
|
||||||
|
struct isc_interval interval;
|
||||||
|
isc_timer_t ti1 = NULL;
|
||||||
isc_event_t event;
|
isc_event_t event;
|
||||||
unsigned int workers;
|
unsigned int workers;
|
||||||
isc_socketmgr_t socketmgr;
|
isc_socketmgr_t socketmgr;
|
||||||
isc_socket_t so1, so2;
|
isc_socket_t so1, so2;
|
||||||
struct isc_sockaddr sockaddr;
|
struct isc_sockaddr sockaddr;
|
||||||
unsigned int addrlen;
|
unsigned int addrlen;
|
||||||
|
|
||||||
|
|
||||||
memset(&sockaddr, 0, sizeof(sockaddr));
|
memset(&sockaddr, 0, sizeof(sockaddr));
|
||||||
sockaddr.type.sin.sin_port = htons(5544);
|
sockaddr.type.sin.sin_port = htons(5544);
|
||||||
@@ -257,12 +287,20 @@ main(int argc, char *argv[])
|
|||||||
printf("task 1 = %p\n", t1);
|
printf("task 1 = %p\n", t1);
|
||||||
printf("task 2 = %p\n", t2);
|
printf("task 2 = %p\n", t2);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* create the timer we'll need
|
||||||
|
*/
|
||||||
|
INSIST(isc_timermgr_create(mctx, &timgr) == ISC_R_SUCCESS);
|
||||||
|
|
||||||
|
(void)isc_time_get(&now);
|
||||||
|
|
||||||
socketmgr = NULL;
|
socketmgr = NULL;
|
||||||
INSIST(isc_socketmgr_create(mctx, &socketmgr) == ISC_R_SUCCESS);
|
INSIST(isc_socketmgr_create(mctx, &socketmgr) == ISC_R_SUCCESS);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* open up a listener socket
|
* open up a listener socket
|
||||||
*/
|
*/
|
||||||
|
sockets_active++;
|
||||||
so1 = NULL;
|
so1 = NULL;
|
||||||
memset(&sockaddr, 0, sizeof(sockaddr));
|
memset(&sockaddr, 0, sizeof(sockaddr));
|
||||||
sockaddr.type.sin.sin_family = AF_INET;
|
sockaddr.type.sin.sin_family = AF_INET;
|
||||||
@@ -278,11 +316,16 @@ main(int argc, char *argv[])
|
|||||||
*/
|
*/
|
||||||
INSIST(isc_socket_accept(so1, t1, my_listen,
|
INSIST(isc_socket_accept(so1, t1, my_listen,
|
||||||
"so1") == ISC_R_SUCCESS);
|
"so1") == ISC_R_SUCCESS);
|
||||||
|
isc_time_settoepoch(&expires);
|
||||||
|
isc_interval_set(&interval, 30, 0);
|
||||||
|
INSIST(isc_timer_create(timgr, isc_timertype_once, &expires, &interval,
|
||||||
|
t1, timeout, so1, &ti1) == ISC_R_SUCCESS);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* open up a socket that will connect to www.flame.org, port 80.
|
* open up a socket that will connect to www.flame.org, port 80.
|
||||||
* Why not. :)
|
* Why not. :)
|
||||||
*/
|
*/
|
||||||
|
sockets_active++;
|
||||||
so2 = NULL;
|
so2 = NULL;
|
||||||
memset(&sockaddr, 0, sizeof(sockaddr));
|
memset(&sockaddr, 0, sizeof(sockaddr));
|
||||||
sockaddr.type.sin.sin_port = htons(80);
|
sockaddr.type.sin.sin_port = htons(80);
|
||||||
@@ -294,7 +337,7 @@ main(int argc, char *argv[])
|
|||||||
INSIST(isc_socket_connect(so2, &sockaddr, addrlen, t1, my_connect,
|
INSIST(isc_socket_connect(so2, &sockaddr, addrlen, t1, my_connect,
|
||||||
"so2") == ISC_R_SUCCESS);
|
"so2") == ISC_R_SUCCESS);
|
||||||
|
|
||||||
sleep(2);
|
sleep(1);
|
||||||
|
|
||||||
event = isc_event_allocate(mctx, (void *)main, 1, my_callback, "1",
|
event = isc_event_allocate(mctx, (void *)main, 1, my_callback, "1",
|
||||||
sizeof *event);
|
sizeof *event);
|
||||||
@@ -330,24 +373,16 @@ main(int argc, char *argv[])
|
|||||||
sizeof *event);
|
sizeof *event);
|
||||||
isc_task_send(t2, &event);
|
isc_task_send(t2, &event);
|
||||||
|
|
||||||
/*
|
sleep(60);
|
||||||
* Grr! there is no way to say "wake me when it's over"
|
|
||||||
*/
|
|
||||||
while (tasks_done != 2) {
|
|
||||||
fprintf(stderr, "Tasks done: %d\n", tasks_done);
|
|
||||||
sleep(2);
|
|
||||||
}
|
|
||||||
|
|
||||||
isc_task_shutdown(t1);
|
isc_task_shutdown(t1);
|
||||||
isc_task_shutdown(t2);
|
isc_task_shutdown(t2);
|
||||||
isc_task_detach(&t1);
|
isc_task_detach(&t1);
|
||||||
isc_task_detach(&t2);
|
isc_task_detach(&t2);
|
||||||
|
|
||||||
printf("destroy\n");
|
printf("Destroying socket manager\n");
|
||||||
isc_socket_detach(&so1);
|
|
||||||
isc_socket_detach(&so2);
|
|
||||||
|
|
||||||
isc_socketmgr_destroy(&socketmgr);
|
isc_socketmgr_destroy(&socketmgr);
|
||||||
|
printf("Destroying task manager\n");
|
||||||
isc_taskmgr_destroy(&manager);
|
isc_taskmgr_destroy(&manager);
|
||||||
printf("destroyed\n");
|
printf("destroyed\n");
|
||||||
|
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
/* $Id: socket.h,v 1.10 1998/12/04 11:21:11 explorer Exp $ */
|
/* $Id: socket.h,v 1.11 1998/12/05 00:28:13 explorer Exp $ */
|
||||||
|
|
||||||
#ifndef ISC_SOCKET_H
|
#ifndef ISC_SOCKET_H
|
||||||
#define ISC_SOCKET_H 1
|
#define ISC_SOCKET_H 1
|
||||||
@@ -106,20 +106,31 @@ typedef struct isc_socket_connev {
|
|||||||
/*
|
/*
|
||||||
* Internal events.
|
* Internal events.
|
||||||
*/
|
*/
|
||||||
#define ISC_SOCKEVENT_INTIO (ISC_EVENTCLASS_SOCKET + 257)
|
#define ISC_SOCKEVENT_INTRECV (ISC_EVENTCLASS_SOCKET + 257)
|
||||||
#define ISC_SOCKEVENT_INTCONN (ISC_EVENTCLASS_SOCKET + 258)
|
#define ISC_SOCKEVENT_INTSEND (ISC_EVENTCLASS_SOCKET + 258)
|
||||||
|
#define ISC_SOCKEVENT_INTACCEPT (ISC_EVENTCLASS_SOCKET + 259)
|
||||||
|
#define ISC_SOCKEVENT_INTCONN (ISC_EVENTCLASS_SOCKET + 260)
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
isc_socket_udp,
|
isc_socket_udp,
|
||||||
isc_socket_tcp
|
isc_socket_tcp
|
||||||
} isc_sockettype_t;
|
} isc_sockettype_t;
|
||||||
|
|
||||||
typedef enum {
|
/*
|
||||||
isc_sockshut_reading,
|
* How a socket should be shutdown in isc_socket_shutdown() calls.
|
||||||
isc_sockshut_writing,
|
*/
|
||||||
isc_sockshut_all
|
#define ISC_SOCKSHUT_RECV 0x00000001 /* close read side */
|
||||||
} isc_socketshutdown_t;
|
#define ISC_SOCKSHUT_SEND 0x00000002 /* close write side */
|
||||||
|
#define ISC_SOCKSHUT_ALL 0x00000003 /* close them all */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* What I/O events to cancel in isc_socket_cancel() calls.
|
||||||
|
*/
|
||||||
|
#define ISC_SOCKCANCEL_RECV 0x00000001 /* cancel recv */
|
||||||
|
#define ISC_SOCKCANCEL_SEND 0x00000002 /* cancel send */
|
||||||
|
#define ISC_SOCKCANCEL_ACCEPT 0x00000004 /* cancel accept */
|
||||||
|
#define ISC_SOCKCANCEL_CONNECT 0x00000008 /* cancel connect */
|
||||||
|
#define ISC_SOCKCANCEL_ALL 0x0000000f /* cancel everything */
|
||||||
|
|
||||||
/***
|
/***
|
||||||
*** Socket and Socket Manager Functions
|
*** Socket and Socket Manager Functions
|
||||||
@@ -153,8 +164,8 @@ isc_socket_create(isc_socketmgr_t manager,
|
|||||||
* ISC_R_UNEXPECTED
|
* ISC_R_UNEXPECTED
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int
|
void
|
||||||
isc_socket_cancel(isc_socket_t socket, isc_task_t task,
|
isc_socket_cancel(isc_socket_t sock, isc_task_t task,
|
||||||
unsigned int how);
|
unsigned int how);
|
||||||
/*
|
/*
|
||||||
* Cancel pending I/O of the type specified by "how".
|
* Cancel pending I/O of the type specified by "how".
|
||||||
@@ -178,11 +189,15 @@ isc_socket_cancel(isc_socket_t socket, isc_task_t task,
|
|||||||
* ISC_SOCKCANCEL_SEND:
|
* ISC_SOCKCANCEL_SEND:
|
||||||
* Cancel pending isc_socket_send() and isc_socket_sendto() calls.
|
* Cancel pending isc_socket_send() and isc_socket_sendto() calls.
|
||||||
*
|
*
|
||||||
* ISC_SOCKCANCEL_
|
* ISC_SOCKCANCEL_ACCEPT:
|
||||||
|
* Cancel pending isc_socket_accept() calls.
|
||||||
|
*
|
||||||
|
* ISC_SOCKCANCEL_CONNECT:
|
||||||
|
* Cancel pending isc_socket_connect() call.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void
|
void
|
||||||
isc_socket_shutdown(isc_socket_t socket, isc_socketshutdown_t how);
|
isc_socket_shutdown(isc_socket_t sock, unsigned int how);
|
||||||
/*
|
/*
|
||||||
* Shutdown 'socket' according to 'how'.
|
* Shutdown 'socket' according to 'how'.
|
||||||
*
|
*
|
||||||
@@ -192,13 +207,13 @@ isc_socket_shutdown(isc_socket_t socket, isc_socketshutdown_t how);
|
|||||||
*
|
*
|
||||||
* 'task' is NULL or is a valid task.
|
* 'task' is NULL or is a valid task.
|
||||||
*
|
*
|
||||||
* If 'how' is 'isc_sockshut_reading' or 'isc_sockshut_all' then
|
* If 'how' is 'ISC_SOCKSHUT_RECV' or 'ISC_SOCKSHUT_ALL' then
|
||||||
*
|
*
|
||||||
* The read queue must be empty.
|
* The read queue must be empty.
|
||||||
*
|
*
|
||||||
* No further read requests may be made.
|
* No further read requests may be made.
|
||||||
*
|
*
|
||||||
* If 'how' is 'isc_sockshut_writing' or 'isc_sockshut_all' then
|
* If 'how' is 'ISC_SOCKSHUT_SEND' or 'ISC_SOCKSHUT_ALL' then
|
||||||
*
|
*
|
||||||
* The write queue must be empty.
|
* The write queue must be empty.
|
||||||
*
|
*
|
||||||
@@ -206,7 +221,7 @@ isc_socket_shutdown(isc_socket_t socket, isc_socketshutdown_t how);
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
void
|
void
|
||||||
isc_socket_attach(isc_socket_t socket, isc_socket_t *socketp);
|
isc_socket_attach(isc_socket_t sock, isc_socket_t *socketp);
|
||||||
/*
|
/*
|
||||||
* Attach *socketp to socket.
|
* Attach *socketp to socket.
|
||||||
*
|
*
|
||||||
@@ -249,7 +264,7 @@ isc_socket_detach(isc_socket_t *socketp);
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
isc_result_t
|
isc_result_t
|
||||||
isc_socket_bind(isc_socket_t socket, struct isc_sockaddr *addressp,
|
isc_socket_bind(isc_socket_t sock, struct isc_sockaddr *addressp,
|
||||||
int length);
|
int length);
|
||||||
/*
|
/*
|
||||||
* Bind 'socket' to '*addressp'.
|
* Bind 'socket' to '*addressp'.
|
||||||
@@ -273,7 +288,7 @@ isc_socket_bind(isc_socket_t socket, struct isc_sockaddr *addressp,
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
isc_result_t
|
isc_result_t
|
||||||
isc_socket_listen(isc_socket_t socket, int backlog);
|
isc_socket_listen(isc_socket_t sock, int backlog);
|
||||||
/*
|
/*
|
||||||
* Set listen mode on the socket. After this call, the only function that
|
* Set listen mode on the socket. After this call, the only function that
|
||||||
* can be used (other than attach and detach) is isc_socket_accept().
|
* can be used (other than attach and detach) is isc_socket_accept().
|
||||||
@@ -295,7 +310,7 @@ isc_socket_listen(isc_socket_t socket, int backlog);
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
isc_result_t
|
isc_result_t
|
||||||
isc_socket_accept(isc_socket_t socket,
|
isc_socket_accept(isc_socket_t sock,
|
||||||
isc_task_t task, isc_taskaction_t action, void *arg);
|
isc_task_t task, isc_taskaction_t action, void *arg);
|
||||||
/*
|
/*
|
||||||
* Queue accept event. When a new connection is received, the task will
|
* Queue accept event. When a new connection is received, the task will
|
||||||
@@ -318,7 +333,7 @@ isc_socket_accept(isc_socket_t socket,
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
isc_result_t
|
isc_result_t
|
||||||
isc_socket_connect(isc_socket_t socket, struct isc_sockaddr *addressp,
|
isc_socket_connect(isc_socket_t sock, struct isc_sockaddr *addressp,
|
||||||
int length, isc_task_t task, isc_taskaction_t action,
|
int length, isc_task_t task, isc_taskaction_t action,
|
||||||
void *arg);
|
void *arg);
|
||||||
/*
|
/*
|
||||||
@@ -354,7 +369,7 @@ isc_socket_connect(isc_socket_t socket, struct isc_sockaddr *addressp,
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
isc_result_t
|
isc_result_t
|
||||||
isc_socket_getpeername(isc_socket_t socket, struct isc_sockaddr *addressp,
|
isc_socket_getpeername(isc_socket_t sock, struct isc_sockaddr *addressp,
|
||||||
int *lengthp);
|
int *lengthp);
|
||||||
/*
|
/*
|
||||||
* Get the name of the peer connected to 'socket'.
|
* Get the name of the peer connected to 'socket'.
|
||||||
@@ -373,7 +388,7 @@ isc_socket_getpeername(isc_socket_t socket, struct isc_sockaddr *addressp,
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
isc_result_t
|
isc_result_t
|
||||||
isc_socket_getsockname(isc_socket_t socket, struct isc_sockaddr *addressp,
|
isc_socket_getsockname(isc_socket_t sock, struct isc_sockaddr *addressp,
|
||||||
int *lengthp);
|
int *lengthp);
|
||||||
/*
|
/*
|
||||||
* Get the name of 'socket'.
|
* Get the name of 'socket'.
|
||||||
@@ -392,7 +407,7 @@ isc_socket_getsockname(isc_socket_t socket, struct isc_sockaddr *addressp,
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
isc_result_t
|
isc_result_t
|
||||||
isc_socket_recv(isc_socket_t socket, isc_region_t region,
|
isc_socket_recv(isc_socket_t sock, isc_region_t region,
|
||||||
isc_boolean_t partial,
|
isc_boolean_t partial,
|
||||||
isc_task_t task, isc_taskaction_t action, void *arg);
|
isc_task_t task, isc_taskaction_t action, void *arg);
|
||||||
/*
|
/*
|
||||||
@@ -438,10 +453,10 @@ isc_socket_recv(isc_socket_t socket, isc_region_t region,
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
isc_result_t
|
isc_result_t
|
||||||
isc_socket_send(isc_socket_t socket, isc_region_t region,
|
isc_socket_send(isc_socket_t sock, isc_region_t region,
|
||||||
isc_task_t task, isc_taskaction_t action, void *arg);
|
isc_task_t task, isc_taskaction_t action, void *arg);
|
||||||
isc_result_t
|
isc_result_t
|
||||||
isc_socket_sendto(isc_socket_t socket, isc_region_t region,
|
isc_socket_sendto(isc_socket_t sock, isc_region_t region,
|
||||||
isc_task_t task, isc_taskaction_t action, void *arg,
|
isc_task_t task, isc_taskaction_t action, void *arg,
|
||||||
isc_sockaddr_t address, unsigned int addrlength);
|
isc_sockaddr_t address, unsigned int addrlength);
|
||||||
/*
|
/*
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
/* $Id: socket.c,v 1.16 1998/12/04 20:00:16 halley Exp $ */
|
/* $Id: socket.c,v 1.17 1998/12/05 00:28:12 explorer Exp $ */
|
||||||
|
|
||||||
#include "attribute.h"
|
#include "attribute.h"
|
||||||
|
|
||||||
@@ -31,8 +31,8 @@
|
|||||||
* if they fail.
|
* if they fail.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define LOCK(lp) INSIST(isc_mutex_lock((lp)) == ISC_R_SUCCESS);
|
#define LOCK(lp) do { XTRACE(TRACE_LOCK, ("%d locked socket %p\n", __LINE__, lp)); INSIST(isc_mutex_lock((lp)) == ISC_R_SUCCESS); } while (0)
|
||||||
#define UNLOCK(lp) INSIST(isc_mutex_unlock((lp)) == ISC_R_SUCCESS);
|
#define UNLOCK(lp) do { XTRACE(TRACE_LOCK, ("%d unlocked socket %p\n", __LINE__, lp)); INSIST(isc_mutex_unlock((lp)) == ISC_R_SUCCESS); } while (0)
|
||||||
|
|
||||||
#define SOFT_ERROR(e) ((e) == EAGAIN || (e) == EWOULDBLOCK || (e) == EINTR)
|
#define SOFT_ERROR(e) ((e) == EAGAIN || (e) == EWOULDBLOCK || (e) == EINTR)
|
||||||
|
|
||||||
@@ -45,9 +45,10 @@
|
|||||||
#define TRACE_RECV 0x0008
|
#define TRACE_RECV 0x0008
|
||||||
#define TRACE_SEND 0x0010
|
#define TRACE_SEND 0x0010
|
||||||
#define TRACE_MANAGER 0x0020
|
#define TRACE_MANAGER 0x0020
|
||||||
|
#define TRACE_LOCK 0x0040
|
||||||
|
|
||||||
#if 0
|
#if 1
|
||||||
int trace_level = TRACE_CONNECT | TRACE_MANAGER;
|
int trace_level = TRACE_CONNECT | TRACE_MANAGER | TRACE_WATCHER | TRACE_LOCK;
|
||||||
#define XTRACE(l, a) if (l & trace_level) printf a
|
#define XTRACE(l, a) if (l & trace_level) printf a
|
||||||
#define XENTER(l, a) if (l & trace_level) printf("ENTER %s\n", (a))
|
#define XENTER(l, a) if (l & trace_level) printf("ENTER %s\n", (a))
|
||||||
#define XEXIT(l, a) if (l & trace_level) printf("EXIT %s\n", (a))
|
#define XEXIT(l, a) if (l & trace_level) printf("EXIT %s\n", (a))
|
||||||
@@ -67,22 +68,25 @@ typedef struct rwintev {
|
|||||||
isc_socketevent_t done_ev; /* the done event to post */
|
isc_socketevent_t done_ev; /* the done event to post */
|
||||||
isc_boolean_t partial; /* partial i/o ok */
|
isc_boolean_t partial; /* partial i/o ok */
|
||||||
isc_boolean_t canceled; /* I/O was canceled */
|
isc_boolean_t canceled; /* I/O was canceled */
|
||||||
|
isc_boolean_t posted; /* event posted to task */
|
||||||
LINK(struct rwintev) link; /* next event */
|
LINK(struct rwintev) link; /* next event */
|
||||||
} *rwintev_t;
|
} *rwintev_t;
|
||||||
|
|
||||||
typedef struct ncintev {
|
typedef struct ncintev {
|
||||||
struct isc_event common; /* Sender is the socket */
|
struct isc_event common; /* Sender is the socket */
|
||||||
isc_task_t task; /* task to send these to */
|
isc_task_t task; /* task to send these to */
|
||||||
isc_socket_newconnev_t done; /* the done event */
|
isc_socket_newconnev_t done_ev; /* the done event */
|
||||||
isc_boolean_t canceled; /* accept was canceled */
|
isc_boolean_t canceled; /* accept was canceled */
|
||||||
|
isc_boolean_t posted; /* event posted to task */
|
||||||
LINK(struct ncintev) link; /* next event */
|
LINK(struct ncintev) link; /* next event */
|
||||||
} *ncintev_t;
|
} *ncintev_t;
|
||||||
|
|
||||||
typedef struct cnintev {
|
typedef struct cnintev {
|
||||||
struct isc_event common; /* Sender is the socket */
|
struct isc_event common; /* Sender is the socket */
|
||||||
isc_task_t task; /* task to send these to */
|
isc_task_t task; /* task to send these to */
|
||||||
|
isc_socket_connev_t done_ev; /* the done event */
|
||||||
isc_boolean_t canceled; /* connect was canceled */
|
isc_boolean_t canceled; /* connect was canceled */
|
||||||
isc_socket_connev_t done; /* the done event */
|
isc_boolean_t posted; /* event posted to task */
|
||||||
} *cnintev_t;
|
} *cnintev_t;
|
||||||
|
|
||||||
#define SOCKET_MAGIC 0x494f696fU /* IOio */
|
#define SOCKET_MAGIC 0x494f696fU /* IOio */
|
||||||
@@ -104,6 +108,7 @@ struct isc_socket {
|
|||||||
cnintev_t connect_ev;
|
cnintev_t connect_ev;
|
||||||
isc_boolean_t pending_recv;
|
isc_boolean_t pending_recv;
|
||||||
isc_boolean_t pending_send;
|
isc_boolean_t pending_send;
|
||||||
|
isc_boolean_t pending_accept;
|
||||||
isc_boolean_t listener; /* is a listener socket */
|
isc_boolean_t listener; /* is a listener socket */
|
||||||
isc_boolean_t connecting; /* connect pending */
|
isc_boolean_t connecting; /* connect pending */
|
||||||
rwintev_t riev; /* allocated recv intev */
|
rwintev_t riev; /* allocated recv intev */
|
||||||
@@ -128,10 +133,15 @@ struct isc_socketmgr {
|
|||||||
fd_set read_fds;
|
fd_set read_fds;
|
||||||
fd_set write_fds;
|
fd_set write_fds;
|
||||||
isc_socket_t fds[FD_SETSIZE];
|
isc_socket_t fds[FD_SETSIZE];
|
||||||
|
int fdstate[FD_SETSIZE];
|
||||||
int maxfd;
|
int maxfd;
|
||||||
int pipe_fds[2];
|
int pipe_fds[2];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define CLOSED 0 /* this one must be zero */
|
||||||
|
#define MANAGED 1
|
||||||
|
#define CLOSE_PENDING 2
|
||||||
|
|
||||||
static void send_recvdone_event(isc_socket_t, rwintev_t *,
|
static void send_recvdone_event(isc_socket_t, rwintev_t *,
|
||||||
isc_socketevent_t *, isc_result_t);
|
isc_socketevent_t *, isc_result_t);
|
||||||
static void send_senddone_event(isc_socket_t, rwintev_t *,
|
static void send_senddone_event(isc_socket_t, rwintev_t *,
|
||||||
@@ -215,6 +225,45 @@ make_nonblock(int fd)
|
|||||||
return (ISC_R_SUCCESS);
|
return (ISC_R_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
socket_dump(isc_socket_t sock)
|
||||||
|
{
|
||||||
|
rwintev_t rwiev;
|
||||||
|
ncintev_t aiev;
|
||||||
|
|
||||||
|
printf("--------\nDump of socket %p\n", sock);
|
||||||
|
printf("fd: %d, references %u\n", sock->fd, sock->references);
|
||||||
|
|
||||||
|
printf("recv queue:\n");
|
||||||
|
rwiev = HEAD(sock->recv_list);
|
||||||
|
while (rwiev != NULL) {
|
||||||
|
printf("\tintev %p, done_ev %p, task %p, canceled %d, posted %d",
|
||||||
|
rwiev, rwiev->done_ev, rwiev->task, rwiev->canceled,
|
||||||
|
rwiev->posted);
|
||||||
|
rwiev = NEXT(rwiev, link);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("send queue:\n");
|
||||||
|
rwiev = HEAD(sock->send_list);
|
||||||
|
while (rwiev != NULL) {
|
||||||
|
printf("\tintev %p, done_ev %p, task %p, canceled %d, posted %d",
|
||||||
|
rwiev, rwiev->done_ev, rwiev->task, rwiev->canceled,
|
||||||
|
rwiev->posted);
|
||||||
|
rwiev = NEXT(rwiev, link);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("accept queue:\n");
|
||||||
|
aiev = HEAD(sock->accept_list);
|
||||||
|
while (aiev != NULL) {
|
||||||
|
printf("\tintev %p, done_ev %p, task %p, canceled %d, posted %d\n",
|
||||||
|
aiev, aiev->done_ev, aiev->task, aiev->canceled,
|
||||||
|
aiev->posted);
|
||||||
|
aiev = NEXT(aiev, link);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("--------\n");
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Handle freeing a done event when needed.
|
* Handle freeing a done event when needed.
|
||||||
*/
|
*/
|
||||||
@@ -264,7 +313,10 @@ destroy(isc_socket_t *sockp)
|
|||||||
* poked, and the socket doesn't have to be locked.
|
* poked, and the socket doesn't have to be locked.
|
||||||
*/
|
*/
|
||||||
manager->fds[sock->fd] = NULL;
|
manager->fds[sock->fd] = NULL;
|
||||||
|
manager->fdstate[sock->fd] = CLOSE_PENDING;
|
||||||
|
select_poke(sock->manager, sock->fd);
|
||||||
manager->nsockets--;
|
manager->nsockets--;
|
||||||
|
XTRACE(TRACE_MANAGER, ("nsockets == %d\n", manager->nsockets));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* XXX should reset manager->maxfd here
|
* XXX should reset manager->maxfd here
|
||||||
@@ -300,6 +352,7 @@ allocate_socket(isc_socketmgr_t manager, isc_sockettype_t type,
|
|||||||
INIT_LIST(sock->accept_list);
|
INIT_LIST(sock->accept_list);
|
||||||
sock->pending_recv = ISC_FALSE;
|
sock->pending_recv = ISC_FALSE;
|
||||||
sock->pending_send = ISC_FALSE;
|
sock->pending_send = ISC_FALSE;
|
||||||
|
sock->pending_accept = ISC_FALSE;
|
||||||
sock->listener = ISC_FALSE;
|
sock->listener = ISC_FALSE;
|
||||||
sock->connecting = ISC_FALSE;
|
sock->connecting = ISC_FALSE;
|
||||||
|
|
||||||
@@ -333,24 +386,21 @@ free_socket(isc_socket_t *socketp)
|
|||||||
|
|
||||||
REQUIRE(sock->references == 0);
|
REQUIRE(sock->references == 0);
|
||||||
REQUIRE(VALID_SOCKET(sock));
|
REQUIRE(VALID_SOCKET(sock));
|
||||||
REQUIRE(!sock->listener);
|
|
||||||
REQUIRE(!sock->connecting);
|
REQUIRE(!sock->connecting);
|
||||||
REQUIRE(!sock->pending_recv);
|
REQUIRE(!sock->pending_recv);
|
||||||
REQUIRE(!sock->pending_send);
|
REQUIRE(!sock->pending_send);
|
||||||
|
REQUIRE(!sock->pending_accept);
|
||||||
REQUIRE(EMPTY(sock->recv_list));
|
REQUIRE(EMPTY(sock->recv_list));
|
||||||
REQUIRE(EMPTY(sock->send_list));
|
REQUIRE(EMPTY(sock->send_list));
|
||||||
REQUIRE(EMPTY(sock->accept_list));
|
REQUIRE(EMPTY(sock->accept_list));
|
||||||
|
|
||||||
sock->magic = 0;
|
sock->magic = 0;
|
||||||
|
|
||||||
if (sock->fd != -1) {
|
|
||||||
close(sock->fd);
|
|
||||||
sock->fd = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
(void)isc_mutex_destroy(&sock->lock);
|
(void)isc_mutex_destroy(&sock->lock);
|
||||||
|
|
||||||
isc_mem_put(sock->manager->mctx, sock, sizeof *sock);
|
isc_mem_put(sock->manager->mctx, sock, sizeof *sock);
|
||||||
|
|
||||||
|
*socketp = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -415,7 +465,9 @@ isc_socket_create(isc_socketmgr_t manager, isc_sockettype_t type,
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
manager->fds[sock->fd] = sock;
|
manager->fds[sock->fd] = sock;
|
||||||
|
manager->fdstate[sock->fd] = MANAGED;
|
||||||
manager->nsockets++;
|
manager->nsockets++;
|
||||||
|
XTRACE(TRACE_MANAGER, ("nsockets == %d\n", manager->nsockets));
|
||||||
if (manager->maxfd < sock->fd)
|
if (manager->maxfd < sock->fd)
|
||||||
manager->maxfd = sock->fd;
|
manager->maxfd = sock->fd;
|
||||||
|
|
||||||
@@ -500,6 +552,8 @@ dispatch_read(isc_socket_t sock)
|
|||||||
XTRACE(TRACE_WATCHER, ("dispatch_read: posted event %p to task %p\n",
|
XTRACE(TRACE_WATCHER, ("dispatch_read: posted event %p to task %p\n",
|
||||||
ev, iev->task));
|
ev, iev->task));
|
||||||
|
|
||||||
|
iev->posted = ISC_TRUE;
|
||||||
|
|
||||||
INSIST(isc_task_send(iev->task, &ev) == ISC_R_SUCCESS);
|
INSIST(isc_task_send(iev->task, &ev) == ISC_R_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -515,6 +569,8 @@ dispatch_write(isc_socket_t sock)
|
|||||||
INSIST(!sock->pending_send);
|
INSIST(!sock->pending_send);
|
||||||
sock->pending_send = ISC_TRUE;
|
sock->pending_send = ISC_TRUE;
|
||||||
|
|
||||||
|
iev->posted = ISC_TRUE;
|
||||||
|
|
||||||
isc_task_send(iev->task, &ev);
|
isc_task_send(iev->task, &ev);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -527,9 +583,11 @@ dispatch_listen(isc_socket_t sock)
|
|||||||
iev = HEAD(sock->accept_list);
|
iev = HEAD(sock->accept_list);
|
||||||
ev = (isc_event_t)iev;
|
ev = (isc_event_t)iev;
|
||||||
|
|
||||||
INSIST(!sock->pending_recv);
|
INSIST(!sock->pending_accept);
|
||||||
|
|
||||||
sock->pending_recv = ISC_TRUE;
|
sock->pending_accept = ISC_TRUE;
|
||||||
|
|
||||||
|
iev->posted = ISC_TRUE;
|
||||||
|
|
||||||
isc_task_send(iev->task, &ev);
|
isc_task_send(iev->task, &ev);
|
||||||
}
|
}
|
||||||
@@ -543,6 +601,8 @@ dispatch_connect(isc_socket_t sock)
|
|||||||
|
|
||||||
iev = sock->connect_ev;
|
iev = sock->connect_ev;
|
||||||
|
|
||||||
|
iev->posted = ISC_TRUE;
|
||||||
|
|
||||||
isc_task_send(iev->task, (isc_event_t *)&iev);
|
isc_task_send(iev->task, (isc_event_t *)&iev);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -587,19 +647,17 @@ send_senddone_event(isc_socket_t sock, rwintev_t *iev,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
send_ncdone_event(isc_socket_t sock, ncintev_t *iev,
|
send_ncdone_event(ncintev_t *iev,
|
||||||
isc_socket_newconnev_t *dev, isc_result_t resultcode)
|
isc_socket_newconnev_t *dev, isc_result_t resultcode)
|
||||||
{
|
{
|
||||||
REQUIRE(!EMPTY(sock->accept_list));
|
|
||||||
REQUIRE(iev != NULL);
|
REQUIRE(iev != NULL);
|
||||||
REQUIRE(*iev != NULL);
|
REQUIRE(*iev != NULL);
|
||||||
REQUIRE(dev != NULL);
|
REQUIRE(dev != NULL);
|
||||||
REQUIRE(*dev != NULL);
|
REQUIRE(*dev != NULL);
|
||||||
|
|
||||||
DEQUEUE(sock->accept_list, *iev, link);
|
|
||||||
(*dev)->result = resultcode;
|
(*dev)->result = resultcode;
|
||||||
isc_task_send((*iev)->task, (isc_event_t *)dev);
|
isc_task_send((*iev)->task, (isc_event_t *)dev);
|
||||||
(*iev)->done = NULL;
|
(*iev)->done_ev = NULL;
|
||||||
|
|
||||||
isc_event_free((isc_event_t *)iev);
|
isc_event_free((isc_event_t *)iev);
|
||||||
}
|
}
|
||||||
@@ -628,12 +686,12 @@ internal_accept(isc_task_t task, isc_event_t ev)
|
|||||||
XTRACE(TRACE_LISTEN,
|
XTRACE(TRACE_LISTEN,
|
||||||
("internal_accept called, locked parent sock %p\n", sock));
|
("internal_accept called, locked parent sock %p\n", sock));
|
||||||
|
|
||||||
REQUIRE(sock->pending_recv);
|
REQUIRE(sock->pending_accept);
|
||||||
REQUIRE(sock->listener);
|
REQUIRE(sock->listener);
|
||||||
REQUIRE(!EMPTY(sock->accept_list));
|
REQUIRE(!EMPTY(sock->accept_list));
|
||||||
REQUIRE(iev->task == task);
|
REQUIRE(iev->task == task);
|
||||||
|
|
||||||
sock->pending_recv = ISC_FALSE;
|
sock->pending_accept = ISC_FALSE;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Has this event been canceled?
|
* Has this event been canceled?
|
||||||
@@ -658,7 +716,6 @@ internal_accept(isc_task_t task, isc_event_t ev)
|
|||||||
fd = accept(sock->fd, &addr, &addrlen);
|
fd = accept(sock->fd, &addr, &addrlen);
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
if (SOFT_ERROR(errno)) {
|
if (SOFT_ERROR(errno)) {
|
||||||
sock->pending_recv = ISC_FALSE;
|
|
||||||
select_poke(sock->manager, sock->fd);
|
select_poke(sock->manager, sock->fd);
|
||||||
UNLOCK(&sock->lock);
|
UNLOCK(&sock->lock);
|
||||||
return (0);
|
return (0);
|
||||||
@@ -672,12 +729,16 @@ internal_accept(isc_task_t task, isc_event_t ev)
|
|||||||
*/
|
*/
|
||||||
XTRACE(TRACE_LISTEN, ("internal_accept: accept returned %s\n",
|
XTRACE(TRACE_LISTEN, ("internal_accept: accept returned %s\n",
|
||||||
strerror(errno)));
|
strerror(errno)));
|
||||||
sock->pending_recv = ISC_FALSE;
|
|
||||||
select_poke(sock->manager, sock->fd);
|
select_poke(sock->manager, sock->fd);
|
||||||
UNLOCK(&sock->lock);
|
UNLOCK(&sock->lock);
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DEQUEUE(sock->accept_list, iev, link);
|
||||||
|
|
||||||
|
if (!EMPTY(sock->accept_list))
|
||||||
|
select_poke(sock->manager, sock->fd);
|
||||||
|
|
||||||
UNLOCK(&sock->lock);
|
UNLOCK(&sock->lock);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -685,8 +746,8 @@ internal_accept(isc_task_t task, isc_event_t ev)
|
|||||||
* fd and other information in the socket descriptor here. These
|
* fd and other information in the socket descriptor here. These
|
||||||
* were preallocated for us.
|
* were preallocated for us.
|
||||||
*/
|
*/
|
||||||
dev = iev->done;
|
dev = iev->done_ev;
|
||||||
iev->done = NULL;
|
iev->done_ev = NULL;
|
||||||
|
|
||||||
dev->newsocket->fd = fd;
|
dev->newsocket->fd = fd;
|
||||||
|
|
||||||
@@ -705,14 +766,16 @@ internal_accept(isc_task_t task, isc_event_t ev)
|
|||||||
*/
|
*/
|
||||||
LOCK(&sock->manager->lock);
|
LOCK(&sock->manager->lock);
|
||||||
sock->manager->fds[fd] = dev->newsocket;
|
sock->manager->fds[fd] = dev->newsocket;
|
||||||
|
sock->manager->fdstate[fd] = MANAGED;
|
||||||
if (sock->manager->maxfd < fd)
|
if (sock->manager->maxfd < fd)
|
||||||
sock->manager->maxfd = fd;
|
sock->manager->maxfd = fd;
|
||||||
|
sock->manager->nsockets++;
|
||||||
UNLOCK(&sock->manager->lock);
|
UNLOCK(&sock->manager->lock);
|
||||||
|
|
||||||
XTRACE(TRACE_LISTEN, ("internal_accept: newsock %p, fd %d\n",
|
XTRACE(TRACE_LISTEN, ("internal_accept: newsock %p, fd %d\n",
|
||||||
dev->newsocket, fd));
|
dev->newsocket, fd));
|
||||||
|
|
||||||
send_ncdone_event(sock, &iev, &dev, ISC_R_SUCCESS);
|
send_ncdone_event(&iev, &dev, ISC_R_SUCCESS);
|
||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
@@ -1041,18 +1104,36 @@ watcher(void *uap)
|
|||||||
writefds = manager->write_fds;
|
writefds = manager->write_fds;
|
||||||
maxfd = manager->maxfd + 1;
|
maxfd = manager->maxfd + 1;
|
||||||
|
|
||||||
|
XTRACE(TRACE_WATCHER, ("select maxfd %d\n", maxfd));
|
||||||
|
for (i = 0 ; i < FD_SETSIZE ; i++) {
|
||||||
|
int printit;
|
||||||
|
|
||||||
|
printit = 0;
|
||||||
|
|
||||||
|
if (FD_ISSET(i, &readfds)) {
|
||||||
|
printf("watcher: select r on %d\n", i);
|
||||||
|
printit = 1;
|
||||||
|
}
|
||||||
|
if (FD_ISSET(i, &writefds)) {
|
||||||
|
printf("watcher: select w on %d\n", i);
|
||||||
|
printit = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (printit && manager->fds[i] != NULL)
|
||||||
|
socket_dump(manager->fds[i]);
|
||||||
|
}
|
||||||
|
|
||||||
UNLOCK(&manager->lock);
|
UNLOCK(&manager->lock);
|
||||||
|
|
||||||
cc = select(maxfd, &readfds, &writefds, NULL,
|
cc = select(maxfd, &readfds, &writefds, NULL, NULL);
|
||||||
NULL);
|
|
||||||
XTRACE(TRACE_WATCHER,
|
XTRACE(TRACE_WATCHER,
|
||||||
("select(%d, ...) == %d, errno %d\n",
|
("select(%d, ...) == %d, errno %d\n",
|
||||||
maxfd, cc, errno));
|
maxfd, cc, errno));
|
||||||
if (cc < 0) {
|
if (cc < 0) {
|
||||||
if (!SOFT_ERROR(errno))
|
if (!SOFT_ERROR(errno))
|
||||||
UNEXPECTED_ERROR(__FILE__, __LINE__,
|
FATAL_ERROR(__FILE__, __LINE__,
|
||||||
"select failed: %s",
|
"select failed: %s",
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
}
|
}
|
||||||
|
|
||||||
LOCK(&manager->lock);
|
LOCK(&manager->lock);
|
||||||
@@ -1081,9 +1162,14 @@ watcher(void *uap)
|
|||||||
* it doesn't matter if we have to do a little
|
* it doesn't matter if we have to do a little
|
||||||
* more work first.
|
* more work first.
|
||||||
*/
|
*/
|
||||||
if (msg == SELECT_POKE_SHUTDOWN)
|
if (msg == SELECT_POKE_SHUTDOWN) {
|
||||||
|
XTRACE(TRACE_WATCHER,
|
||||||
|
("watcher got SHUTDOWN\n"));
|
||||||
done = ISC_TRUE;
|
done = ISC_TRUE;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This is a wakeup on a socket. Look
|
* This is a wakeup on a socket. Look
|
||||||
* at the event queue for both read and write,
|
* at the event queue for both read and write,
|
||||||
@@ -1093,7 +1179,26 @@ watcher(void *uap)
|
|||||||
if (msg >= 0) {
|
if (msg >= 0) {
|
||||||
INSIST(msg < FD_SETSIZE);
|
INSIST(msg < FD_SETSIZE);
|
||||||
|
|
||||||
|
if (manager->fdstate[msg] == CLOSE_PENDING) {
|
||||||
|
manager->fdstate[msg] = CLOSED;
|
||||||
|
FD_CLR(msg,
|
||||||
|
&manager->read_fds);
|
||||||
|
FD_CLR(msg,
|
||||||
|
&manager->write_fds);
|
||||||
|
|
||||||
|
close(msg);
|
||||||
|
XTRACE(TRACE_WATCHER,
|
||||||
|
("Watcher closed %d\n",
|
||||||
|
msg));
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (manager->fdstate[msg] != MANAGED)
|
||||||
|
continue;
|
||||||
|
|
||||||
sock = manager->fds[msg];
|
sock = manager->fds[msg];
|
||||||
|
|
||||||
LOCK(&sock->lock);
|
LOCK(&sock->lock);
|
||||||
XTRACE(TRACE_WATCHER,
|
XTRACE(TRACE_WATCHER,
|
||||||
("watcher locked socket %p\n",
|
("watcher locked socket %p\n",
|
||||||
@@ -1109,7 +1214,8 @@ watcher(void *uap)
|
|||||||
iev = HEAD(sock->recv_list);
|
iev = HEAD(sock->recv_list);
|
||||||
nciev = HEAD(sock->accept_list);
|
nciev = HEAD(sock->accept_list);
|
||||||
if ((iev == NULL && nciev == NULL)
|
if ((iev == NULL && nciev == NULL)
|
||||||
|| sock->pending_recv) {
|
|| sock->pending_recv
|
||||||
|
|| sock->pending_accept) {
|
||||||
FD_CLR(sock->fd,
|
FD_CLR(sock->fd,
|
||||||
&manager->read_fds);
|
&manager->read_fds);
|
||||||
XTRACE(TRACE_WATCHER,
|
XTRACE(TRACE_WATCHER,
|
||||||
@@ -1146,41 +1252,67 @@ watcher(void *uap)
|
|||||||
* and unlocking twice if both reads and writes are possible.
|
* and unlocking twice if both reads and writes are possible.
|
||||||
*/
|
*/
|
||||||
for (i = 0 ; i < maxfd ; i++) {
|
for (i = 0 ; i < maxfd ; i++) {
|
||||||
if (manager->fds[i] != NULL) {
|
if (i == manager->pipe_fds[0]
|
||||||
sock = manager->fds[i];
|
|| i == manager->pipe_fds[1])
|
||||||
unlock_sock = ISC_FALSE;
|
continue;
|
||||||
if (FD_ISSET(i, &readfds)) {
|
|
||||||
XTRACE(TRACE_WATCHER,
|
if (manager->fdstate[i] == CLOSE_PENDING) {
|
||||||
("watcher r on %d, sock %p\n",
|
manager->fdstate[i] = CLOSED;
|
||||||
i, manager->fds[i]));
|
FD_CLR(i, &manager->read_fds);
|
||||||
|
FD_CLR(i, &manager->write_fds);
|
||||||
|
|
||||||
|
close(i);
|
||||||
|
XTRACE(TRACE_WATCHER,
|
||||||
|
("Watcher closed %d\n", i));
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
sock = manager->fds[i];
|
||||||
|
unlock_sock = ISC_FALSE;
|
||||||
|
if (FD_ISSET(i, &readfds)) {
|
||||||
|
if (sock == NULL) {
|
||||||
|
FD_CLR(i, &manager->read_fds);
|
||||||
|
goto check_write;
|
||||||
|
}
|
||||||
|
XTRACE(TRACE_WATCHER,
|
||||||
|
("watcher r on %d, sock %p\n",
|
||||||
|
i, manager->fds[i]));
|
||||||
|
unlock_sock = ISC_TRUE;
|
||||||
|
LOCK(&sock->lock);
|
||||||
|
socket_dump(sock);
|
||||||
|
if (sock->listener)
|
||||||
|
dispatch_listen(sock);
|
||||||
|
else
|
||||||
|
dispatch_read(sock);
|
||||||
|
FD_CLR(i, &manager->read_fds);
|
||||||
|
}
|
||||||
|
check_write:
|
||||||
|
if (FD_ISSET(i, &writefds)) {
|
||||||
|
if (sock == NULL) {
|
||||||
|
FD_CLR(i, &manager->write_fds);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
XTRACE(TRACE_WATCHER,
|
||||||
|
("watcher w on %d, sock %p\n",
|
||||||
|
i, manager->fds[i]));
|
||||||
|
if (!unlock_sock) {
|
||||||
unlock_sock = ISC_TRUE;
|
unlock_sock = ISC_TRUE;
|
||||||
LOCK(&sock->lock);
|
LOCK(&sock->lock);
|
||||||
if (sock->listener)
|
|
||||||
dispatch_listen(sock);
|
|
||||||
else
|
|
||||||
dispatch_read(sock);
|
|
||||||
FD_CLR(i, &manager->read_fds);
|
|
||||||
}
|
}
|
||||||
if (FD_ISSET(i, &writefds)) {
|
if (sock->connecting)
|
||||||
XTRACE(TRACE_WATCHER,
|
dispatch_connect(sock);
|
||||||
("watcher w on %d, sock %p\n",
|
else
|
||||||
i, manager->fds[i]));
|
dispatch_write(sock);
|
||||||
if (!unlock_sock) {
|
FD_CLR(i, &manager->write_fds);
|
||||||
unlock_sock = ISC_TRUE;
|
|
||||||
LOCK(&sock->lock);
|
|
||||||
}
|
|
||||||
if (sock->connecting)
|
|
||||||
dispatch_connect(sock);
|
|
||||||
else
|
|
||||||
dispatch_write(sock);
|
|
||||||
FD_CLR(i, &manager->write_fds);
|
|
||||||
}
|
|
||||||
if (unlock_sock)
|
|
||||||
UNLOCK(&sock->lock);
|
|
||||||
}
|
}
|
||||||
|
if (unlock_sock)
|
||||||
|
UNLOCK(&sock->lock);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
XTRACE(TRACE_WATCHER, ("Watcher exiting\n"));
|
||||||
|
|
||||||
UNLOCK(&manager->lock);
|
UNLOCK(&manager->lock);
|
||||||
return ((isc_threadresult_t)0);
|
return ((isc_threadresult_t)0);
|
||||||
}
|
}
|
||||||
@@ -1237,6 +1369,7 @@ isc_socketmgr_create(isc_memctx_t mctx, isc_socketmgr_t *managerp)
|
|||||||
FD_ZERO(&manager->write_fds);
|
FD_ZERO(&manager->write_fds);
|
||||||
FD_SET(manager->pipe_fds[0], &manager->read_fds);
|
FD_SET(manager->pipe_fds[0], &manager->read_fds);
|
||||||
manager->maxfd = manager->pipe_fds[0];
|
manager->maxfd = manager->pipe_fds[0];
|
||||||
|
memset(manager->fdstate, 0, sizeof(manager->fdstate));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Start up the select/poll thread.
|
* Start up the select/poll thread.
|
||||||
@@ -1260,6 +1393,7 @@ void
|
|||||||
isc_socketmgr_destroy(isc_socketmgr_t *managerp)
|
isc_socketmgr_destroy(isc_socketmgr_t *managerp)
|
||||||
{
|
{
|
||||||
isc_socketmgr_t manager;
|
isc_socketmgr_t manager;
|
||||||
|
int i;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Destroy a socket manager.
|
* Destroy a socket manager.
|
||||||
@@ -1270,6 +1404,7 @@ isc_socketmgr_destroy(isc_socketmgr_t *managerp)
|
|||||||
REQUIRE(VALID_MANAGER(manager));
|
REQUIRE(VALID_MANAGER(manager));
|
||||||
|
|
||||||
LOCK(&manager->lock);
|
LOCK(&manager->lock);
|
||||||
|
XTRACE(TRACE_MANAGER, ("nsockets == %d\n", manager->nsockets));
|
||||||
REQUIRE(manager->nsockets == 0);
|
REQUIRE(manager->nsockets == 0);
|
||||||
manager->done = ISC_TRUE;
|
manager->done = ISC_TRUE;
|
||||||
UNLOCK(&manager->lock);
|
UNLOCK(&manager->lock);
|
||||||
@@ -1292,6 +1427,11 @@ isc_socketmgr_destroy(isc_socketmgr_t *managerp)
|
|||||||
*/
|
*/
|
||||||
close(manager->pipe_fds[0]);
|
close(manager->pipe_fds[0]);
|
||||||
close(manager->pipe_fds[1]);
|
close(manager->pipe_fds[1]);
|
||||||
|
|
||||||
|
for (i = 0 ; i < FD_SETSIZE ; i++)
|
||||||
|
if (manager->fdstate[i] == CLOSE_PENDING)
|
||||||
|
close(i);
|
||||||
|
|
||||||
(void)isc_mutex_destroy(&manager->lock);
|
(void)isc_mutex_destroy(&manager->lock);
|
||||||
manager->magic = 0;
|
manager->magic = 0;
|
||||||
isc_mem_put(manager->mctx, manager, sizeof *manager);
|
isc_mem_put(manager->mctx, manager, sizeof *manager);
|
||||||
@@ -1322,11 +1462,11 @@ isc_socket_recv(isc_socket_t sock, isc_region_t region,
|
|||||||
|
|
||||||
if (sock->riev == NULL) {
|
if (sock->riev == NULL) {
|
||||||
iev = (rwintev_t)isc_event_allocate(manager->mctx,
|
iev = (rwintev_t)isc_event_allocate(manager->mctx,
|
||||||
sock,
|
sock,
|
||||||
ISC_SOCKEVENT_INTIO,
|
ISC_SOCKEVENT_INTRECV,
|
||||||
internal_recv,
|
internal_recv,
|
||||||
sock,
|
sock,
|
||||||
sizeof(*iev));
|
sizeof(*iev));
|
||||||
if (iev == NULL) {
|
if (iev == NULL) {
|
||||||
/* no special free routine yet */
|
/* no special free routine yet */
|
||||||
isc_event_free((isc_event_t *)&ev);
|
isc_event_free((isc_event_t *)&ev);
|
||||||
@@ -1334,6 +1474,8 @@ isc_socket_recv(isc_socket_t sock, isc_region_t region,
|
|||||||
}
|
}
|
||||||
|
|
||||||
INIT_LINK(iev, link);
|
INIT_LINK(iev, link);
|
||||||
|
iev->posted = ISC_FALSE;
|
||||||
|
|
||||||
|
|
||||||
sock->riev = iev;
|
sock->riev = iev;
|
||||||
iev = NULL; /* just in case */
|
iev = NULL; /* just in case */
|
||||||
@@ -1473,7 +1615,7 @@ isc_socket_sendto(isc_socket_t sock, isc_region_t region,
|
|||||||
if (sock->wiev == NULL) {
|
if (sock->wiev == NULL) {
|
||||||
iev = (rwintev_t)isc_event_allocate(manager->mctx,
|
iev = (rwintev_t)isc_event_allocate(manager->mctx,
|
||||||
sock,
|
sock,
|
||||||
ISC_SOCKEVENT_INTIO,
|
ISC_SOCKEVENT_INTSEND,
|
||||||
internal_send,
|
internal_send,
|
||||||
sock,
|
sock,
|
||||||
sizeof(*iev));
|
sizeof(*iev));
|
||||||
@@ -1484,6 +1626,7 @@ isc_socket_sendto(isc_socket_t sock, isc_region_t region,
|
|||||||
}
|
}
|
||||||
|
|
||||||
INIT_LINK(iev, link);
|
INIT_LINK(iev, link);
|
||||||
|
iev->posted = ISC_FALSE;
|
||||||
|
|
||||||
sock->wiev = iev;
|
sock->wiev = iev;
|
||||||
iev = NULL; /* just in case */
|
iev = NULL; /* just in case */
|
||||||
@@ -1711,7 +1854,7 @@ isc_socket_accept(isc_socket_t sock,
|
|||||||
REQUIRE(sock->listener);
|
REQUIRE(sock->listener);
|
||||||
|
|
||||||
iev = (ncintev_t)isc_event_allocate(manager->mctx, sock,
|
iev = (ncintev_t)isc_event_allocate(manager->mctx, sock,
|
||||||
ISC_SOCKEVENT_INTCONN,
|
ISC_SOCKEVENT_INTACCEPT,
|
||||||
internal_accept, sock,
|
internal_accept, sock,
|
||||||
sizeof(*iev));
|
sizeof(*iev));
|
||||||
if (iev == NULL) {
|
if (iev == NULL) {
|
||||||
@@ -1719,6 +1862,8 @@ isc_socket_accept(isc_socket_t sock,
|
|||||||
return (ISC_R_NOMEMORY);
|
return (ISC_R_NOMEMORY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
iev->posted = ISC_FALSE;
|
||||||
|
|
||||||
dev = (isc_socket_newconnev_t)isc_event_allocate(manager->mctx,
|
dev = (isc_socket_newconnev_t)isc_event_allocate(manager->mctx,
|
||||||
sock,
|
sock,
|
||||||
ISC_SOCKEVENT_NEWCONN,
|
ISC_SOCKEVENT_NEWCONN,
|
||||||
@@ -1752,7 +1897,7 @@ isc_socket_accept(isc_socket_t sock,
|
|||||||
sock->listener = ISC_TRUE;
|
sock->listener = ISC_TRUE;
|
||||||
|
|
||||||
iev->task = ntask;
|
iev->task = ntask;
|
||||||
iev->done = dev;
|
iev->done_ev = dev;
|
||||||
iev->canceled = ISC_FALSE;
|
iev->canceled = ISC_FALSE;
|
||||||
dev->common.destroy = done_event_destroy;
|
dev->common.destroy = done_event_destroy;
|
||||||
dev->newsocket = nsock;
|
dev->newsocket = nsock;
|
||||||
@@ -1793,15 +1938,17 @@ isc_socket_connect(isc_socket_t sock, struct isc_sockaddr *addr, int addrlen,
|
|||||||
|
|
||||||
if (sock->ciev == NULL) {
|
if (sock->ciev == NULL) {
|
||||||
sock->ciev = (cnintev_t)isc_event_allocate(manager->mctx,
|
sock->ciev = (cnintev_t)isc_event_allocate(manager->mctx,
|
||||||
sock,
|
sock,
|
||||||
ISC_SOCKEVENT_INTCONN,
|
ISC_SOCKEVENT_INTCONN,
|
||||||
internal_connect,
|
internal_connect,
|
||||||
sock,
|
sock,
|
||||||
sizeof(*(sock->ciev)));
|
sizeof(*(sock->ciev)));
|
||||||
if (sock->ciev == NULL) {
|
if (sock->ciev == NULL) {
|
||||||
UNLOCK(&sock->lock);
|
UNLOCK(&sock->lock);
|
||||||
return (ISC_R_NOMEMORY);
|
return (ISC_R_NOMEMORY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sock->ciev->posted = ISC_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
dev = (isc_socket_connev_t)isc_event_allocate(manager->mctx,
|
dev = (isc_socket_connev_t)isc_event_allocate(manager->mctx,
|
||||||
@@ -1858,7 +2005,7 @@ isc_socket_connect(isc_socket_t sock, struct isc_sockaddr *addr, int addrlen,
|
|||||||
sock->connecting = ISC_TRUE;
|
sock->connecting = ISC_TRUE;
|
||||||
|
|
||||||
sock->ciev->task = ntask;
|
sock->ciev->task = ntask;
|
||||||
sock->ciev->done = dev;
|
sock->ciev->done_ev = dev;
|
||||||
sock->ciev->canceled = ISC_FALSE;
|
sock->ciev->canceled = ISC_FALSE;
|
||||||
dev->common.destroy = done_event_destroy;
|
dev->common.destroy = done_event_destroy;
|
||||||
|
|
||||||
@@ -1916,7 +2063,7 @@ internal_connect(isc_task_t task, isc_event_t ev)
|
|||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
dev = iev->done;
|
dev = iev->done_ev;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get any possible error status here.
|
* Get any possible error status here.
|
||||||
@@ -1972,29 +2119,34 @@ internal_connect(isc_task_t task, isc_event_t ev)
|
|||||||
* us.
|
* us.
|
||||||
*/
|
*/
|
||||||
isc_task_send(iev->task, (isc_event_t *)&dev);
|
isc_task_send(iev->task, (isc_event_t *)&dev);
|
||||||
iev->done = NULL;
|
iev->done_ev = NULL;
|
||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Locking should not be necessary
|
|
||||||
*/
|
|
||||||
isc_result_t
|
isc_result_t
|
||||||
isc_socket_getpeername(isc_socket_t sock, struct isc_sockaddr *addressp,
|
isc_socket_getpeername(isc_socket_t sock, struct isc_sockaddr *addressp,
|
||||||
int *lengthp)
|
int *lengthp)
|
||||||
{
|
{
|
||||||
if (*lengthp < sock->addrlength)
|
REQUIRE(VALID_SOCKET(sock));
|
||||||
|
REQUIRE(addressp != NULL);
|
||||||
|
REQUIRE(lengthp != NULL);
|
||||||
|
|
||||||
|
LOCK(&sock->lock);
|
||||||
|
|
||||||
|
if (*lengthp < sock->addrlength) {
|
||||||
|
UNLOCK(&sock->lock);
|
||||||
return (ISC_R_TOOSMALL);
|
return (ISC_R_TOOSMALL);
|
||||||
|
}
|
||||||
|
|
||||||
memcpy(addressp, &sock->address, sock->addrlength);
|
memcpy(addressp, &sock->address, sock->addrlength);
|
||||||
*lengthp = sock->addrlength;
|
*lengthp = sock->addrlength;
|
||||||
|
|
||||||
|
UNLOCK(&sock->lock);
|
||||||
|
|
||||||
return (ISC_R_SUCCESS);
|
return (ISC_R_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Locking should not be necessary
|
|
||||||
*/
|
|
||||||
isc_result_t
|
isc_result_t
|
||||||
isc_socket_getsockname(isc_socket_t sock, struct isc_sockaddr *addressp,
|
isc_socket_getsockname(isc_socket_t sock, struct isc_sockaddr *addressp,
|
||||||
int *lengthp)
|
int *lengthp)
|
||||||
@@ -2002,18 +2154,170 @@ isc_socket_getsockname(isc_socket_t sock, struct isc_sockaddr *addressp,
|
|||||||
struct isc_sockaddr addr;
|
struct isc_sockaddr addr;
|
||||||
int len;
|
int len;
|
||||||
|
|
||||||
|
REQUIRE(VALID_SOCKET(sock));
|
||||||
|
REQUIRE(addressp != NULL);
|
||||||
|
REQUIRE(lengthp != NULL);
|
||||||
|
|
||||||
|
LOCK(&sock->lock);
|
||||||
|
|
||||||
len = sizeof(addr);
|
len = sizeof(addr);
|
||||||
if (getsockname(sock->fd, (struct sockaddr *)&addr, &len) < 0) {
|
if (getsockname(sock->fd, (struct sockaddr *)&addr, &len) < 0) {
|
||||||
UNEXPECTED_ERROR(__FILE__, __LINE__,
|
UNEXPECTED_ERROR(__FILE__, __LINE__,
|
||||||
"getsockname: %s", strerror(errno));
|
"getsockname: %s", strerror(errno));
|
||||||
|
UNLOCK(&sock->lock);
|
||||||
return (ISC_R_UNEXPECTED);
|
return (ISC_R_UNEXPECTED);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*lengthp < sock->addrlength)
|
if (*lengthp < sock->addrlength) {
|
||||||
|
UNLOCK(&sock->lock);
|
||||||
return (ISC_R_TOOSMALL);
|
return (ISC_R_TOOSMALL);
|
||||||
|
}
|
||||||
|
|
||||||
memcpy(addressp, &sock->address, sock->addrlength);
|
memcpy(addressp, &sock->address, sock->addrlength);
|
||||||
*lengthp = sock->addrlength;
|
*lengthp = sock->addrlength;
|
||||||
|
|
||||||
|
UNLOCK(&sock->lock);
|
||||||
|
|
||||||
return (ISC_R_SUCCESS);
|
return (ISC_R_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Run through the list of events on this socket, and cancel the ones
|
||||||
|
* queued for task "task" of type "how". "how" is a bitmask.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
isc_socket_cancel(isc_socket_t sock, isc_task_t task,
|
||||||
|
unsigned int how)
|
||||||
|
{
|
||||||
|
isc_boolean_t poke_needed;
|
||||||
|
|
||||||
|
REQUIRE(VALID_SOCKET(sock));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Quick exit if there is nothing to do. Don't even bother locking
|
||||||
|
* in this case.
|
||||||
|
*/
|
||||||
|
if (how == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
poke_needed = ISC_FALSE;
|
||||||
|
|
||||||
|
LOCK(&sock->lock);
|
||||||
|
|
||||||
|
printf("Cancel how == %d\n", how);
|
||||||
|
socket_dump(sock);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* All of these do the same thing, more or less.
|
||||||
|
* Each will:
|
||||||
|
* o If the internal event is marked as "dispatched" try to
|
||||||
|
* remove it from the task's queue. If this fails, mark it
|
||||||
|
* as canceled instead, and let the task clean it up later.
|
||||||
|
* o For each I/O request for that task of that type, post
|
||||||
|
* its done event with status of "ISC_R_CANCELED".
|
||||||
|
* o Reset any state needed.
|
||||||
|
*/
|
||||||
|
if ((how & ISC_SOCKCANCEL_RECV) && HEAD(sock->recv_list) != NULL) {
|
||||||
|
rwintev_t iev;
|
||||||
|
rwintev_t next;
|
||||||
|
isc_socketevent_t dev;
|
||||||
|
|
||||||
|
iev = HEAD(sock->recv_list);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the internal event was posted, try to remove
|
||||||
|
* it from the task's queue. If this fails,
|
||||||
|
* set the canceled flag, post the done event, and
|
||||||
|
* point "iev" to the next item on the list, and enter
|
||||||
|
* the while loop. Otherwise, just enter the while loop
|
||||||
|
* and let it dispatch the done event.
|
||||||
|
*/
|
||||||
|
if ((task == NULL || task == iev->task)
|
||||||
|
&& iev->posted && !iev->canceled) {
|
||||||
|
if (isc_task_purge(task, sock,
|
||||||
|
ISC_SOCKEVENT_INTRECV) == 0) {
|
||||||
|
iev->canceled = ISC_TRUE;
|
||||||
|
/*
|
||||||
|
* pull off the done event and post it.
|
||||||
|
*/
|
||||||
|
dev = iev->done_ev;
|
||||||
|
iev->done_ev = NULL;
|
||||||
|
dev->result = ISC_R_CANCELED;
|
||||||
|
isc_task_send(iev->task,
|
||||||
|
(isc_event_t *)&dev);
|
||||||
|
|
||||||
|
iev = NEXT(iev, link);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* run through the event queue, posting done events with the
|
||||||
|
* canceled result, and freeing the internal event.
|
||||||
|
*/
|
||||||
|
while (iev != NULL) {
|
||||||
|
next = NEXT(iev, link);
|
||||||
|
|
||||||
|
if (task == NULL || task == iev->task)
|
||||||
|
send_recvdone_event(sock, &iev,
|
||||||
|
&iev->done_ev,
|
||||||
|
ISC_R_CANCELED);
|
||||||
|
|
||||||
|
iev = next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (how & ISC_SOCKCANCEL_SEND) {
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((how & ISC_SOCKCANCEL_ACCEPT) && HEAD(sock->accept_list) != NULL) {
|
||||||
|
ncintev_t iev;
|
||||||
|
ncintev_t next;
|
||||||
|
isc_socket_newconnev_t dev;
|
||||||
|
|
||||||
|
iev = HEAD(sock->accept_list);
|
||||||
|
|
||||||
|
if ((task == NULL || task == iev->task)
|
||||||
|
&& iev->posted && !iev->canceled) {
|
||||||
|
if (isc_task_purge(task, sock,
|
||||||
|
ISC_SOCKEVENT_INTACCEPT) == 0) {
|
||||||
|
iev->canceled = ISC_TRUE;
|
||||||
|
dev = iev->done_ev;
|
||||||
|
iev->done_ev = NULL;
|
||||||
|
dev->result = ISC_R_CANCELED;
|
||||||
|
dev->newsocket->references--;
|
||||||
|
free_socket(&dev->newsocket);
|
||||||
|
isc_task_send(iev->task,
|
||||||
|
(isc_event_t *)&dev);
|
||||||
|
|
||||||
|
iev = NEXT(iev, link);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
while (iev != NULL) {
|
||||||
|
next = NEXT(iev, link);
|
||||||
|
|
||||||
|
if (task == NULL || task == iev->task) {
|
||||||
|
dev = iev->done_ev;
|
||||||
|
iev->done_ev = NULL;
|
||||||
|
dev->newsocket->references--;
|
||||||
|
free_socket(&dev->newsocket);
|
||||||
|
DEQUEUE(sock->accept_list, iev, link);
|
||||||
|
send_ncdone_event(&iev, &dev, ISC_R_CANCELED);
|
||||||
|
}
|
||||||
|
|
||||||
|
iev = next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (how & ISC_SOCKCANCEL_CONNECT) {
|
||||||
|
}
|
||||||
|
|
||||||
|
socket_dump(sock);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Need to guess if we need to poke or not... XXX
|
||||||
|
*/
|
||||||
|
select_poke(sock->manager, sock->fd);
|
||||||
|
|
||||||
|
UNLOCK(&sock->lock);
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user