diff options
author | John Baldwin <jhb@FreeBSD.org> | 2009-06-01 21:17:03 +0000 |
---|---|---|
committer | John Baldwin <jhb@FreeBSD.org> | 2009-06-01 21:17:03 +0000 |
commit | 74fb0ba732c0470e4cae21d0a7af01715bd77bc3 (patch) | |
tree | 13628b6be10af95db7dc7d8ef88b3291d48583ab /sys/sys/socketvar.h | |
parent | b2bc85365907ed05547af9b400576928866915b9 (diff) | |
download | src-74fb0ba732c0470e4cae21d0a7af01715bd77bc3.tar.gz src-74fb0ba732c0470e4cae21d0a7af01715bd77bc3.zip |
Rework socket upcalls to close some races with setup/teardown of upcalls.
- Each socket upcall is now invoked with the appropriate socket buffer
locked. It is not permissible to call soisconnected() with this lock
held; however, so socket upcalls now return an integer value. The two
possible values are SU_OK and SU_ISCONNECTED. If an upcall returns
SU_ISCONNECTED, then the soisconnected() will be invoked on the
socket after the socket buffer lock is dropped.
- A new API is provided for setting and clearing socket upcalls. The
API consists of soupcall_set() and soupcall_clear().
- To simplify locking, each socket buffer now has a separate upcall.
- When a socket upcall returns SU_ISCONNECTED, the upcall is cleared from
the receive socket buffer automatically. Note that a SO_SND upcall
should never return SU_ISCONNECTED.
- All this means that accept filters should now return SU_ISCONNECTED
instead of calling soisconnected() directly. They also no longer need
to explicitly clear the upcall on the new socket.
- The HTTP accept filter still uses soupcall_set() to manage its internal
state machine, but other accept filters no longer have any explicit
knowlege of socket upcall internals aside from their return value.
- The various RPC client upcalls currently drop the socket buffer lock
while invoking soreceive() as a temporary band-aid. The plan for
the future is to add a new flag to allow soreceive() to be called with
the socket buffer locked.
- The AIO callback for socket I/O is now also invoked with the socket
buffer locked. Previously sowakeup() would drop the socket buffer
lock only to call aio_swake() which immediately re-acquired the socket
buffer lock for the duration of the function call.
Discussed with: rwatson, rmacklem
Notes
Notes:
svn path=/head/; revision=193272
Diffstat (limited to 'sys/sys/socketvar.h')
-rw-r--r-- | sys/sys/socketvar.h | 17 |
1 files changed, 14 insertions, 3 deletions
diff --git a/sys/sys/socketvar.h b/sys/sys/socketvar.h index 81e6b8825afd..6565930da6f7 100644 --- a/sys/sys/socketvar.h +++ b/sys/sys/socketvar.h @@ -55,6 +55,8 @@ struct vnet; */ typedef u_quad_t so_gen_t; +struct socket; + /*- * Locking key to struct socket: * (a) constant after allocation, no locking required. @@ -104,8 +106,6 @@ struct socket { struct sockbuf so_rcv, so_snd; - void (*so_upcall)(struct socket *, void *, int); - void *so_upcallarg; struct ucred *so_cred; /* (a) user credentials */ struct label *so_label; /* (b) MAC label for socket */ struct label *so_peerlabel; /* (b) cached MAC label for peer */ @@ -280,7 +280,7 @@ struct xsocket { struct accept_filter { char accf_name[16]; - void (*accf_callback) + int (*accf_callback) (struct socket *so, void *arg, int waitflag); void * (*accf_create) (struct socket *so, char *arg); @@ -305,6 +305,14 @@ struct sockaddr; struct ucred; struct uio; +/* 'which' values for socket upcalls. */ +#define SO_RCV 1 +#define SO_SND 2 + +/* Return values for socket upcalls. */ +#define SU_OK 0 +#define SU_ISCONNECTED 1 + /* * From uipc_socket and friends */ @@ -356,6 +364,9 @@ int sosend_generic(struct socket *so, struct sockaddr *addr, int flags, struct thread *td); int soshutdown(struct socket *so, int how); void sotoxsocket(struct socket *so, struct xsocket *xso); +void soupcall_clear(struct socket *so, int which); +void soupcall_set(struct socket *so, int which, + int (*func)(struct socket *, void *, int), void *arg); void sowakeup(struct socket *so, struct sockbuf *sb); int selsocket(struct socket *so, int events, struct timeval *tv, struct thread *td); |