Bug 1877522 - [3/3] Enforce linearity (exclusivity) of ThenCommand r=xpcom-reviewers,barret

ThenCommands are effectively linear: they can only be used once. Make
this restriction more difficult to accidentally violate by applying
MOZ_TEMPORARY_CLASS.

Fix the one line of code that this breaks. Castigate its author (who is
also the author of this commit) accordingly.

No functional changes.

Differential Revision: https://phabricator.services.mozilla.com/D200061
This commit is contained in:
Ray Kraesig 2024-03-20 01:30:14 +00:00
parent cd10421cfb
commit 712b2391b0
2 changed files with 14 additions and 9 deletions

View File

@ -840,7 +840,7 @@ nsresult nsFilePicker::Open(nsIFilePickerShownCallback* aCallback) {
auto promise = mMode == modeGetFolder ? ShowFolderPicker(initialDir)
: ShowFilePicker(initialDir);
auto p2 = promise->Then(
promise->Then(
mozilla::GetMainThreadSerialEventTarget(), __PRETTY_FUNCTION__,
[self = RefPtr(this),
callback = RefPtr(aCallback)](bool selectionMade) -> void {

View File

@ -10,6 +10,7 @@
#include <type_traits>
#include <utility>
#include "mozilla/Attributes.h"
#include "mozilla/ErrorNames.h"
#include "mozilla/Logging.h"
#include "mozilla/Maybe.h"
@ -1049,17 +1050,21 @@ class MozPromise : public MozPromiseBase {
protected:
/*
* A command object to store all information needed to make a request to
* the promise. This allows us to delay the request until further use is
* known (whether it is ->Then() again for more promise chaining or ->Track()
* to terminate chaining and issue the request).
* A command object to store all information needed to make a request to the
* promise. This allows us to delay the request until further use is known
* (whether it is ->Then() again for more promise chaining or ->Track() to
* terminate chaining and issue the request).
*
* This allows a unified syntax for promise chaining and disconnection
* and feels more like its JS counterpart.
* This allows a unified syntax for promise chaining and disconnection, and
* feels more like its JS counterpart.
*
* Note that a ThenCommand is always exclusive, even if its source or result
* promises are not. To attach multiple continuations, explicitly convert it
* to a promise first.
*/
template <typename ThenValueType>
class ThenCommand {
// Allow Promise1::ThenCommand to access the private constructor,
class MOZ_TEMPORARY_CLASS ThenCommand {
// Allow Promise1::ThenCommand to access the private constructor
// Promise2::ThenCommand(ThenCommand&&).
template <typename, typename, bool>
friend class MozPromise;