Making {open,close,read,tell,seek}dir thread-safe.

2000-12-10 Thread Garrett Wollman

< said:

> I started a cleanup of libc to make it thread-safe.

Just as a matter of information The seekdir/telldir interface was
debated recently by the Austin Group.  The Open Group wanted to
include it as part of the XSI extension to 1003.1-200x; other people
were strongly opposed to its inclusion.  I believe the final decision
was that it seekdir/telldir would not be included, because it is
impossible to implement over certain filesystems (e.g., SGI's XFS,
which uses a radically different data structure for directories).

-GAWollman

--
Garrett A. Wollman   | O Siem / We are all family / O Siem / We're all the same
[EMAIL PROTECTED]  | O Siem / The fires of freedom 
Opinions not those of| Dance in the burning flame
MIT, LCS, CRS, or NSA| - Susan Aglukark and Chad Irschick


To Unsubscribe: send mail to [EMAIL PROTECTED]
with "unsubscribe freebsd-current" in the body of the message



Making {open,close,read,tell,seek}dir thread-safe.

2000-12-04 Thread Dan Eischen

I started a cleanup of libc to make it thread-safe.  I would
like to get rid of the hash table in libc/gen/telldir.c and
maintain telldir position information on a per-DIR basis.  A
summary of the changes are as follows:

  o Add a LIST_HEAD to DIR to contain a queue of telldir
positions.  Also add a location count (used as the magic
for telldir) to DIR.  A future change may also add a
mutex/lock.

  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 another
recent thread.

Question: Is there a reason to use a hash table in each DIR
instead of a list (for performance reasons)?

Proposed diffs below.

-- 
Dan Eischen

Index: dirent.h
===
RCS file: /opt/FreeBSD/cvs/src/include/dirent.h,v
retrieving revision 1.7
diff -u -r1.7 dirent.h
--- dirent.h1999/12/29 05:01:20 1.7
+++ dirent.h2000/12/04 20:03:49
@@ -46,12 +46,15 @@
 #ifdef _POSIX_SOURCE
 typedef void * DIR;
 #else
+#include 
 
 #defined_ino   d_fileno/* backward compatibility */
 
 /* definitions for library routines operating on directories. */
 #defineDIRBLKSIZ   1024
 
+struct ddloc;
+
 /* structure describing an open directory. */
 typedef struct _dirdesc {
int dd_fd;  /* file descriptor associated with directory */
@@ -61,7 +64,9 @@
int dd_len; /* size of data buffer */
longdd_seek;/* magic cookie returned by getdirentries */
longdd_rewind;  /* magic cookie for rewinding */
-   int dd_flags;   /* flags for readdir */
+   int dd_flags;   /* flags for readdir */\
+   longdd_loccnt;  /* current key for dd_locq entry */
+   LIST_HEAD(, ddloc) dd_locq; /* telldir position recording */
 } DIR;
 
 #definedirfd(dirp) ((dirp)->dd_fd)
@@ -89,7 +94,7 @@
 int closedir __P((DIR *));
 #ifndef _POSIX_SOURCE
 DIR *__opendir2 __P((const char *, int));
-long telldir __P((const DIR *));
+long telldir __P((DIR *));
 void seekdir __P((DIR *, long));
 int scandir __P((const char *, struct dirent ***,
 int (*)(struct dirent *), int (*)(const void *, const void *)));
Index: libc/gen/closedir.c
===
RCS file: /opt/FreeBSD/cvs/src/lib/libc/gen/closedir.c,v
retrieving revision 1.6
diff -u -r1.6 closedir.c
--- libc/gen/closedir.c 2000/01/27 23:06:14 1.6
+++ libc/gen/closedir.c 2000/12/04 20:03:30
@@ -58,7 +58,7 @@
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));
 }
Index: libc/gen/opendir.c
===
RCS file: /opt/FreeBSD/cvs/src/lib/libc/gen/opendir.c,v
retrieving revision 1.10
diff -u -r1.10 opendir.c
--- libc/gen/opendir.c  2000/01/27 23:06:18 1.10
+++ libc/gen/opendir.c  2000/12/04 20:03:13
@@ -259,6 +259,8 @@
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.
Index: libc/gen/telldir.c
===
RCS file: /opt/FreeBSD/cvs/src/lib/libc/gen/telldir.c,v
retrieving revision 1.4
diff -u -r1.4 telldir.c
--- libc/gen/telldir.c  1995/05/30 05:40:26 1.4
+++ libc/gen/telldir.c  2000/12/04 20:18:22
@@ -54,39 +54,28 @@
  * associated with that return value.
  */
 struct ddloc {
-   struct  ddloc *loc_next;/* next structure in list */
+   LIST_ENTRY(ddloc) loc_lqe; /* list entry */
longloc_index;  /* key associated with structure */
longloc_seek;   /* magic cookie returned by getdirentries */
longloc_loc;/* offset of entry in buffer */
-   const DIR* loc_dirp;/* directory which used this entry */
 };
 
-#defineNDIRHASH32  /* Num of hash lists, must be a power of 2 */
-#defineLOCHASH(i)  ((i)&(NDIRHASH-1))
-
-static longdd_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)
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)];
-   d