It would be sufficient exactly for this bug. However, there is another bug: without the lock a socket can be closed before initialization of m_reader variable and close method would access uninitialized m_reader.
Hm, you are right. A yield() at the beginning of startReader would fix that, too, with a little less overhead, but ManualEvent (and thus TaskMutex) are supposed to get some single-thread optimizations anyway, so that shouldn't matter. So I'd say your approach is preferable due to the clearer semantics.