summaryrefslogtreecommitdiff
path: root/usr/src/uts
diff options
context:
space:
mode:
authorpraks <none@none>2007-08-20 17:45:19 -0700
committerpraks <none@none>2007-08-20 17:45:19 -0700
commit8b79e857d6e0e451d2bfffef5af697d008e9b28c (patch)
tree47336038820c64413311edb2526e84e13f60e6e5 /usr/src/uts
parentb6233ca500dcfb36bc38a5dbd2c7e3584f2c2485 (diff)
downloadillumos-gate-8b79e857d6e0e451d2bfffef5af697d008e9b28c.tar.gz
6536565 port_close() hangs in the kernel with pending timer cleanup
Diffstat (limited to 'usr/src/uts')
-rw-r--r--usr/src/uts/common/os/timer.c22
1 files changed, 16 insertions, 6 deletions
diff --git a/usr/src/uts/common/os/timer.c b/usr/src/uts/common/os/timer.c
index 801a7691ff..57c1ed97bd 100644
--- a/usr/src/uts/common/os/timer.c
+++ b/usr/src/uts/common/os/timer.c
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -32,7 +32,7 @@
#include <sys/kmem.h>
#include <sys/debug.h>
#include <sys/policy.h>
-#include <sys/port.h>
+#include <sys/port_impl.h>
#include <sys/port_kernel.h>
#include <sys/contract/process_impl.h>
@@ -138,15 +138,20 @@ timer_delete_locked(proc_t *p, timer_t tid, itimer_t *it)
if (it->it_portev) {
mutex_enter(&it->it_mutex);
if (it->it_portev) {
+ port_kevent_t *pev;
/* dissociate timer from the event port */
(void) port_dissociate_ksource(it->it_portfd,
PORT_SOURCE_TIMER, (port_source_t *)it->it_portsrc);
- port_free_event((port_kevent_t *)it->it_portev);
+ pev = (port_kevent_t *)it->it_portev;
it->it_portev = NULL;
it->it_flags &= ~IT_PORT;
it->it_pending = 0;
+ mutex_exit(&it->it_mutex);
+ (void) port_remove_done_event(pev);
+ port_free_event(pev);
+ } else {
+ mutex_exit(&it->it_mutex);
}
- mutex_exit(&it->it_mutex);
}
mutex_enter(&p->p_lock);
@@ -984,11 +989,16 @@ timer_close_port(void *arg, int port, pid_t pid, int lastclose)
if (it->it_portev) {
mutex_enter(&it->it_mutex);
if (it->it_portfd == port) {
- port_free_event((port_kevent_t *)it->it_portev);
+ port_kevent_t *pev;
+ pev = (port_kevent_t *)it->it_portev;
it->it_portev = NULL;
it->it_flags &= ~IT_PORT;
+ mutex_exit(&it->it_mutex);
+ (void) port_remove_done_event(pev);
+ port_free_event(pev);
+ } else {
+ mutex_exit(&it->it_mutex);
}
- mutex_exit(&it->it_mutex);
}
timer_release(p, it);
}