Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
C
capnproto
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
submodule
capnproto
Commits
793b2af2
Commit
793b2af2
authored
Nov 30, 2013
by
Kenton Varda
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Tweak scheduling.
parent
222c3b20
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
95 additions
and
66 deletions
+95
-66
async-inl.h
c++/src/kj/async-inl.h
+13
-14
async-test.c++
c++/src/kj/async-test.c++
+35
-13
async.c++
c++/src/kj/async.c++
+42
-38
async.h
c++/src/kj/async.h
+5
-1
No files found.
c++/src/kj/async-inl.h
View file @
793b2af2
...
@@ -133,8 +133,8 @@ class PromiseNode {
...
@@ -133,8 +133,8 @@ class PromiseNode {
// internal implementation details.
// internal implementation details.
public
:
public
:
virtual
bool
onReady
(
Event
&
event
)
noexcept
=
0
;
virtual
void
onReady
(
Event
&
event
)
noexcept
=
0
;
//
Returns true if already ready, otherwise a
rms the given event when ready.
//
A
rms the given event when ready.
virtual
void
get
(
ExceptionOrValue
&
output
)
noexcept
=
0
;
virtual
void
get
(
ExceptionOrValue
&
output
)
noexcept
=
0
;
// Get the result. `output` points to an ExceptionOr<T> into which the result will be written.
// Get the result. `output` points to an ExceptionOr<T> into which the result will be written.
...
@@ -150,7 +150,7 @@ protected:
...
@@ -150,7 +150,7 @@ protected:
// Helper class for implementing onReady().
// Helper class for implementing onReady().
public
:
public
:
bool
init
(
Event
&
newEvent
);
void
init
(
Event
&
newEvent
);
// Returns true if arm() was already called.
// Returns true if arm() was already called.
void
arm
();
void
arm
();
...
@@ -166,7 +166,7 @@ protected:
...
@@ -166,7 +166,7 @@ protected:
class
ImmediatePromiseNodeBase
:
public
PromiseNode
{
class
ImmediatePromiseNodeBase
:
public
PromiseNode
{
public
:
public
:
bool
onReady
(
Event
&
event
)
noexcept
override
;
void
onReady
(
Event
&
event
)
noexcept
override
;
};
};
template
<
typename
T
>
template
<
typename
T
>
...
@@ -200,7 +200,7 @@ class AttachmentPromiseNodeBase: public PromiseNode {
...
@@ -200,7 +200,7 @@ class AttachmentPromiseNodeBase: public PromiseNode {
public
:
public
:
AttachmentPromiseNodeBase
(
Own
<
PromiseNode
>&&
dependency
);
AttachmentPromiseNodeBase
(
Own
<
PromiseNode
>&&
dependency
);
bool
onReady
(
Event
&
event
)
noexcept
override
;
void
onReady
(
Event
&
event
)
noexcept
override
;
void
get
(
ExceptionOrValue
&
output
)
noexcept
override
;
void
get
(
ExceptionOrValue
&
output
)
noexcept
override
;
PromiseNode
*
getInnerForTrace
()
override
;
PromiseNode
*
getInnerForTrace
()
override
;
...
@@ -239,7 +239,7 @@ class TransformPromiseNodeBase: public PromiseNode {
...
@@ -239,7 +239,7 @@ class TransformPromiseNodeBase: public PromiseNode {
public
:
public
:
TransformPromiseNodeBase
(
Own
<
PromiseNode
>&&
dependency
);
TransformPromiseNodeBase
(
Own
<
PromiseNode
>&&
dependency
);
bool
onReady
(
Event
&
event
)
noexcept
override
;
void
onReady
(
Event
&
event
)
noexcept
override
;
void
get
(
ExceptionOrValue
&
output
)
noexcept
override
;
void
get
(
ExceptionOrValue
&
output
)
noexcept
override
;
PromiseNode
*
getInnerForTrace
()
override
;
PromiseNode
*
getInnerForTrace
()
override
;
...
@@ -309,7 +309,7 @@ public:
...
@@ -309,7 +309,7 @@ public:
// Called by the hub to indicate that it is ready.
// Called by the hub to indicate that it is ready.
// implements PromiseNode ------------------------------------------
// implements PromiseNode ------------------------------------------
bool
onReady
(
Event
&
event
)
noexcept
override
;
void
onReady
(
Event
&
event
)
noexcept
override
;
PromiseNode
*
getInnerForTrace
()
override
;
PromiseNode
*
getInnerForTrace
()
override
;
protected
:
protected
:
...
@@ -401,7 +401,7 @@ public:
...
@@ -401,7 +401,7 @@ public:
explicit
ChainPromiseNode
(
Own
<
PromiseNode
>
inner
);
explicit
ChainPromiseNode
(
Own
<
PromiseNode
>
inner
);
~
ChainPromiseNode
()
noexcept
(
false
);
~
ChainPromiseNode
()
noexcept
(
false
);
bool
onReady
(
Event
&
event
)
noexcept
override
;
void
onReady
(
Event
&
event
)
noexcept
override
;
void
get
(
ExceptionOrValue
&
output
)
noexcept
override
;
void
get
(
ExceptionOrValue
&
output
)
noexcept
override
;
PromiseNode
*
getInnerForTrace
()
override
;
PromiseNode
*
getInnerForTrace
()
override
;
...
@@ -439,7 +439,7 @@ public:
...
@@ -439,7 +439,7 @@ public:
ExclusiveJoinPromiseNode
(
Own
<
PromiseNode
>
left
,
Own
<
PromiseNode
>
right
);
ExclusiveJoinPromiseNode
(
Own
<
PromiseNode
>
left
,
Own
<
PromiseNode
>
right
);
~
ExclusiveJoinPromiseNode
()
noexcept
(
false
);
~
ExclusiveJoinPromiseNode
()
noexcept
(
false
);
bool
onReady
(
Event
&
event
)
noexcept
override
;
void
onReady
(
Event
&
event
)
noexcept
override
;
void
get
(
ExceptionOrValue
&
output
)
noexcept
override
;
void
get
(
ExceptionOrValue
&
output
)
noexcept
override
;
PromiseNode
*
getInnerForTrace
()
override
;
PromiseNode
*
getInnerForTrace
()
override
;
...
@@ -474,7 +474,7 @@ class EagerPromiseNodeBase: public PromiseNode, protected Event {
...
@@ -474,7 +474,7 @@ class EagerPromiseNodeBase: public PromiseNode, protected Event {
public
:
public
:
EagerPromiseNodeBase
(
Own
<
PromiseNode
>&&
dependency
,
ExceptionOrValue
&
resultRef
);
EagerPromiseNodeBase
(
Own
<
PromiseNode
>&&
dependency
,
ExceptionOrValue
&
resultRef
);
bool
onReady
(
Event
&
event
)
noexcept
override
;
void
onReady
(
Event
&
event
)
noexcept
override
;
PromiseNode
*
getInnerForTrace
()
override
;
PromiseNode
*
getInnerForTrace
()
override
;
private
:
private
:
...
@@ -511,7 +511,7 @@ Own<PromiseNode> spark(Own<PromiseNode>&& node) {
...
@@ -511,7 +511,7 @@ Own<PromiseNode> spark(Own<PromiseNode>&& node) {
class
AdapterPromiseNodeBase
:
public
PromiseNode
{
class
AdapterPromiseNodeBase
:
public
PromiseNode
{
public
:
public
:
bool
onReady
(
Event
&
event
)
noexcept
override
;
void
onReady
(
Event
&
event
)
noexcept
override
;
protected
:
protected
:
inline
void
setReady
()
{
inline
void
setReady
()
{
...
@@ -588,10 +588,9 @@ T EventLoop::wait(Promise<T>&& promise) {
...
@@ -588,10 +588,9 @@ T EventLoop::wait(Promise<T>&& promise) {
template
<
typename
Func
>
template
<
typename
Func
>
PromiseForResult
<
Func
,
void
>
EventLoop
::
evalLater
(
Func
&&
func
)
{
PromiseForResult
<
Func
,
void
>
EventLoop
::
evalLater
(
Func
&&
func
)
{
// Invoke thenImpl() on yield().
Always spark the result.
// Invoke thenImpl() on yield().
return
PromiseForResult
<
Func
,
void
>
(
false
,
return
PromiseForResult
<
Func
,
void
>
(
false
,
_
::
spark
<
_
::
FixVoid
<
_
::
JoinPromises
<
_
::
ReturnType
<
Func
,
void
>>>>
(
thenImpl
(
yield
(),
kj
::
fwd
<
Func
>
(
func
),
_
::
PropagateException
()));
thenImpl
(
yield
(),
kj
::
fwd
<
Func
>
(
func
),
_
::
PropagateException
())));
}
}
template
<
typename
T
,
typename
Func
,
typename
ErrorFunc
>
template
<
typename
T
,
typename
Func
,
typename
ErrorFunc
>
...
...
c++/src/kj/async-test.c++
View file @
793b2af2
...
@@ -240,24 +240,43 @@ TEST(Async, Ordering) {
...
@@ -240,24 +240,43 @@ TEST(Async, Ordering) {
promises
[
1
]
=
evalLater
([
&
]()
{
promises
[
1
]
=
evalLater
([
&
]()
{
EXPECT_EQ
(
0
,
counter
++
);
EXPECT_EQ
(
0
,
counter
++
);
promises
[
2
]
=
Promise
<
void
>
(
READY_NOW
).
then
([
&
]()
{
EXPECT_EQ
(
1
,
counter
++
);
{
return
Promise
<
void
>
(
READY_NOW
);
// Force proactive evaluation by faking a chain.
// Use a promise and fulfiller so that we can fulfill the promise after waiting on it in
});
// order to induce depth-first scheduling.
promises
[
3
]
=
evalLater
([
&
]()
{
auto
paf
=
kj
::
newPromiseAndFulfiller
<
void
>
();
EXPECT_EQ
(
4
,
counter
++
);
promises
[
2
]
=
paf
.
promise
.
then
([
&
]()
{
return
Promise
<
void
>
(
READY_NOW
).
then
([
&
]()
{
EXPECT_EQ
(
1
,
counter
++
);
EXPECT_EQ
(
5
,
counter
++
);
});
});
promises
[
2
].
eagerlyEvaluate
();
paf
.
fulfiller
->
fulfill
();
}
// .then() is scheduled breadth-first if the promise has already resolved, but depth-first
// if the promise resolves later.
promises
[
3
]
=
Promise
<
void
>
(
READY_NOW
).
then
([
&
]()
{
EXPECT_EQ
(
4
,
counter
++
);
}).
then
([
&
]()
{
EXPECT_EQ
(
5
,
counter
++
);
});
});
promises
[
4
]
=
Promise
<
void
>
(
READY_NOW
).
then
([
&
]()
{
promises
[
3
].
eagerlyEvaluate
();
EXPECT_EQ
(
2
,
counter
++
);
return
Promise
<
void
>
(
READY_NOW
);
// Force proactive evaluation by faking a chain.
{
});
auto
paf
=
kj
::
newPromiseAndFulfiller
<
void
>
();
promises
[
4
]
=
paf
.
promise
.
then
([
&
]()
{
EXPECT_EQ
(
2
,
counter
++
);
});
promises
[
4
].
eagerlyEvaluate
();
paf
.
fulfiller
->
fulfill
();
}
// evalLater() is like READY_NOW.then().
promises
[
5
]
=
evalLater
([
&
]()
{
promises
[
5
]
=
evalLater
([
&
]()
{
EXPECT_EQ
(
6
,
counter
++
);
EXPECT_EQ
(
6
,
counter
++
);
});
});
promises
[
5
].
eagerlyEvaluate
();
});
});
promises
[
1
].
eagerlyEvaluate
();
promises
[
0
]
=
evalLater
([
&
]()
{
promises
[
0
]
=
evalLater
([
&
]()
{
EXPECT_EQ
(
3
,
counter
++
);
EXPECT_EQ
(
3
,
counter
++
);
...
@@ -266,6 +285,7 @@ TEST(Async, Ordering) {
...
@@ -266,6 +285,7 @@ TEST(Async, Ordering) {
// point.)
// point.)
return
Promise
<
void
>
(
READY_NOW
);
return
Promise
<
void
>
(
READY_NOW
);
});
});
promises
[
0
].
eagerlyEvaluate
();
for
(
auto
i
:
indices
(
promises
))
{
for
(
auto
i
:
indices
(
promises
))
{
kj
::
mv
(
promises
[
i
]).
wait
();
kj
::
mv
(
promises
[
i
]).
wait
();
...
@@ -367,8 +387,10 @@ TEST(Async, ExclusiveJoin) {
...
@@ -367,8 +387,10 @@ TEST(Async, ExclusiveJoin) {
{
{
SimpleEventLoop
loop
;
SimpleEventLoop
loop
;
auto
right
=
evalLater
([
&
]()
{
return
456
;
});
auto
left
=
evalLater
([
&
]()
{
return
123
;
});
auto
left
=
evalLater
([
&
]()
{
return
123
;
});
auto
right
=
evalLater
([
&
]()
{
return
456
;
});
right
.
eagerlyEvaluate
();
left
.
exclusiveJoin
(
kj
::
mv
(
right
));
left
.
exclusiveJoin
(
kj
::
mv
(
right
));
...
...
c++/src/kj/async.c++
View file @
793b2af2
...
@@ -58,19 +58,18 @@ public:
...
@@ -58,19 +58,18 @@ public:
class
YieldPromiseNode
final
:
public
_
::
PromiseNode
{
class
YieldPromiseNode
final
:
public
_
::
PromiseNode
{
public
:
public
:
bool
onReady
(
_
::
Event
&
event
)
noexcept
override
{
void
onReady
(
_
::
Event
&
event
)
noexcept
override
{
event
.
armBreadthFirst
();
event
.
armBreadthFirst
();
return
false
;
}
}
void
get
(
_
::
ExceptionOrValue
&
output
)
noexcept
override
{
void
get
(
_
::
ExceptionOrValue
&
output
)
noexcept
override
{
output
.
as
<
_
::
Void
>
()
.
value
=
_
::
Void
();
output
.
as
<
_
::
Void
>
()
=
_
::
Void
();
}
}
};
};
class
NeverReadyPromiseNode
final
:
public
_
::
PromiseNode
{
class
NeverReadyPromiseNode
final
:
public
_
::
PromiseNode
{
public
:
public
:
bool
onReady
(
_
::
Event
&
event
)
noexcept
override
{
void
onReady
(
_
::
Event
&
event
)
noexcept
override
{
return
false
;
// ignore
}
}
void
get
(
_
::
ExceptionOrValue
&
output
)
noexcept
override
{
void
get
(
_
::
ExceptionOrValue
&
output
)
noexcept
override
{
KJ_FAIL_REQUIRE
(
"Not ready."
);
KJ_FAIL_REQUIRE
(
"Not ready."
);
...
@@ -100,9 +99,7 @@ public:
...
@@ -100,9 +99,7 @@ public:
public
:
public
:
Task
(
TaskSetImpl
&
taskSet
,
Own
<
_
::
PromiseNode
>&&
nodeParam
)
Task
(
TaskSetImpl
&
taskSet
,
Own
<
_
::
PromiseNode
>&&
nodeParam
)
:
taskSet
(
taskSet
),
node
(
kj
::
mv
(
nodeParam
))
{
:
taskSet
(
taskSet
),
node
(
kj
::
mv
(
nodeParam
))
{
if
(
node
->
onReady
(
*
this
))
{
node
->
onReady
(
*
this
);
armDepthFirst
();
}
}
}
protected
:
protected
:
...
@@ -232,7 +229,7 @@ void EventLoop::waitImpl(Own<_::PromiseNode>&& node, _::ExceptionOrValue& result
...
@@ -232,7 +229,7 @@ void EventLoop::waitImpl(Own<_::PromiseNode>&& node, _::ExceptionOrValue& result
KJ_REQUIRE
(
!
running
,
"wait() is not allowed from within event callbacks."
);
KJ_REQUIRE
(
!
running
,
"wait() is not allowed from within event callbacks."
);
BoolEvent
doneEvent
;
BoolEvent
doneEvent
;
doneEvent
.
fired
=
node
->
onReady
(
doneEvent
);
node
->
onReady
(
doneEvent
);
running
=
true
;
running
=
true
;
KJ_DEFER
(
running
=
false
);
KJ_DEFER
(
running
=
false
);
...
@@ -251,6 +248,10 @@ void EventLoop::waitImpl(Own<_::PromiseNode>&& node, _::ExceptionOrValue& result
...
@@ -251,6 +248,10 @@ void EventLoop::waitImpl(Own<_::PromiseNode>&& node, _::ExceptionOrValue& result
_
::
Event
*
event
=
head
;
_
::
Event
*
event
=
head
;
head
=
event
->
next
;
head
=
event
->
next
;
if
(
head
!=
nullptr
)
{
head
->
prev
=
&
head
;
}
depthFirstInsertPoint
=
&
head
;
depthFirstInsertPoint
=
&
head
;
if
(
tail
==
&
event
->
next
)
{
if
(
tail
==
&
event
->
next
)
{
tail
=
&
head
;
tail
=
&
head
;
...
@@ -294,9 +295,6 @@ Event::Event()
...
@@ -294,9 +295,6 @@ Event::Event()
Event
::~
Event
()
noexcept
(
false
)
{
Event
::~
Event
()
noexcept
(
false
)
{
if
(
prev
!=
nullptr
)
{
if
(
prev
!=
nullptr
)
{
if
(
loop
.
head
==
this
)
{
loop
.
head
=
next
;
}
if
(
loop
.
tail
==
&
next
)
{
if
(
loop
.
tail
==
&
next
)
{
loop
.
tail
=
prev
;
loop
.
tail
=
prev
;
}
}
...
@@ -489,12 +487,14 @@ kj::String PromiseBase::trace() {
...
@@ -489,12 +487,14 @@ kj::String PromiseBase::trace() {
PromiseNode
*
PromiseNode
::
getInnerForTrace
()
{
return
nullptr
;
}
PromiseNode
*
PromiseNode
::
getInnerForTrace
()
{
return
nullptr
;
}
bool
PromiseNode
::
OnReadyEvent
::
init
(
Event
&
newEvent
)
{
void
PromiseNode
::
OnReadyEvent
::
init
(
Event
&
newEvent
)
{
if
(
event
==
_kJ_ALREADY_READY
)
{
if
(
event
==
_kJ_ALREADY_READY
)
{
return
true
;
// A new continuation was added to a promise that was already ready. In this case, we schedule
// breadth-first, to make it difficult for applications to accidentally starve the event loop
// by repeatedly waiting on immediate promises.
newEvent
.
armBreadthFirst
();
}
else
{
}
else
{
event
=
&
newEvent
;
event
=
&
newEvent
;
return
false
;
}
}
}
}
...
@@ -502,13 +502,18 @@ void PromiseNode::OnReadyEvent::arm() {
...
@@ -502,13 +502,18 @@ void PromiseNode::OnReadyEvent::arm() {
if
(
event
==
nullptr
)
{
if
(
event
==
nullptr
)
{
event
=
_kJ_ALREADY_READY
;
event
=
_kJ_ALREADY_READY
;
}
else
{
}
else
{
// A promise resolved and an event is already waiting on it. In this case, arm in depth-first
// order so that the event runs immediately after the current one. This way, chained promises
// execute together for better cache locality and lower latency.
event
->
armDepthFirst
();
event
->
armDepthFirst
();
}
}
}
}
// -------------------------------------------------------------------
// -------------------------------------------------------------------
bool
ImmediatePromiseNodeBase
::
onReady
(
Event
&
event
)
noexcept
{
return
true
;
}
void
ImmediatePromiseNodeBase
::
onReady
(
Event
&
event
)
noexcept
{
event
.
armBreadthFirst
();
}
ImmediateBrokenPromiseNode
::
ImmediateBrokenPromiseNode
(
Exception
&&
exception
)
ImmediateBrokenPromiseNode
::
ImmediateBrokenPromiseNode
(
Exception
&&
exception
)
:
exception
(
kj
::
mv
(
exception
))
{}
:
exception
(
kj
::
mv
(
exception
))
{}
...
@@ -522,8 +527,8 @@ void ImmediateBrokenPromiseNode::get(ExceptionOrValue& output) noexcept {
...
@@ -522,8 +527,8 @@ void ImmediateBrokenPromiseNode::get(ExceptionOrValue& output) noexcept {
AttachmentPromiseNodeBase
::
AttachmentPromiseNodeBase
(
Own
<
PromiseNode
>&&
dependency
)
AttachmentPromiseNodeBase
::
AttachmentPromiseNodeBase
(
Own
<
PromiseNode
>&&
dependency
)
:
dependency
(
kj
::
mv
(
dependency
))
{}
:
dependency
(
kj
::
mv
(
dependency
))
{}
bool
AttachmentPromiseNodeBase
::
onReady
(
Event
&
event
)
noexcept
{
void
AttachmentPromiseNodeBase
::
onReady
(
Event
&
event
)
noexcept
{
return
dependency
->
onReady
(
event
);
dependency
->
onReady
(
event
);
}
}
void
AttachmentPromiseNodeBase
::
get
(
ExceptionOrValue
&
output
)
noexcept
{
void
AttachmentPromiseNodeBase
::
get
(
ExceptionOrValue
&
output
)
noexcept
{
...
@@ -543,8 +548,8 @@ void AttachmentPromiseNodeBase::dropDependency() {
...
@@ -543,8 +548,8 @@ void AttachmentPromiseNodeBase::dropDependency() {
TransformPromiseNodeBase
::
TransformPromiseNodeBase
(
Own
<
PromiseNode
>&&
dependency
)
TransformPromiseNodeBase
::
TransformPromiseNodeBase
(
Own
<
PromiseNode
>&&
dependency
)
:
dependency
(
kj
::
mv
(
dependency
))
{}
:
dependency
(
kj
::
mv
(
dependency
))
{}
bool
TransformPromiseNodeBase
::
onReady
(
Event
&
event
)
noexcept
{
void
TransformPromiseNodeBase
::
onReady
(
Event
&
event
)
noexcept
{
return
dependency
->
onReady
(
event
);
dependency
->
onReady
(
event
);
}
}
void
TransformPromiseNodeBase
::
get
(
ExceptionOrValue
&
output
)
noexcept
{
void
TransformPromiseNodeBase
::
get
(
ExceptionOrValue
&
output
)
noexcept
{
...
@@ -607,8 +612,8 @@ void ForkBranchBase::releaseHub(ExceptionOrValue& output) {
...
@@ -607,8 +612,8 @@ void ForkBranchBase::releaseHub(ExceptionOrValue& output) {
}
}
}
}
bool
ForkBranchBase
::
onReady
(
Event
&
event
)
noexcept
{
void
ForkBranchBase
::
onReady
(
Event
&
event
)
noexcept
{
return
onReadyEvent
.
init
(
event
);
onReadyEvent
.
init
(
event
);
}
}
PromiseNode
*
ForkBranchBase
::
getInnerForTrace
()
{
PromiseNode
*
ForkBranchBase
::
getInnerForTrace
()
{
...
@@ -619,7 +624,7 @@ PromiseNode* ForkBranchBase::getInnerForTrace() {
...
@@ -619,7 +624,7 @@ PromiseNode* ForkBranchBase::getInnerForTrace() {
ForkHubBase
::
ForkHubBase
(
Own
<
PromiseNode
>&&
innerParam
,
ExceptionOrValue
&
resultRef
)
ForkHubBase
::
ForkHubBase
(
Own
<
PromiseNode
>&&
innerParam
,
ExceptionOrValue
&
resultRef
)
:
inner
(
kj
::
mv
(
innerParam
)),
resultRef
(
resultRef
)
{
:
inner
(
kj
::
mv
(
innerParam
)),
resultRef
(
resultRef
)
{
i
f
(
inner
->
onReady
(
*
this
))
armDepthFirst
(
);
i
nner
->
onReady
(
*
this
);
}
}
Maybe
<
Own
<
Event
>>
ForkHubBase
::
fire
()
{
Maybe
<
Own
<
Event
>>
ForkHubBase
::
fire
()
{
...
@@ -652,19 +657,20 @@ _::PromiseNode* ForkHubBase::getInnerForTrace() {
...
@@ -652,19 +657,20 @@ _::PromiseNode* ForkHubBase::getInnerForTrace() {
ChainPromiseNode
::
ChainPromiseNode
(
Own
<
PromiseNode
>
innerParam
)
ChainPromiseNode
::
ChainPromiseNode
(
Own
<
PromiseNode
>
innerParam
)
:
state
(
STEP1
),
inner
(
kj
::
mv
(
innerParam
))
{
:
state
(
STEP1
),
inner
(
kj
::
mv
(
innerParam
))
{
i
f
(
inner
->
onReady
(
*
this
))
armDepthFirst
(
);
i
nner
->
onReady
(
*
this
);
}
}
ChainPromiseNode
::~
ChainPromiseNode
()
noexcept
(
false
)
{}
ChainPromiseNode
::~
ChainPromiseNode
()
noexcept
(
false
)
{}
bool
ChainPromiseNode
::
onReady
(
Event
&
event
)
noexcept
{
void
ChainPromiseNode
::
onReady
(
Event
&
event
)
noexcept
{
switch
(
state
)
{
switch
(
state
)
{
case
STEP1
:
case
STEP1
:
KJ_REQUIRE
(
onReadyEvent
==
nullptr
,
"onReady() can only be called once."
);
KJ_REQUIRE
(
onReadyEvent
==
nullptr
,
"onReady() can only be called once."
);
onReadyEvent
=
&
event
;
onReadyEvent
=
&
event
;
return
false
;
return
;
case
STEP2
:
case
STEP2
:
return
inner
->
onReady
(
event
);
inner
->
onReady
(
event
);
return
;
}
}
KJ_UNREACHABLE
;
KJ_UNREACHABLE
;
}
}
...
@@ -710,9 +716,7 @@ Maybe<Own<Event>> ChainPromiseNode::fire() {
...
@@ -710,9 +716,7 @@ Maybe<Own<Event>> ChainPromiseNode::fire() {
state
=
STEP2
;
state
=
STEP2
;
if
(
onReadyEvent
!=
nullptr
)
{
if
(
onReadyEvent
!=
nullptr
)
{
if
(
inner
->
onReady
(
*
onReadyEvent
))
{
inner
->
onReady
(
*
onReadyEvent
);
onReadyEvent
->
armDepthFirst
();
}
}
}
return
nullptr
;
return
nullptr
;
...
@@ -725,8 +729,8 @@ ExclusiveJoinPromiseNode::ExclusiveJoinPromiseNode(Own<PromiseNode> left, Own<Pr
...
@@ -725,8 +729,8 @@ ExclusiveJoinPromiseNode::ExclusiveJoinPromiseNode(Own<PromiseNode> left, Own<Pr
ExclusiveJoinPromiseNode
::~
ExclusiveJoinPromiseNode
()
noexcept
(
false
)
{}
ExclusiveJoinPromiseNode
::~
ExclusiveJoinPromiseNode
()
noexcept
(
false
)
{}
bool
ExclusiveJoinPromiseNode
::
onReady
(
Event
&
event
)
noexcept
{
void
ExclusiveJoinPromiseNode
::
onReady
(
Event
&
event
)
noexcept
{
return
onReadyEvent
.
init
(
event
);
onReadyEvent
.
init
(
event
);
}
}
void
ExclusiveJoinPromiseNode
::
get
(
ExceptionOrValue
&
output
)
noexcept
{
void
ExclusiveJoinPromiseNode
::
get
(
ExceptionOrValue
&
output
)
noexcept
{
...
@@ -744,7 +748,7 @@ PromiseNode* ExclusiveJoinPromiseNode::getInnerForTrace() {
...
@@ -744,7 +748,7 @@ PromiseNode* ExclusiveJoinPromiseNode::getInnerForTrace() {
ExclusiveJoinPromiseNode
::
Branch
::
Branch
(
ExclusiveJoinPromiseNode
::
Branch
::
Branch
(
ExclusiveJoinPromiseNode
&
joinNode
,
Own
<
PromiseNode
>
dependencyParam
)
ExclusiveJoinPromiseNode
&
joinNode
,
Own
<
PromiseNode
>
dependencyParam
)
:
joinNode
(
joinNode
),
dependency
(
kj
::
mv
(
dependencyParam
))
{
:
joinNode
(
joinNode
),
dependency
(
kj
::
mv
(
dependencyParam
))
{
if
(
dependency
->
onReady
(
*
this
))
armDepthFirst
(
);
dependency
->
onReady
(
*
this
);
}
}
ExclusiveJoinPromiseNode
::
Branch
::~
Branch
()
noexcept
(
false
)
{}
ExclusiveJoinPromiseNode
::
Branch
::~
Branch
()
noexcept
(
false
)
{}
...
@@ -779,11 +783,11 @@ PromiseNode* ExclusiveJoinPromiseNode::Branch::getInnerForTrace() {
...
@@ -779,11 +783,11 @@ PromiseNode* ExclusiveJoinPromiseNode::Branch::getInnerForTrace() {
EagerPromiseNodeBase
::
EagerPromiseNodeBase
(
EagerPromiseNodeBase
::
EagerPromiseNodeBase
(
Own
<
PromiseNode
>&&
dependencyParam
,
ExceptionOrValue
&
resultRef
)
Own
<
PromiseNode
>&&
dependencyParam
,
ExceptionOrValue
&
resultRef
)
:
dependency
(
kj
::
mv
(
dependencyParam
)),
resultRef
(
resultRef
)
{
:
dependency
(
kj
::
mv
(
dependencyParam
)),
resultRef
(
resultRef
)
{
if
(
dependency
->
onReady
(
*
this
))
armDepthFirst
(
);
dependency
->
onReady
(
*
this
);
}
}
bool
EagerPromiseNodeBase
::
onReady
(
Event
&
event
)
noexcept
{
void
EagerPromiseNodeBase
::
onReady
(
Event
&
event
)
noexcept
{
return
onReadyEvent
.
init
(
event
);
onReadyEvent
.
init
(
event
);
}
}
PromiseNode
*
EagerPromiseNodeBase
::
getInnerForTrace
()
{
PromiseNode
*
EagerPromiseNodeBase
::
getInnerForTrace
()
{
...
@@ -804,8 +808,8 @@ Maybe<Own<Event>> EagerPromiseNodeBase::fire() {
...
@@ -804,8 +808,8 @@ Maybe<Own<Event>> EagerPromiseNodeBase::fire() {
// -------------------------------------------------------------------
// -------------------------------------------------------------------
bool
AdapterPromiseNodeBase
::
onReady
(
Event
&
event
)
noexcept
{
void
AdapterPromiseNodeBase
::
onReady
(
Event
&
event
)
noexcept
{
return
onReadyEvent
.
init
(
event
);
onReadyEvent
.
init
(
event
);
}
}
}
// namespace _ (private)
}
// namespace _ (private)
...
...
c++/src/kj/async.h
View file @
793b2af2
...
@@ -309,10 +309,14 @@ PromiseForResult<Func, void> evalLater(Func&& func);
...
@@ -309,10 +309,14 @@ PromiseForResult<Func, void> evalLater(Func&& func);
// Example usage:
// Example usage:
// Promise<int> x = evalLater([]() { return 123; });
// Promise<int> x = evalLater([]() { return 123; });
//
//
// The above is exactly equivalent to:
// Promise<int> x = Promise<void>(READY_NOW).then([]() { return 123; });
//
// If the returned promise is destroyed before the callback runs, the callback will be canceled
// If the returned promise is destroyed before the callback runs, the callback will be canceled
// (never called).
// (never called).
//
//
// If you schedule several evaluations with `evalLater`, they will be executed in order.
// If you schedule several evaluations with `evalLater` during the same callback, they are
// guaranteed to be executed in order.
// =======================================================================================
// =======================================================================================
// Hack for creating a lambda that holds an owned pointer.
// Hack for creating a lambda that holds an owned pointer.
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment