/* * This routine inserts a polldat into the portcache's hash table. It * may be necessary to grow the size of the hash table. */ static void port_cache_insert_fd(port_fdcache_t *pcp, polldat_t *pdp) { portfd_t **bucket; ASSERT(MUTEX_HELD(&pcp->pc_lock)); if (pcp->pc_fdcount > (pcp->pc_hashsize * PORTHASH_MULT)) port_cache_grow_hashtbl(pcp); bucket = PORT_FD_BUCKET(pcp, pdp->pd_fd); pdp->pd_hashnext = PFTOD(*bucket); *bucket = PDTOF(pdp); pcp->pc_fdcount++; }
/* * This routine returns a pointer to a cached poll fd entry, or NULL if it * does not find it in the hash table. * The fd is used as index. * The fd and the fp are used to detect a valid entry. * This function returns a pointer to a valid portfd_t structure only when * the fd and the fp in the args match the entries in polldat_t. */ portfd_t * port_cache_lookup_fp(port_fdcache_t *pcp, int fd, file_t *fp) { polldat_t *pdp; portfd_t **bucket; ASSERT(MUTEX_HELD(&pcp->pc_lock)); bucket = PORT_FD_BUCKET(pcp, fd); pdp = PFTOD(*bucket); while (pdp != NULL) { if (pdp->pd_fd == fd && pdp->pd_fp == fp) break; pdp = pdp->pd_hashnext; } return (PDTOF(pdp)); }
/* * This routine removes a portfd_t from the fd cache's hash table. */ void port_pcache_remove_fd(port_fdcache_t *pcp, portfd_t *pfd) { polldat_t *lpdp; polldat_t *cpdp; portfd_t **bucket; polldat_t *pdp = PFTOD(pfd); ASSERT(MUTEX_HELD(&pcp->pc_lock)); bucket = PORT_FD_BUCKET(pcp, pdp->pd_fd); cpdp = PFTOD(*bucket); if (pdp == cpdp) { *bucket = PDTOF(pdp->pd_hashnext); if (--pcp->pc_fdcount == 0) { /* * signal the thread which may have blocked in * port_close_sourcefd() on lastclose waiting * for pc_fdcount to drop to 0. */ cv_signal(&pcp->pc_lclosecv); } kmem_free(pfd, sizeof (portfd_t)); return; } while (cpdp != NULL) { lpdp = cpdp; cpdp = cpdp->pd_hashnext; if (cpdp == pdp) { /* polldat struct found */ lpdp->pd_hashnext = pdp->pd_hashnext; if (--pcp->pc_fdcount == 0) { /* * signal the thread which may have blocked in * port_close_sourcefd() on lastclose waiting * for pc_fdcount to drop to 0. */ cv_signal(&pcp->pc_lclosecv); } break; } } ASSERT(cpdp != NULL); kmem_free(pfd, sizeof (portfd_t)); }