/*
* Copyright (c) 2000-2004 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) 1982, 1986, 1989, 1991, 1993
struct zone *unp_zone;
static unp_gen_t unp_gencnt;
static u_int unp_count;
-static lck_mtx_t *unp_mutex;
+
+static lck_attr_t *unp_mtx_attr;
+static lck_grp_t *unp_mtx_grp;
+static lck_grp_attr_t *unp_mtx_grp_attr;
+static lck_rw_t *unp_list_mtx;
extern lck_mtx_t * uipc_lock;
static struct unp_head unp_shead, unp_dhead;
goto release;
}
- if (control && (error = unp_internalize(control, p)))
- goto release;
+ if (control) {
+ socket_unlock(so, 0); /* release global lock to avoid deadlock (4436174) */
+ error = unp_internalize(control, p);
+ socket_lock(so, 0);
+ if (error)
+ goto release;
+ }
switch (so->so_type) {
case SOCK_DGRAM:
if (unp == NULL)
return (ENOBUFS);
bzero(unp, sizeof *unp);
- lck_mtx_lock(unp_mutex);
+ lck_rw_lock_exclusive(unp_list_mtx);
LIST_INIT(&unp->unp_refs);
unp->unp_socket = so;
unp->unp_gencnt = ++unp_gencnt;
LIST_INSERT_HEAD(so->so_type == SOCK_DGRAM ? &unp_dhead
: &unp_shead, unp, unp_link);
so->so_pcb = (caddr_t)unp;
- lck_mtx_unlock(unp_mutex);
+ lck_rw_done(unp_list_mtx);
return (0);
}
static void
unp_detach(struct unpcb *unp)
{
- lck_mtx_assert(unp_mutex, LCK_MTX_ASSERT_OWNED);
+ lck_rw_lock_exclusive(unp_list_mtx);
LIST_REMOVE(unp, unp_link);
unp->unp_gencnt = ++unp_gencnt;
+ lck_rw_done(unp_list_mtx);
--unp_count;
if (unp->unp_vnode) {
struct vnode *tvp = unp->unp_vnode;
if (error)
goto bad;
so2 = vp->v_socket;
- if (so2 == 0) {
+ if (so2 == 0 || so2->so_pcb == NULL ) {
error = ECONNREFUSED;
goto bad;
}
}
error = unp_connect2(so, so2);
bad:
- if (so2 != NULL)
- so2->so_usecount--; /* release count on socket */
+
+ if (so2 != NULL)
+ so2->so_usecount--; /* release count on socket */
+
vnode_put(vp);
return (error);
}
if (unp2 == 0)
return;
- lck_mtx_assert(unp_mutex, LCK_MTX_ASSERT_OWNED);
unp->unp_conn = 0;
switch (unp->unp_socket->so_type) {
case SOCK_DGRAM:
+ lck_rw_lock_exclusive(unp_list_mtx);
LIST_REMOVE(unp, unp_reflink);
+ lck_rw_done(unp_list_mtx);
unp->unp_socket->so_state &= ~SS_ISCONNECTED;
break;
struct xunpgen xug;
struct unp_head *head;
- lck_mtx_lock(unp_mutex);
+ lck_rw_lock_shared(unp_list_mtx);
head = ((intptr_t)arg1 == SOCK_DGRAM ? &unp_dhead : &unp_shead);
/*
n = unp_count;
req->oldidx = 2 * (sizeof xug)
+ (n + n/8) * sizeof(struct xunpcb);
- lck_mtx_unlock(unp_mutex);
+ lck_rw_done(unp_list_mtx);
return 0;
}
if (req->newptr != USER_ADDR_NULL) {
- lck_mtx_unlock(unp_mutex);
+ lck_rw_done(unp_list_mtx);
return EPERM;
}
xug.xug_sogen = so_gencnt;
error = SYSCTL_OUT(req, &xug, sizeof xug);
if (error) {
- lck_mtx_unlock(unp_mutex);
+ lck_rw_done(unp_list_mtx);
return error;
}
* We are done if there is no pcb
*/
if (n == 0) {
- lck_mtx_unlock(unp_mutex);
+ lck_rw_done(unp_list_mtx);
return 0;
}
MALLOC(unp_list, struct unpcb **, n * sizeof *unp_list, M_TEMP, M_WAITOK);
if (unp_list == 0) {
- lck_mtx_unlock(unp_mutex);
+ lck_rw_done(unp_list_mtx);
return ENOMEM;
}
error = SYSCTL_OUT(req, &xug, sizeof xug);
}
FREE(unp_list, M_TEMP);
- lck_mtx_unlock(unp_mutex);
+ lck_rw_done(unp_list_mtx);
return error;
}
LIST_INIT(&unp_dhead);
LIST_INIT(&unp_shead);
- unp_mutex = localdomain.dom_mtx;
+ /*
+ * allocate lock group attribute and group for udp pcb mutexes
+ */
+ unp_mtx_grp_attr = lck_grp_attr_alloc_init();
+
+ unp_mtx_grp = lck_grp_alloc_init("unp_list", unp_mtx_grp_attr);
+
+ unp_mtx_attr = lck_attr_alloc_init();
+
+ if ((unp_list_mtx = lck_rw_alloc_init(unp_mtx_grp, unp_mtx_attr)) == NULL)
+ return; /* pretty much dead if this fails... */
+
}
#ifndef MIN