X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/cc9f6e38162d3c1bf6ca97536c2477f476c8e01b..5d5c5d0d5b79ade9a973d55186ffda2638ba2b6e:/bsd/kern/uipc_socket2.c diff --git a/bsd/kern/uipc_socket2.c b/bsd/kern/uipc_socket2.c index 1d324fc8b..2a47db5d1 100644 --- a/bsd/kern/uipc_socket2.c +++ b/bsd/kern/uipc_socket2.c @@ -1,23 +1,31 @@ /* * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. * - * @APPLE_LICENSE_HEADER_START@ + * @APPLE_LICENSE_OSREFERENCE_HEADER_START@ * - * The contents of this file constitute Original Code as defined in and - * are subject to the Apple Public Source License Version 1.1 (the - * "License"). You may not use this file except in compliance with the - * License. Please obtain a copy of the License at - * http://www.apple.com/publicsource and read it before using this file. - * - * This Original Code and all software distributed under the License are - * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the - * License for the specific language governing rights and limitations - * under the License. - * - * @APPLE_LICENSE_HEADER_END@ + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the + * License may not be used to create, or enable the creation or + * redistribution of, unlawful or unlicensed copies of an Apple operating + * system, or to circumvent, violate, or enable the circumvention or + * violation of, any terms of an Apple operating system software license + * agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_OSREFERENCE_HEADER_END@ */ /* Copyright (c) 1998, 1999 Apple Computer, Inc. All Rights Reserved */ /* Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved */ @@ -81,6 +89,7 @@ #define DBG_FNC_SBDROP NETDBG_CODE(DBG_NETSOCK, 4) #define DBG_FNC_SBAPPEND NETDBG_CODE(DBG_NETSOCK, 5) +static int sbcompress(struct sockbuf *, struct mbuf *, struct mbuf *); /* * Primitive routines for operating on sockets and socket buffers @@ -142,18 +151,22 @@ soisconnected(so) sflt_notify(so, sock_evt_connected, NULL); if (head && (so->so_state & SS_INCOMP)) { - if (head->so_proto->pr_getlock != NULL) + so->so_state &= ~SS_INCOMP; + so->so_state |= SS_COMP; + if (head->so_proto->pr_getlock != NULL) { + socket_unlock(so, 0); socket_lock(head, 1); + } postevent(head, 0, EV_RCONN); TAILQ_REMOVE(&head->so_incomp, so, so_list); head->so_incqlen--; - so->so_state &= ~SS_INCOMP; TAILQ_INSERT_TAIL(&head->so_comp, so, so_list); - so->so_state |= SS_COMP; sorwakeup(head); wakeup_one((caddr_t)&head->so_timeo); - if (head->so_proto->pr_getlock != NULL) + if (head->so_proto->pr_getlock != NULL) { socket_unlock(head, 1); + socket_lock(so, 0); + } } else { postevent(so, 0, EV_WCONN); wakeup((caddr_t)&so->so_timeo); @@ -283,6 +296,14 @@ sonewconn_internal(head, connstatus) so->so_pgid = head->so_pgid; so->so_uid = head->so_uid; so->so_usecount = 1; + so->next_lock_lr = 0; + so->next_unlock_lr = 0; + +#ifdef __APPLE__ + so->so_rcv.sb_flags |= SB_RECV; /* XXX */ + so->so_rcv.sb_so = so->so_snd.sb_so = so; + TAILQ_INIT(&so->so_evlist); +#endif if (soreserve(so, head->so_snd.sb_hiwat, head->so_rcv.sb_hiwat)) { sflt_termsock(so); @@ -291,16 +312,19 @@ sonewconn_internal(head, connstatus) } /* - * Must be done with head unlocked to avoid deadlock with pcb list + * Must be done with head unlocked to avoid deadlock for protocol with per socket mutexes. */ - socket_unlock(head, 0); + if (head->so_proto->pr_unlock) + socket_unlock(head, 0); if (((*so->so_proto->pr_usrreqs->pru_attach)(so, 0, NULL) != 0) || error) { sflt_termsock(so); sodealloc(so); - socket_lock(head, 0); + if (head->so_proto->pr_unlock) + socket_lock(head, 0); return ((struct socket *)0); } - socket_lock(head, 0); + if (head->so_proto->pr_unlock) + socket_lock(head, 0); #ifdef __APPLE__ so->so_proto->pr_domain->dom_refs++; #endif @@ -314,12 +338,10 @@ sonewconn_internal(head, connstatus) head->so_incqlen++; } head->so_qlen++; -#ifdef __APPLE__ - so->so_rcv.sb_so = so->so_snd.sb_so = so; - TAILQ_INIT(&so->so_evlist); - /* Attach socket filters for this protocol */ - sflt_initsock(so); +#ifdef __APPLE__ + /* Attach socket filters for this protocol */ + sflt_initsock(so); #endif if (connstatus) { so->so_state |= connstatus; @@ -400,17 +422,13 @@ int sbwait(sb) struct sockbuf *sb; { - int error = 0, lr, lr_saved; + int error = 0, lr_saved; struct socket *so = sb->sb_so; lck_mtx_t *mutex_held; struct timespec ts; -#ifdef __ppc__ - __asm__ volatile("mflr %0" : "=r" (lr)); - lr_saved = lr; -#endif + lr_saved = (unsigned int) __builtin_return_address(0); - if (so->so_proto->pr_getlock != NULL) mutex_held = (*so->so_proto->pr_getlock)(so, 0); else @@ -448,12 +466,7 @@ sb_lock(sb) { struct socket *so = sb->sb_so; lck_mtx_t * mutex_held; - int error = 0, lr, lr_saved; - -#ifdef __ppc__ - __asm__ volatile("mflr %0" : "=r" (lr)); - lr_saved = lr; -#endif + int error = 0; if (so == NULL) panic("sb_lock: null so back pointer sb=%x\n", sb); @@ -466,6 +479,7 @@ sb_lock(sb) mutex_held = so->so_proto->pr_domain->dom_mtx; if (so->so_usecount < 1) panic("sb_lock: so=%x refcount=%d\n", so, so->so_usecount); + error = msleep((caddr_t)&sb->sb_flags, mutex_held, (sb->sb_flags & SB_NOINTR) ? PSOCK : PSOCK | PCATCH, "sblock", 0); if (so->so_usecount < 1) @@ -731,7 +745,7 @@ sbcheck(sb) int sbappendrecord(sb, m0) register struct sockbuf *sb; - register struct mbuf *m0; + struct mbuf *m0; { register struct mbuf *m; int result = 0; @@ -1455,13 +1469,12 @@ void sbunlock(struct sockbuf *sb, int keeplocked) { struct socket *so = sb->sb_so; - int lr, lr_saved; + int lr_saved; lck_mtx_t *mutex_held; -#ifdef __ppc__ - __asm__ volatile("mflr %0" : "=r" (lr)); - lr_saved = lr; -#endif + + lr_saved = (unsigned int) __builtin_return_address(0); + sb->sb_flags &= ~SB_LOCK; if (so->so_proto->pr_getlock != NULL) @@ -1483,7 +1496,8 @@ sbunlock(struct sockbuf *sb, int keeplocked) so->so_usecount--; if (so->so_usecount < 0) panic("sbunlock: unlock on exit so=%x lr=%x sb_flags=%x\n", so, so->so_usecount,lr_saved, sb->sb_flags); - so->reserved4= lr_saved; + so->unlock_lr[so->next_unlock_lr] = (void *)lr_saved; + so->next_unlock_lr = (so->next_unlock_lr+1) % SO_LCKDBG_MAX; lck_mtx_unlock(mutex_held); } }