Changeset View
Changeset View
Standalone View
Standalone View
head/sys/kern/kern_descrip.c
Show First 20 Lines • Show All 1,795 Lines • ▼ Show 20 Lines | fdgrowtable(struct filedesc *fdp, int nfd) | ||||
/* | /* | ||||
* Make sure that ntable is correctly initialized before we replace | * Make sure that ntable is correctly initialized before we replace | ||||
* fd_files poiner. Otherwise fget_unlocked() may see inconsistent | * fd_files poiner. Otherwise fget_unlocked() may see inconsistent | ||||
* data. | * data. | ||||
*/ | */ | ||||
atomic_store_rel_ptr((volatile void *)&fdp->fd_files, (uintptr_t)ntable); | atomic_store_rel_ptr((volatile void *)&fdp->fd_files, (uintptr_t)ntable); | ||||
/* | /* | ||||
* Do not free the old file table, as some threads may still | * Free the old file table when not shared by other threads or processes. | ||||
* reference entries within it. Instead, place it on a freelist | * The old file table is considered to be shared when either are true: | ||||
* - The process has more than one thread. | |||||
* - The file descriptor table has been shared via fdshare(). | |||||
* | |||||
* When shared, the old file table will be placed on a freelist | |||||
* which will be processed when the struct filedesc is released. | * which will be processed when the struct filedesc is released. | ||||
* | * | ||||
* Note that if onfiles == NDFILE, we're dealing with the original | * Note that if onfiles == NDFILE, we're dealing with the original | ||||
* static allocation contained within (struct filedesc0 *)fdp, | * static allocation contained within (struct filedesc0 *)fdp, | ||||
* which must not be freed. | * which must not be freed. | ||||
*/ | */ | ||||
if (onfiles > NDFILE) { | if (onfiles > NDFILE) { | ||||
if (curproc->p_numthreads == 1 && fdp->fd_refcnt == 1) | |||||
free(otable, M_FILEDESC); | |||||
else { | |||||
ft = (struct freetable *)&otable->fdt_ofiles[onfiles]; | ft = (struct freetable *)&otable->fdt_ofiles[onfiles]; | ||||
fdp0 = (struct filedesc0 *)fdp; | fdp0 = (struct filedesc0 *)fdp; | ||||
ft->ft_table = otable; | ft->ft_table = otable; | ||||
SLIST_INSERT_HEAD(&fdp0->fd_free, ft, ft_next); | SLIST_INSERT_HEAD(&fdp0->fd_free, ft, ft_next); | ||||
} | |||||
} | } | ||||
/* | /* | ||||
* The map does not have the same possibility of threads still | * The map does not have the same possibility of threads still | ||||
* holding references to it. So always free it as long as it | * holding references to it. So always free it as long as it | ||||
* does not reference the original static allocation. | * does not reference the original static allocation. | ||||
*/ | */ | ||||
if (NDSLOTS(onfiles) > NDSLOTS(NDFILE)) | if (NDSLOTS(onfiles) > NDSLOTS(NDFILE)) | ||||
free(omap, M_FILEDESC); | free(omap, M_FILEDESC); | ||||
▲ Show 20 Lines • Show All 3,059 Lines • Show Last 20 Lines |