If your app is fully non-blocking, doesn't it make sense to just do everything on the one pool, CPU bound tasks and IO polling.
Rather than passing messages between threads.
"Fully non-blocking" means "does no work". Ignoring the process' spawning thread, if your app performs CPU-bound tasks on a bounded thread pool, you will be leaving I/O throughput on the table as the number of tasks increases, since I/O-bound tasks will block on waiting for a thread.