Chris Jones [:cjones] [:warhammer] <
jones....@gmail.com> has canceled Dave
Hylands [:dhylands] <
dhyl...@mozilla.com>'s request for superreview:
------- Additional Comments from Chris Jones [:cjones] [:warhammer]
<
jones....@gmail.com>
>diff --git a/ipc/volumemanager/Volume.cpp b/ipc/volumemanager/Volume.cpp
Sorry Dave, hate to nitpick code locations more, this code belongs in
dom/system/gonk/ for now. The ipc/ directory is code that implements
IPC (and related things). This code /uses/ IPC, in service of DOM
interfaces. (For now, just DOM settings.) It's also gonk specific.
A general point about RefPtr: we use this convention to pass
refcounted objects around
class Object : Refcounted<Object> { ... };
void Foo(Object* aO) { ... }
RefPtr<Object> p(new Object(...));
Foo(p);
That is, the caller of |Foo()| "loans" Foo() its reference, and Foo()
can further loan that reference to callees. The reason we do this is
to eliminate a lot of extraneous ref/unref'ing of arguments.
Similarly, we have a helper TemporaryRef<T> to "forward" references to
refcounted objects returned from functions. So if you need to return
a refcounted object, you should do
TemporaryRef<Object> Bar() { ... }
RefPtr<Object> p = Bar();
This is again used to save unnecessary ref/unref.
Most of the time this usage doesn't matter perf-wise, but it's a good
habit to be in. There are places in the code where it does matter.
One more general nit: our coding style uses a stupid
Hungarian-notation-lite style to annotate function parameters, like so
void Function(const Foo& aParameter)
note the "a" prefix, for "argument". This is silly and worthless but
it's best to stay consistent with the rest of the code around DOM.
I won't call out those things specifically below.
>diff --git a/ipc/volumemanager/Volume.cpp b/ipc/volumemanager/Volume.cpp
>+void
>+Volume::CommandDone(const VolumeCommand &cmd, const VolumeResponse &response)
>+{
>+ Volume::Callback *cb = mCallback;
>+ mCallback = NULL;
>+
>+ cb->CommandDone(this, cmd, response);
This is invalid usage of mCallback ... that might be the last
reference. Instead, you want to do
RefPtr<Callback> cb = mCallback;
mCallback = NULL;
//...
It might be the case here that you can guarantee there's always
another reference, but that's a distributed invariant that's hard to
maintain. If the invariant isn't maintained, we have a security
vulnerability here. Not worth it ;).
>diff --git a/ipc/volumemanager/Volume.h b/ipc/volumemanager/Volume.h
>+namespace mozilla {
>+namespace ipc {
When this moves to dom/system/gonk, let's put it in namespace
mozilla::system. And the other classes here.
>+class Volume; // Forward declarations
Drop this comment.
>+class Volume : public RefCounted<Volume>
>+{
>+ void SetMountPoint(const nsCSubstring &mountPoint);
This method needs an explanatory comment about the mount point
parameter. Use |const nsACString&| for the type.
>+ void StartMount(RefPtr<Callback> cb);
>+ void StartUnmount(RefPtr<Callback> cb);
>+ void StartShare(RefPtr<Callback> cb);
>+ void StartUnshare(RefPtr<Callback> cb);
The state machine here needs to be documented, the fact that it's only
legal to have one or zero operations pending.
>diff --git a/ipc/volumemanager/VolumeCommand.h
b/ipc/volumemanager/VolumeCommand.h
>+class VolumeCommand : public RefCounted<VolumeCommand>
>+{
>+ VolumeCommand(const nsACString &cmd)
>+ : mCmd(cmd),
>+ mBytesConsumed(0)
>+ {
>+ // Add a null character. We want this to be included in the length since
>+ // vold uses it to determine the end of the command.
You can drop this duplicated comment and the one below. Or, factor
out this logic into a separate helper and put the comment there.
>+ const char *CmdStr() const { return mCmd.get(); }
>+ const char *Data() const { return mCmd.Data() +
mBytesConsumed; }
>+ void ConsumeBytes( size_t numBytes ) { mBytesConsumed += numBytes; }
Nit: |ConsumeBytes(size_t aNumBytes)|, no margin in parens.
Non-nit: there's nothing ensuring here that mBytesConsumed points
within mCmd. If a caller accidentally does Consume(1e10), then we
have a security vulnerability in Data(). Let's check this always (not
just debug-only).
>diff --git a/ipc/volumemanager/VolumeManager.cpp
b/ipc/volumemanager/VolumeManager.cpp
>+//static
>+RefPtr<Volume>
>+VolumeManager::FindVolumeByName(const nsCSubstring &name)
nsACString&
>+{
>+ if (!sVolumeManager) {
>+ return NULL;
>+ }
>+ for (VolumeArray::iterator volIter = sVolumeManager->mVolumeArray.begin();
CString has operator== so should be able to use std::find() here.
>diff --git a/ipc/volumemanager/VolumeManager.h
b/ipc/volumemanager/VolumeManager.h
>+class VolumeManager : public MessageLoopForIO::Watcher,
>+ public RefCounted<VolumeManager>
>+{
>+public:
>+
>+ typedef std::vector<RefPtr<Volume>> VolumeArray;
Need "> >" or this won't compile (C++ lexing ambiguity).
Nice work! I like this patch :).
I'd like to see the next version with these comments addressed.