aboutsummaryrefslogtreecommitdiff
path: root/sys/sys/socketvar.h
diff options
context:
space:
mode:
authorJohn Baldwin <jhb@FreeBSD.org>2009-06-01 21:17:03 +0000
committerJohn Baldwin <jhb@FreeBSD.org>2009-06-01 21:17:03 +0000
commit74fb0ba732c0470e4cae21d0a7af01715bd77bc3 (patch)
tree13628b6be10af95db7dc7d8ef88b3291d48583ab /sys/sys/socketvar.h
parentb2bc85365907ed05547af9b400576928866915b9 (diff)
downloadsrc-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.h17
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);