Compile-time check on task parameters (part 2)

In my previous post in the series I wrote how in our HTML rendering engine we try to avoid accidental errors when passing parameters to tasks. A task is a unit of work that might happen on a different thread. Specifically we want to avoid passing objects of types that are not designed to be kept in a task. The previous post highlights the rationale behind the design of the system, I’ll only discuss the implementation here.

The syntax for launching the task is the following:

The syntax is very close to a normal C++ lambda, slightly modified to perform the parameter validation, which is hidden behind the TASK_PARAMS macro. At compile-time it’ll walk all the variables passed to it and make sure that their types are explicitly allowed to be passed to a task. All other types will produce a meaningful compilation error.

The macro is expanded to a ValidateTaskParameters function that looks like this:

The function inspects all parameters through variadic template expansion and performs a series of compile-time checks of their types. The meta-programming templates are somewhat annoying, but worth the complexity in this case.

The first condition for instance says “if the type is a pointer and it wasn’t explicitly allowed to be passed as pointer – generate error”. We usually don’t allow naked pointers to be passed around in tasks, but if the developer knows what she is doing, she can force-allow it.

Marking types is done with template tagging hidden behind a macro for convenience.

Additional macros are available for marking other ways to share an object: by shared pointer, by weak pointer etc. There is also tag & macro that forbid passing a type to a task altogether.

To recap, our system forces developers to think carefully what types can be passed around in tasks and reduces the chances of accidental errors. The implementation warns at the earliest possible time – during compilation and has no run-time cost and a modest compilation-time cost.

Suggestions and comments are appreciated, please share if you have tackled a similar problem.