There is no need to call PostQueuedCompletionStatus to stop the io_service if the outstanding work count is initially zero. A run/poll call can only be calling GetQueuedCompletionStatus if it the count was non-zero at some point. However, if it was previously non-zero, then the io_service will have already been stop()-ed when the count was decremented to zero.