Skip to content

Commit bdf0d5e

Browse files
committed
Use better perfect forwarding in task system
1 parent 3ab872f commit bdf0d5e

File tree

2 files changed

+78
-57
lines changed

2 files changed

+78
-57
lines changed

fly/task/task_runner.cpp

+10-16
Original file line numberDiff line numberDiff line change
@@ -13,16 +13,13 @@ TaskRunner::TaskRunner(std::weak_ptr<TaskManager> weak_task_manager) noexcept :
1313
//==================================================================================================
1414
bool TaskRunner::post_task_to_task_manager(TaskLocation &&location, Task &&task)
1515
{
16-
std::shared_ptr<TaskManager> task_manager = m_weak_task_manager.lock();
17-
if (!task_manager)
16+
if (std::shared_ptr<TaskManager> task_manager = m_weak_task_manager.lock(); task_manager)
1817
{
19-
return false;
18+
task_manager->post_task(std::move(location), std::move(task), shared_from_this());
19+
return true;
2020
}
2121

22-
std::weak_ptr<TaskRunner> task_runner = shared_from_this();
23-
task_manager->post_task(std::move(location), std::move(task), std::move(task_runner));
24-
25-
return true;
22+
return false;
2623
}
2724

2825
//==================================================================================================
@@ -31,23 +28,20 @@ bool TaskRunner::post_task_to_task_manager_with_delay(
3128
Task &&task,
3229
std::chrono::milliseconds delay)
3330
{
34-
std::shared_ptr<TaskManager> task_manager = m_weak_task_manager.lock();
35-
if (!task_manager)
31+
if (std::shared_ptr<TaskManager> task_manager = m_weak_task_manager.lock(); task_manager)
3632
{
37-
return false;
33+
task_manager
34+
->post_task_with_delay(std::move(location), std::move(task), shared_from_this(), delay);
35+
return true;
3836
}
3937

40-
std::weak_ptr<TaskRunner> task_runner = shared_from_this();
41-
task_manager
42-
->post_task_with_delay(std::move(location), std::move(task), std::move(task_runner), delay);
43-
44-
return true;
38+
return false;
4539
}
4640

4741
//==================================================================================================
4842
void TaskRunner::execute(TaskLocation &&location, Task &&task)
4943
{
50-
std::move(task)(this, location);
44+
std::invoke(std::move(task), this, location);
5145
task_complete(std::move(location));
5246
}
5347

fly/task/task_runner.hpp

+68-41
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,15 @@ class TaskRunner : public std::enable_shared_from_this<TaskRunner>
344344
std::chrono::milliseconds delay);
345345

346346
private:
347+
/**
348+
* Container to wrap around a generic callable type to allow perfect forwarding into lambdas.
349+
*/
350+
template <typename TaskType>
351+
struct TaskHolder
352+
{
353+
TaskType m_task;
354+
};
355+
347356
/**
348357
* Wrap a task in a generic lambda to be agnostic to the return type of the task.
349358
*
@@ -523,7 +532,7 @@ class SequencedTaskRunner : public TaskRunner
523532
template <typename TaskType>
524533
bool TaskRunner::post_task(TaskLocation &&location, TaskType &&task)
525534
{
526-
return post_task_internal(std::move(location), wrap_task(std::move(task)));
535+
return post_task_internal(std::move(location), wrap_task(std::forward<TaskType>(task)));
527536
}
528537

529538
//==================================================================================================
@@ -535,14 +544,16 @@ bool TaskRunner::post_task(
535544
{
536545
return post_task_internal(
537546
std::move(location),
538-
wrap_task(std::move(task), std::move(weak_owner)));
547+
wrap_task(std::forward<TaskType>(task), std::move(weak_owner)));
539548
}
540549

541550
//==================================================================================================
542551
template <typename TaskType, typename ReplyType>
543552
bool TaskRunner::post_task_with_reply(TaskLocation &&location, TaskType &&task, ReplyType reply)
544553
{
545-
return post_task_internal(std::move(location), wrap_task(std::move(task), std::move(reply)));
554+
return post_task_internal(
555+
std::move(location),
556+
wrap_task(std::forward<TaskType>(task), std::move(reply)));
546557
}
547558

548559
//==================================================================================================
@@ -555,7 +566,7 @@ bool TaskRunner::post_task_with_reply(
555566
{
556567
return post_task_internal(
557568
std::move(location),
558-
wrap_task(std::move(task), std::move(reply), std::move(weak_owner)));
569+
wrap_task(std::forward<TaskType>(task), std::move(reply), std::move(weak_owner)));
559570
}
560571

561572
//==================================================================================================
@@ -567,7 +578,7 @@ bool TaskRunner::post_task_with_delay(
567578
{
568579
return post_task_to_task_manager_with_delay(
569580
std::move(location),
570-
wrap_task(std::move(task)),
581+
wrap_task(std::forward<TaskType>(task)),
571582
delay);
572583
}
573584

@@ -581,7 +592,7 @@ bool TaskRunner::post_task_with_delay(
581592
{
582593
return post_task_to_task_manager_with_delay(
583594
std::move(location),
584-
wrap_task(std::move(task), std::move(weak_owner)),
595+
wrap_task(std::forward<TaskType>(task), std::move(weak_owner)),
585596
delay);
586597
}
587598

@@ -595,7 +606,7 @@ bool TaskRunner::post_task_with_delay_and_reply(
595606
{
596607
return post_task_to_task_manager_with_delay(
597608
std::move(location),
598-
wrap_task(std::move(task), std::move(reply)),
609+
wrap_task(std::forward<TaskType>(task), std::move(reply)),
599610
delay);
600611
}
601612

@@ -610,7 +621,7 @@ bool TaskRunner::post_task_with_delay_and_reply(
610621
{
611622
return post_task_to_task_manager_with_delay(
612623
std::move(location),
613-
wrap_task(std::move(task), std::move(reply), std::move(weak_owner)),
624+
wrap_task(std::forward<TaskType>(task), std::move(reply), std::move(weak_owner)),
614625
delay);
615626
}
616627

@@ -620,9 +631,11 @@ Task TaskRunner::wrap_task(TaskType &&task)
620631
{
621632
static_assert(std::is_invocable_v<TaskType>, "Task must be invocable without any arguments");
622633

623-
return [task = std::move(task)](TaskRunner *, TaskLocation) mutable
634+
TaskHolder<TaskType> holder {std::forward<TaskType>(task)};
635+
636+
return [holder = std::move(holder)](TaskRunner *, TaskLocation) mutable
624637
{
625-
FLY_UNUSED(std::move(task)());
638+
FLY_UNUSED(std::invoke(std::move(holder.m_task)));
626639
};
627640
}
628641

@@ -636,14 +649,14 @@ Task TaskRunner::wrap_task(TaskType &&task, std::weak_ptr<OwnerType> weak_owner)
636649
std::is_invocable_v<TaskType, StrongOwnerType>,
637650
"Task must be invocable with only a strong pointer to its owner");
638651

639-
return [task = std::move(task),
652+
TaskHolder<TaskType> holder {std::forward<TaskType>(task)};
653+
654+
return [holder = std::move(holder),
640655
weak_owner = std::move(weak_owner)](TaskRunner *, TaskLocation) mutable
641656
{
642-
StrongOwnerType owner = weak_owner.lock();
643-
644-
if (owner)
657+
if (StrongOwnerType owner = weak_owner.lock(); owner)
645658
{
646-
FLY_UNUSED(std::move(task)(std::move(owner)));
659+
FLY_UNUSED(std::invoke(std::move(holder.m_task), std::move(owner)));
647660
}
648661
};
649662
}
@@ -664,18 +677,25 @@ Task TaskRunner::wrap_task(TaskType &&task, ReplyType &&reply)
664677
"that type, or the task must return void and the reply must be invocable without any "
665678
"arguments");
666679

667-
return [task = std::move(task),
668-
reply = std::move(reply)](TaskRunner *runner, TaskLocation location) mutable
680+
TaskHolder<TaskType> task_holder {std::forward<TaskType>(task)};
681+
TaskHolder<ReplyType> reply_holder {std::forward<ReplyType>(reply)};
682+
683+
return
684+
[task_holder = std::move(task_holder),
685+
reply_holder = std::move(reply_holder)](TaskRunner *runner, TaskLocation location) mutable
669686
{
670687
if constexpr (s_result_is_void)
671688
{
672-
std::move(task)();
673-
runner->post_task(std::move(location), std::move(reply));
689+
std::invoke(std::move(task_holder.m_task));
690+
runner->post_task(std::move(location), std::move(reply_holder.m_task));
674691
}
675692
else
676693
{
677-
auto result = std::move(task)();
678-
runner->post_task(std::move(location), std::bind(std::move(reply), std::move(result)));
694+
auto result = std::invoke(std::move(task_holder.m_task));
695+
696+
runner->post_task(
697+
std::move(location),
698+
std::bind(std::move(reply_holder.m_task), std::move(result)));
679699
}
680700
};
681701
}
@@ -700,29 +720,36 @@ Task TaskRunner::wrap_task(TaskType &&task, ReplyType &&reply, std::weak_ptr<Own
700720
"type and a strong pointer to its owner, or the task must return void and the reply must "
701721
"be invocable with only a strong pointer to its owner");
702722

703-
return [task = std::move(task),
704-
reply = std::move(reply),
723+
TaskHolder<TaskType> task_holder {std::forward<TaskType>(task)};
724+
TaskHolder<ReplyType> reply_holder {std::forward<ReplyType>(reply)};
725+
726+
return [task_holder = std::move(task_holder),
727+
reply_holder = std::move(reply_holder),
705728
weak_owner = std::move(weak_owner)](TaskRunner *runner, TaskLocation location) mutable
706729
{
707-
StrongOwnerType owner = weak_owner.lock();
708-
if (!owner)
709-
{
710-
return;
711-
}
712-
713-
if constexpr (s_result_is_void)
730+
if (StrongOwnerType owner = weak_owner.lock(); owner)
714731
{
715-
std::move(task)(std::move(owner));
716-
runner->post_task(std::move(location), std::move(reply), std::move(weak_owner));
717-
}
718-
else
719-
{
720-
auto result = std::move(task)(std::move(owner));
721-
722-
runner->post_task(
723-
std::move(location),
724-
std::bind(std::move(reply), std::move(result), std::placeholders::_1),
725-
std::move(weak_owner));
732+
if constexpr (s_result_is_void)
733+
{
734+
std::invoke(std::move(task_holder.m_task), std::move(owner));
735+
736+
runner->post_task(
737+
std::move(location),
738+
std::move(reply_holder.m_task),
739+
std::move(weak_owner));
740+
}
741+
else
742+
{
743+
auto result = std::invoke(std::move(task_holder.m_task), std::move(owner));
744+
745+
runner->post_task(
746+
std::move(location),
747+
std::bind(
748+
std::move(reply_holder.m_task),
749+
std::move(result),
750+
std::placeholders::_1),
751+
std::move(weak_owner));
752+
}
726753
}
727754
};
728755
}

0 commit comments

Comments
 (0)