readdir() threadsafe?

This forum is for general developer support questions.
chris
Posts: 564
Joined: Sat Jun 18, 2011 12:05 pm
Contact:

readdir() threadsafe?

Post by chris »

Is the readdir() function in newlib.library threadsafe?
User avatar
salass00
AmigaOS Core Developer
AmigaOS Core Developer
Posts: 534
Joined: Sat Jun 18, 2011 4:12 pm
Location: Finland
Contact:

Re: readdir() threadsafe?

Post by salass00 »

chris wrote:Is the readdir() function in newlib.library threadsafe?
If you need thread safety you should use readdir_r() instead (or at least never call readdir() from more than one task at once).

edit: couldn't find readdir_r() in newlib or clib2 includes so I guess it doesn't exist. I could swear I had used it before but I was probably confusing it with strtok()/strtok_r(). I guess you'll have to either hope that readdir() is implemented in a threadsafe manner somehow or add some mutex locking around your directory scanning code.

edit 2: looking at the definition of DIR type (used by readdir()) I don't really see why it wouldn't be threadsafe (assuming that you don't access the same directory handle from more than one task of course):

Code: Select all

struct __dir
{
   unsigned long numentries;
   unsigned long allocatedentries;
   unsigned long currententry;
   struct dirent *entries;
};
typedef struct __dir DIR;
chris
Posts: 564
Joined: Sat Jun 18, 2011 12:05 pm
Contact:

Re: readdir() threadsafe?

Post by chris »

salass00 wrote:
chris wrote:Is the readdir() function in newlib.library threadsafe?
If you need thread safety you should use readdir_r() instead (or at least never call readdir() from more than one task at once).

edit: couldn't find readdir_r() in newlib or clib2 includes so I guess it doesn't exist. I could swear I had used it before but I was probably confusing it with strtok()/strtok_r(). I guess you'll have to either hope that readdir() is implemented in a threadsafe manner somehow or add some mutex locking around your directory scanning code.

edit 2: looking at the definition of DIR type (used by readdir()) I don't really see why it wouldn't be threadsafe (assuming that you don't access the same directory handle from more than one task of course):

Code: Select all

struct __dir
{
   unsigned long numentries;
   unsigned long allocatedentries;
   unsigned long currententry;
   struct dirent *entries;
};
typedef struct __dir DIR;
Looking at that, as long as a simultaneous request for the same directory gets a different DIR pointer, I agree it should be fine.

Thanks.
xenic
Posts: 1185
Joined: Sun Jun 19, 2011 1:06 am

Re: readdir() threadsafe?

Post by xenic »

@chris
It seems that newlib opendir() doesn't lock the directory so I wonder what happens when you opendir() a directory that gets deleted by another Process before you call readdir()?
AmigaOne X1000 with 2GB memory - OS4.1 FE
chris
Posts: 564
Joined: Sat Jun 18, 2011 12:05 pm
Contact:

Re: readdir() threadsafe?

Post by chris »

xenic wrote:@chris
It seems that newlib opendir() doesn't lock the directory so I wonder what happens when you opendir() a directory that gets deleted by another Process before you call readdir()?
Hmm, good question. I guess it would return no entries. I would also expect readdir_r() to have the same problem.
xenic
Posts: 1185
Joined: Sun Jun 19, 2011 1:06 am

Re: readdir() threadsafe?

Post by xenic »

@chris
Hmm, good question. I guess it would return no entries. I would also expect readdir_r() to have the same problem.
I wrote a little test program for opendir() and the directory is locked and can't be deleted if the program is compiled with clib2. Since the underlying AmigaDOS functions Examine() & Exall() require a lock for input args and the new function ExamineDir() gets a lock on the directory when the context is created by ObtainDirContext() (according to the autodocs). If the AmigaDOS directory functions lock the directory so it can't disappear, it seems sort of sloppy that newlib doesn't do the same.
AmigaOne X1000 with 2GB memory - OS4.1 FE
chris
Posts: 564
Joined: Sat Jun 18, 2011 12:05 pm
Contact:

Re: readdir() threadsafe?

Post by chris »

xenic wrote:@chris
Hmm, good question. I guess it would return no entries. I would also expect readdir_r() to have the same problem.
I wrote a little test program for opendir() and the directory is locked and can't be deleted if the program is compiled with clib2. Since the underlying AmigaDOS functions Examine() & Exall() require a lock for input args and the new function ExamineDir() gets a lock on the directory when the context is created by ObtainDirContext() (according to the autodocs). If the AmigaDOS directory functions lock the directory so it can't disappear, it seems sort of sloppy that newlib doesn't do the same.
That sounds like a bug in newlib.library.
User avatar
tonyw
AmigaOS Core Developer
AmigaOS Core Developer
Posts: 1483
Joined: Wed Mar 09, 2011 1:36 pm
Location: Sydney, Australia

Re: readdir() threadsafe?

Post by tonyw »

DOS locks the directory as soon as anyone calls IDOS->ObtainDirContext() (that's what the Lock is for). There shouldn't be any contention between competing clients, no matter whether they come through a C lib or directly by calling IDOS->ExamineObject().

Newlib and clib don't have to lock anything, it's all done at a lower level.
cheers
tony
xenic
Posts: 1185
Joined: Sun Jun 19, 2011 1:06 am

Re: readdir() threadsafe?

Post by xenic »

tonyw wrote:DOS locks the directory as soon as anyone calls IDOS->ObtainDirContext() (that's what the Lock is for). There shouldn't be any contention between competing clients, no matter whether they come through a C lib or directly by calling IDOS->ExamineObject().

Newlib and clib don't have to lock anything, it's all done at a lower level.
Did you read my post? I wrote a small program which calls opendir() on a directory and then waits for a Ctrl-C to closedir() and exit. While opendir() is still in effect (and supposedly locked as you state) I can delete the directory from another shell. If I compile the test program with clib2 then the directory can't be deleted from another shell while opendir() is in effect for that directlry. I would call being able to delete a directory while newlib opendir() is in effect a contention between 2 applications. I checked the sources for clib2 and it is in fact locking the directory when opendir() is performed; probably because it is using old OS3 AmigaDOS commands for directory and file access. If newlib opendir() is using new OS4 functions and calling IDOS->ObtainDirContext() (which supposedly locks the directory) then I shouldn't be able to delete the directory from another application until closedir() is called.
AmigaOne X1000 with 2GB memory - OS4.1 FE
xenic
Posts: 1185
Joined: Sun Jun 19, 2011 1:06 am

Re: readdir() threadsafe?

Post by xenic »

chris wrote:That sounds like a bug in newlib.library.
It would be interresting to see what happens if the directory is deleted after opendir() is called but before the first readdir().
AmigaOne X1000 with 2GB memory - OS4.1 FE
Post Reply