-
Notifications
You must be signed in to change notification settings - Fork 38
Description
I've been trying to understand how it is possible for your excellent library to be able to execute async operations (for example steady_timer) on the same main thread as grpc.
I ran the hello-world-server-cpp20.cpp in a debugger to help my understanding.
Part of my initial confusion is because I see in grpcContext.ipp/get_next_event() that it seems to be blocking only on the grpc completion queue (call to get_completion_queue()->AsyncNext()), so how could it unblock on other async events that are not grpc?
Then using the debugger I found that at the start of main() of hello-world-server-cpp20.cpp that this statement:
boost::asio::basic_signal_set signals{grpc_context, SIGINT, SIGTERM};
spawns a 2nd ASIO thread.
Then I see that when I have another non-grpc async operation, such as steady_timer, that when the steady_timer expires it wakes up this 2nd ASIO thread somehow. Then when that wakes up somehow you get it to post a grpc alarm with immediate deadline to the grpc completion queue which unblocks the main thread and allows the handler for the steady timer to execute. Is this the proper understanding?
So would it be that any (not just steady_timer) non-grpc async completion handlers would wake up that 2nd thread which then sends an immediate grpc alarm to wake up the completion handler in the main thread? That is how you get non-grpc async completion handlers to execute?
Not knowing how boost::asio works so well, I suppose this 2nd thread is always there and wakes up the main thread, even when using basic io_context and not an overridden execution_context? Or is this 2nd thread somehow created because you have overridden the basic io_context/execution_context?