Cleanup XXXdir functions to eliminate global hash table of
telldir positions. This will allow (future) locking on a per-DIR basis (for MT-safety). For now, this change does the following: o Remove the hash table from telldir.c. Recode to use queue macros. o Remove 'const' from 'telldir(const DIR *)'. o Remove 'register' variables as suggested in a recent thread. No response from: -current
This commit is contained in:
parent
507950431d
commit
cf92dabe14
@ -42,14 +42,14 @@ static char sccsid[] = "@(#)closedir.c 8.1 (Berkeley) 6/10/93";
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
extern void _reclaim_telldir __P(( const DIR * ));
|
||||
extern void _reclaim_telldir __P((DIR *));
|
||||
|
||||
/*
|
||||
* close a directory.
|
||||
*/
|
||||
int
|
||||
closedir(dirp)
|
||||
register DIR *dirp;
|
||||
DIR *dirp;
|
||||
{
|
||||
int fd;
|
||||
|
||||
@ -58,7 +58,7 @@ closedir(dirp)
|
||||
dirp->dd_fd = -1;
|
||||
dirp->dd_loc = 0;
|
||||
free((void *)dirp->dd_buf);
|
||||
free((void *)dirp);
|
||||
_reclaim_telldir(dirp);
|
||||
free((void *)dirp);
|
||||
return(_close(fd));
|
||||
}
|
||||
|
@ -57,7 +57,7 @@
|
||||
.Ft int
|
||||
.Fn readdir_r "DIR *dirp" "struct dirent *entry" "struct dirent **result"
|
||||
.Ft long
|
||||
.Fn telldir "const DIR *dirp"
|
||||
.Fn telldir "DIR *dirp"
|
||||
.Ft void
|
||||
.Fn seekdir "DIR *dirp" "long loc"
|
||||
.Ft void
|
||||
|
@ -259,6 +259,8 @@ __opendir2(name, flags)
|
||||
dirp->dd_loc = 0;
|
||||
dirp->dd_fd = fd;
|
||||
dirp->dd_flags = flags;
|
||||
dirp->dd_loccnt = 0;
|
||||
LIST_INIT(&dirp->dd_locq);
|
||||
|
||||
/*
|
||||
* Set up seek point for rewinddir.
|
||||
|
@ -52,9 +52,9 @@ static char sccsid[] = "@(#)readdir.c 8.3 (Berkeley) 9/29/94";
|
||||
*/
|
||||
struct dirent *
|
||||
readdir(dirp)
|
||||
register DIR *dirp;
|
||||
DIR *dirp;
|
||||
{
|
||||
register struct dirent *dp;
|
||||
struct dirent *dp;
|
||||
|
||||
for (;;) {
|
||||
if (dirp->dd_loc >= dirp->dd_size) {
|
||||
@ -90,9 +90,10 @@ readdir_r(dirp, entry, result)
|
||||
struct dirent **result;
|
||||
{
|
||||
struct dirent *dp;
|
||||
int ret, saved_errno;
|
||||
|
||||
int saved_errno;
|
||||
#ifdef _THREAD_SAFE
|
||||
int ret;
|
||||
|
||||
if ((ret = _FD_LOCK(dirp->dd_fd, FD_READ, NULL)) != 0)
|
||||
return (ret);
|
||||
#endif
|
||||
|
@ -29,6 +29,8 @@
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
@ -53,40 +55,29 @@ static char sccsid[] = "@(#)telldir.c 8.1 (Berkeley) 6/4/93";
|
||||
* cookie returned by getdirentries and the offset within the buffer
|
||||
* associated with that return value.
|
||||
*/
|
||||
struct ddloc {
|
||||
struct ddloc *loc_next;/* next structure in list */
|
||||
struct _ddloc {
|
||||
LIST_ENTRY(_ddloc) loc_lqe; /* entry in list */
|
||||
long loc_index; /* key associated with structure */
|
||||
long loc_seek; /* magic cookie returned by getdirentries */
|
||||
long loc_loc; /* offset of entry in buffer */
|
||||
const DIR* loc_dirp; /* directory which used this entry */
|
||||
};
|
||||
|
||||
#define NDIRHASH 32 /* Num of hash lists, must be a power of 2 */
|
||||
#define LOCHASH(i) ((i)&(NDIRHASH-1))
|
||||
|
||||
static long dd_loccnt; /* Index of entry for sequential readdir's */
|
||||
static struct ddloc *dd_hash[NDIRHASH]; /* Hash list heads for ddlocs */
|
||||
|
||||
/*
|
||||
* return a pointer into a directory
|
||||
*/
|
||||
long
|
||||
telldir(dirp)
|
||||
const DIR *dirp;
|
||||
DIR *dirp;
|
||||
{
|
||||
register int index;
|
||||
register struct ddloc *lp;
|
||||
struct _ddloc *lp;
|
||||
|
||||
if ((lp = (struct ddloc *)malloc(sizeof(struct ddloc))) == NULL)
|
||||
if ((lp = (struct _ddloc *)malloc(sizeof(struct _ddloc))) == NULL)
|
||||
return (-1);
|
||||
index = dd_loccnt++;
|
||||
lp->loc_index = index;
|
||||
lp->loc_index = dirp->dd_loccnt++;
|
||||
lp->loc_seek = dirp->dd_seek;
|
||||
lp->loc_loc = dirp->dd_loc;
|
||||
lp->loc_dirp = dirp;
|
||||
lp->loc_next = dd_hash[LOCHASH(index)];
|
||||
dd_hash[LOCHASH(index)] = lp;
|
||||
return (index);
|
||||
LIST_INSERT_HEAD(&dirp->dd_locq, lp, loc_lqe);
|
||||
return (lp->loc_index);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -95,20 +86,15 @@ telldir(dirp)
|
||||
*/
|
||||
void
|
||||
_seekdir(dirp, loc)
|
||||
register DIR *dirp;
|
||||
DIR *dirp;
|
||||
long loc;
|
||||
{
|
||||
register struct ddloc *lp;
|
||||
register struct ddloc **prevlp;
|
||||
struct _ddloc *lp;
|
||||
struct dirent *dp;
|
||||
|
||||
prevlp = &dd_hash[LOCHASH(loc)];
|
||||
lp = *prevlp;
|
||||
while (lp != NULL) {
|
||||
LIST_FOREACH(lp, &dirp->dd_locq, loc_lqe) {
|
||||
if (lp->loc_index == loc)
|
||||
break;
|
||||
prevlp = &lp->loc_next;
|
||||
lp = lp->loc_next;
|
||||
}
|
||||
if (lp == NULL)
|
||||
return;
|
||||
@ -124,7 +110,7 @@ _seekdir(dirp, loc)
|
||||
}
|
||||
found:
|
||||
#ifdef SINGLEUSE
|
||||
*prevlp = lp->loc_next;
|
||||
LIST_REMOVE(lp, loc_lqe);
|
||||
free((caddr_t)lp);
|
||||
#endif
|
||||
}
|
||||
@ -134,24 +120,16 @@ found:
|
||||
*/
|
||||
void
|
||||
_reclaim_telldir(dirp)
|
||||
register const DIR *dirp;
|
||||
DIR *dirp;
|
||||
{
|
||||
register struct ddloc *lp;
|
||||
register struct ddloc **prevlp;
|
||||
int i;
|
||||
struct _ddloc *lp;
|
||||
struct _ddloc *templp;
|
||||
|
||||
for (i = 0; i < NDIRHASH; i++) {
|
||||
prevlp = &dd_hash[i];
|
||||
lp = *prevlp;
|
||||
while (lp != NULL) {
|
||||
if (lp->loc_dirp == dirp) {
|
||||
*prevlp = lp->loc_next;
|
||||
free((caddr_t)lp);
|
||||
lp = *prevlp;
|
||||
continue;
|
||||
}
|
||||
prevlp = &lp->loc_next;
|
||||
lp = lp->loc_next;
|
||||
}
|
||||
lp = LIST_FIRST(&dirp->dd_locq);
|
||||
while (lp != NULL) {
|
||||
templp = lp;
|
||||
lp = LIST_NEXT(lp, loc_lqe);
|
||||
free(templp);
|
||||
}
|
||||
LIST_INIT(&dirp->dd_locq);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user