Closed Bug 100828 Opened 23 years ago Closed 23 years ago

nsLocalFileMac has serious problems

Categories

(Core :: XPCOM, defect)

x86
Windows 2000
defect
Not set
normal

Tracking

()

RESOLVED FIXED
mozilla0.9.8

People

(Reporter: dougt, Assigned: ccarlen)

References

Details

Attachments

(1 file, 4 obsolete files)

There are serious nsCOMPtr usage problems which cause preformance problem.  This
file needs a nice overhaul.
Blocks: 27079
It needs an overhaul for other reasons as well - too many redundant instance
vars for one. I'm hoping to get to that in 0.9.6. What are the nsCOMPtr uses
which cause perf problems?
great. over to you.  maybe a dup.

Check for cases where we assign our base class into a comptr for the fun of it.
 Also, for excessive QI's.
Assignee: dougt → ccarlen
Reworking it to address these problems:

(1) It doesn't observe the followLinks attribute - perf problem because we
always attempt to check for and resolve aliases on every ResolveAndStat(). It
will have to default to TRUE for debug builds but could help on release builds.
(2) nsILocalFileMac does not have an .idl file and the iface does not inherit
from nsILocalFile. This is a huge pain. Whenever making an nsILocalFileMac with
an NS_NewLocalFileWithFSSpec, you have to QI the stupid thing before using it as
an nsIFile.
(3) The directory iterator is really inefficient - see this mess:
http://lxr.mozilla.org/mozilla/source/xpcom/io/nsLocalFileMac.cpp#924
(4) Making better use of the cached cat info

This patch will also fix bug 28966
Status: NEW → ASSIGNED
Target Milestone: --- → mozilla0.9.6
Attached file prelim patch (obsolete) —
Now it has an actual .idl file and descends from nsILocalFile which makes using
it much better - notice lack of annoying QI's in PPEmbed.

Two things I'm not sure about:
(1) fileCreator and type are separate attributes which seems right to me.
Although, most consumers get both at the same time so it adds a line of code
here and there.
(2) There is a stack object which sets and restores the state of the followLinks
attribute. This saves a few lines of code an restores the state on early
function exit. It's defined locally in nsLocalFileMac.cpp. Should it be in the
header of nsILocalFile?
I took some before patch/after patch performance measurements. I measured the
time it took for xptiInterfaceInfoManager::BuildFileList() to enumerate the
components dir which happens twice each time at startup. I did this with a debug
build but I resolved all the aliases using drop stuff/stuffit expander to
simulate a release build. In both cases, the 1st scan of the dir takes more time
than the 2nd (probably because of OS level file mgr caching)

                  1st scan      2nd scan
before patch:
                  101 ticks     24 ticks
after patch:      3 ticks       2 ticks

That means this patch saves 120 ticks (2 seconds!) on directory enumeration on
every freakin' launch. And this was only the enumeration done by
xptiInterfaceInfoManager::BuildFileList() Caveat: in a debug build, there are
more items in the components dir because xSYM files are present but still, the
gain is pretty big.

I'm posting a new patch to nsLocalFileMac as some bugs were discovered in the
prelim patch.
Attached file updated patch to nsLocalFileMac (obsolete) —
Conrad: there are problems with the cached CInfoPBRec. Basically, it's impossible 
for us to maintain the dirty state of this cache, because calls outside of 
nsLocalFileMac can invalidate it. For example, we have code that uses the 
OpenNSPRFileDesc (or whatever) to open a file for writing outside of this code. 
Writing to the file will invalidte the cached CInfoPBRec, but there's no way we 
can know that it's changed (other than to check the mod date, which you'd do with 
PBGetCatInfo anyway).

Note also that there are some new file APIs using FSRefs which allow for getting 
file info in batches. This would be good for the enumerators.
Also xpti enumration happens only for debug builds (right jband ?) There are
other enumerations happening though on release builds. Will this patch save on
any enumeration ?
dp: yes, the xpt file enumeration happens only in debug builds, if the xpti.dat 
is unreadable, or we are doing an explicit xpcom autoregistration. If it is a 
useful benchmark, then great. But don't count on speeding up this particular 
directory enumeration to matter for release builds.
> Conrad: there are problems with the cached CInfoPBRec.

* I could probably ditch that optimization. I tested the performance again,
forcing UpdateCachedCatInfo() to always update and it did not lessen the perf
gain of enumeration. The current enumeration code is slow for several other reasons.
* Still, we could keep it and be smarter about when to invalidate it. The
methods IsFile() and IsDirectory() are called a lot. Even if something opens the
file and changes it, whether it's a file or directory is not going to change.
So, GetFileSize() and GetLastModificationDate() could always force an update of
the cached info, whereas IsFile() and IsDirectory() would not.


> Note also that there are some new file APIs using FSRefs

Those will be used when the nsLocalFile impl is factored into Classic, HFSPlus,
and OSX versions. There's already too much piecemeal OS X code in here now.

> There are other enumerations happening though on release builds. Will this
> patch save on any enumeration ?

Yes. I measured xptiInterfaceInfoManager::BuildFileList() because it does little
else other than the enumeration so measuring it is close to measuring only the
enumeration. But still, any enumeration done at startup will benefit.
Attached file updated patch to mozilla/xpcom/io (obsolete) —
The update contains improvements and fixes after running it through
http://jimbob/trigger3.html. The xpinstall test script is good because it makes
extensive use of nsILocalFile.

Another change: UpdateCachedCatInfo takes a boolean parameter with which an
update can be forced. This is used in most places - particularly when getting
the date, size, or existence. The original code was caching this info far too
long. See mHaveFileInfo. The only thing which reset this member was MakeDirty()
which reset everything which isn't nescesary. Even with updating the cached cat
info more frequently, dir enumeration is still tremendously faster. 
Conrad: can you obsolete the old patches please?
Attachment #53708 - Attachment is obsolete: true
Attachment #53708 - Attachment is patch: false
Simon, the prelim patch contains tree-wide changes for nsILocalFileMac API
changes. At this point, those will not change. The changes in attachment 54483 [details]
supercede any changes in the first patch to mozilla/xpcom/io. It's not quite
ready for review yet, though. I'm currently getting rid of the internal use of
eInitWithPath/eInitWithFSSpec. Assuming that works out, there'll be another patch.
*** Bug 104248 has been marked as a duplicate of this bug. ***
I have a new patch coming up which does a few things:

(1) Gets rid of eInitializedWithPath, eInitializedWithFSSpec distinction. When
initialized with a full patch, the existant portion of the path is resolved into
a spec and the rest, which doesn't exist, is kept in mAppendedPath. When
initializing with a full path, at least the volume must exist or else it's an error.
(2) The object used to contain 3 FSSpecs and 3 path member vars - not very
concise. The object now contains 2 specs and only one path. The reason for 2
specs is so that, is the leaf is an alias, we can toggle back and forth between
resolving the alias or not.
(3) When Append() is called, the current leaf is resolved if it is an alias.
Before this wasn't done and alises were only resolved at the leaf when the patch
was finally built up. If one of the appended nodes was an alias, it would fail.
The problem, to a user, was that you could not make an alias of your cache
directory (or much of anything else) Now you can.

Attached patch new tree-wide patch (obsolete) — Splinter Review
Attachment #53312 - Attachment is obsolete: true
Attachment #53312 - Attachment is patch: false
Attachment #54483 - Attachment is obsolete: true
Attachment #54483 - Attachment is patch: false
This one is ready for review. Another thing I would like to do, since so much of
this is being rewritten, is to get rid of the tabs that have always been present
thoughout this file. As you can see, it makes diffs ugly if the new code uses
spaces. I could do one of two things - reviewers take your choice:
1. review as-is and, before checking in, I'll detab it with BBEdit.
2. detab it now and post a new diff made with -w
Do this one:
1. review as-is and, before checking in, I'll detab it with BBEdit.
Alright, then review away. I'll detab it before checking in.
*** Bug 28966 has been marked as a duplicate of this bug. ***
Comments:
+    attribute OSType fileType;
+    attribute OSType creator;

Use 'fileCreator' for consistency?

+    char        mAutoBuffer[512];
+    char        *mAllocatedBuffer;
+    char        *mNewString;

We really need a class that does this stack/buffer thing transparently. It's used 
in so many places.

+        return nsCRT::strtok(mAllocatedBuffer ? mAllocatedBuffer : mAutoBuffer, 
":", &mNewString);

Why not store a pointer than can point to either the allocated buffer, or the 
stack buffer, and avoid this if/else test all the time? You'd just have to set it 
up in the ctor.

The rest looks OK, but this patch needs some thorough testing, since it's so 
core. I'd even suggest testing an installer, to make sure that installation 
didn't break.

sr=sfraser
> Use 'fileCreator' for consistency?

OK

> Why not store a pointer than can point to either the allocated buffer

OK - It was to save an instance var in favor of the low expense of the if/else.
Now, I think what you suggest is better.

As far as testing with the installer, I did test successfully with
http://jimbob/trigger3.html which hits every obscure case.

I still need an r= on this. Patrick or Doug? Since the changes mentioned above
are slight, please review the current patch.


Attachment #54920 - Flags: superreview+
CC'ing rjc for review. This has had sr= for a while. Now if I can get an r=.
o  attribute OSType creator;

I second the "fileCreator" instead of "creator" change.  I assume that the
method name (not just the variable name) was also changed ... GetFileCreator()
instead of GetCreator()

o  *outIsWritable = !(mCachedCatInfo.hFileInfo.ioFlAttrib & 0x01);

Nit:  instead of 0x01, suggest using the correct mask from <Files.h>
      which looks to be kioFlAttribLockedMask


Also, I've always been quite annoyed by our alias resolution handling on Mac. 
SO... I'd like to see the following test done.  :)

1)  mount a remote Appletalk volume (call it _VOL_ for short)
2)  make an alias to that remote volume (call it _AL_ for short)
3)  unmount the remote volume
4)  place the alias in some directory (call it _DIR_ for short) on the local
hard disk
5)  with Mozilla, type in the appropritate file:/// URL to view the contents of
directory _DIR_

If Mozilla seems to go to sleep for up to two minutes (as it incorrectly tries
to mount _VOL_) or anything action other than merely listing the alias _AL_
itself, then something is still wrong with alias resolution.

With the above changes, and IFF Mozilla passes the above test correctly, r=rjc
I'll do the first two points.

As far as this:
1)  mount a remote Appletalk volume (call it _VOL_ for short)
2)  make an alias to that remote volume (call it _AL_ for short)
3)  unmount the remote volume
4)  place the alias in some directory (call it _DIR_ for short) on the local
hard disk
5)  with Mozilla, type in the appropritate file:/// URL to view the contents of
directory _DIR_

 It currently defaults to resolving aliases. It has to for most consumers to
work. One thing this patch does is to make nsLocalFile obey the followLinks
attribute. With this patch, you could at least set the follow links attribute to
FALSE on each entry you got back in the enumeration and it would actually do
something.
 I think what would be more convenient and offer better control would be to add
a param to GetEntries() specifying whether or not to resolve aliases on each
entry that's returned. You  may want to resolve the alias to the dir being
enumerated but not resolve the children. That's another bug though.

 
Robert, I will try putting a call to SetFollowLinks(PR_FALSE) in the directory
listing generator as soon as it gets back an entry and make sure it does the
right thing.
Conrad:  SetFollowLinks(PR_FALSE) is already in the RDF file system datasource
which is what actually ends up handling file:/// URL display.  :)  So the test
should be a good one to do.
At this point, right:
http://lxr.mozilla.org/mozilla/source/rdf/datasource/src/nsFileSystemDataSource.cpp#1215
That's not quite going to do it. It should be done also on line 1233. Say in
this case, aDirLocal was an alias to a directory. You may want to resolve that.
But, what you don't want resolved are its entries. The additional call on line
1233 will do that.
Agreed on line # 1233 due to the IsHidden() call; however I don't know that I
agree that aliases to directories should ever be resolved. Sticky issue... if I
wanted to delete the alias to a directory (assuming that we actually had that
functionality, that is), I wouldn't want the real directory to be blown away. 
Anyway, different issue for a different time/bug.  :)
Mass move to 0.9.7
Target Milestone: mozilla0.9.6 → mozilla0.9.7
Better to get something like this into the beginning of 0.9.8 than end of 0.9.7
Target Milestone: mozilla0.9.7 → mozilla0.9.8
Attached patch updated patchSplinter Review
Update to the last patch - no significant changes, just updated for changes in
the tree. nsLocalFileMac.cpp was de-tabbed as this is the final which will be
checked in.
Attachment #54920 - Attachment is obsolete: true
Checked in. nsLocalFileMac was de-tabbed so pretty much everything is different.
After the tree closed, I remembered that the old nsILocalFileMac.h needs to be
removed. I'll leave this open until I do that later today.
The handmade nsILocalFileMac.h is removed so marking fixed.
Status: ASSIGNED → RESOLVED
Closed: 23 years ago
Resolution: --- → FIXED
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: