Created by: zhaoqin
We split the synch-all threads operation into two synch operations:
- pre-exit synch: synchronize all app threads and ignore client threads
- post-exit synch: synchronize all threads. The pre-exit synch is called before all client thread exit and process exit events. The post-exit synch is called after all the client exit events. By doing so, the sideline client thread could have a chance to perform graceful exit from the process exit event.
Fixes #297