Print this page
pbchk
cleanup port_free_event_local() semantics
@@ -23,11 +23,11 @@
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
- * Copyright (c) 2014, Joyent, Inc. All rights reserved.
+ * Copyright 2020 Joyent, Inc.
*/
#include <sys/types.h>
#include <sys/vnode.h>
#include <sys/vfs_opreg.h>
@@ -113,19 +113,29 @@
port_kevent_t *pkevp;
int events; /* ignore events */
mutex_enter(&portq->portq_mutex);
while (pkevp = list_head(&portq->portq_list)) {
+ port_t *pp = pkevp->portkev_port;
+
portq->portq_nent--;
list_remove(&portq->portq_list, pkevp);
if (pkevp->portkev_callback) {
(void) (*pkevp->portkev_callback)(pkevp->portkev_arg,
&events, pkevp->portkev_pid, PORT_CALLBACK_CLOSE,
pkevp);
}
- mutex_exit(&portq->portq_mutex);
- port_free_event_local(pkevp, 0);
+ /*
+ * Don't drop the portq_mutex, but instead perform the
+ * decrement of port_curr in advance of calling
+ * port_free_event_local(). We do need to reacquire
+ * portq_mutex so we can properly wait for any
+ * pollwakeup()-signalled threads to finish up.
+ */
+ if (--pp->port_curr < pp->port_max_events)
+ cv_signal(&pp->port_cv);
+ port_free_event_local(pkevp, B_FALSE);
mutex_enter(&portq->portq_mutex);
}
/*
* Wait for any thread in pollwakeup(), accessing this port to