for (auto stack : spawned.entries) {
stack->put();
}
+
+ if (preallocated_stack) {
+ preallocated_stack->put();
+ }
}
int RGWCoroutinesStack::operate(RGWCoroutinesEnv *_env)
rgw_spawned_stacks *s = (source_op ? &source_op->spawned : &spawned);
- RGWCoroutinesStack *stack = env->manager->allocate_stack();
+ RGWCoroutinesStack *stack = preallocated_stack;
+ if (!stack) {
+ stack = env->manager->allocate_stack();
+ }
+ preallocated_stack = nullptr;
+
s->add_pending(stack);
stack->parent = this;
return spawn(NULL, op, wait);
}
+RGWCoroutinesStack *RGWCoroutinesStack::prealloc_stack()
+{
+ if (!preallocated_stack) {
+ preallocated_stack = env->manager->allocate_stack();
+ }
+ return preallocated_stack;
+}
+
int RGWCoroutinesStack::wait(const utime_t& interval)
{
RGWCompletionManager *completion_mgr = env->manager->get_completion_mgr();
return stack->spawn(this, op, wait);
}
+RGWCoroutinesStack *RGWCoroutine::prealloc_stack()
+{
+ return stack->prealloc_stack();
+}
+
+uint64_t RGWCoroutine::prealloc_stack_id()
+{
+ return prealloc_stack()->get_id();
+}
+
bool RGWCoroutine::collect(int *ret, RGWCoroutinesStack *skip_stack, uint64_t *stack_id) /* returns true if needs to be called again */
{
return stack->collect(this, ret, skip_stack, stack_id);
bool collect(int *ret, RGWCoroutinesStack *skip_stack, uint64_t *stack_id = nullptr); /* returns true if needs to be called again */
bool collect_next(int *ret, RGWCoroutinesStack **collected_stack = NULL); /* returns true if found a stack to collect */
+ RGWCoroutinesStack *prealloc_stack(); /* prepare a stack that will be used in the next spawn operation */
+ uint64_t prealloc_stack_id(); /* prepare a stack that will be used in the next spawn operation, return its id */
+
int wait(const utime_t& interval);
bool drain_children(int num_cr_left,
RGWCoroutinesStack *skip_stack = nullptr,
rgw_spawned_stacks spawned;
+ RGWCoroutinesStack *preallocated_stack{nullptr};
+
set<RGWCoroutinesStack *> blocked_by_stack;
set<RGWCoroutinesStack *> blocking_stacks;
void call(RGWCoroutine *next_op);
RGWCoroutinesStack *spawn(RGWCoroutine *next_op, bool wait);
+ RGWCoroutinesStack *prealloc_stack();
int unwind(int retcode);
int wait(const utime_t& interval);