{"push_id":1470776693,"size":1,"distinct_size":0,"ref":"refs/heads/cpp98","head":"0502020488bc6d381f76fb6a1616cc58c8ffb903","before":"7267ff124076bea9f391dc0dde3b0f6dd376db33","commits":[{"sha":"0502020488bc6d381f76fb6a1616cc58c8ffb903","author":{"name":"Shuo Chen","email":"05e1b3eeb69037b2f64b5addbc9b3d463fc26409@chenshuo.com"},"message":"Fix race condition of Tunnel.\n\nHigh watermark callback should only stop reading peer connection if its\noutput buffer is not empty.\n\nOriginally, the high watermark callback will stop reading the peer\nconnection and register a write complete callback unconditionally.\n\nConsiter two events happening in the same EventLoop iteration:\n  Connection C is readable\n  Connection S is writable\n\nIn C.onMessage(), it calls S.send(), then decides to queue a high\nwatermark callback because S.outputBuffer is full.  S.HWM will be\ncalled after event handling.\n\nIn S.handleWrite(), all data are sent, output buffer becomes empty,\nbut it doesn't queue write complete callback of S because it's not\nregistered yet.\n\nIn doPendingFunctors(), S.HWM is called, stop reading C, and register a\nwrite complete callback for S to re-enable reading C.  This will never\nhappen because S has nothing to send, it is already write complete.\n\nA false fix:\n  Register write complete callback at beginning, never unregister it.\nThis of course has some performance penalty, but appears to work\nbecause in the case of two events above, S.handleWrite() will queue its\nwrite complete callback after S.HWM.  In doPendingFunctors(), first call\nS.HWM to stop reading C, then call S.WC to re-enable reading C.\n\nThis false fix has a subtle dependency on the execution sequence of\nmuduo EventLoop::doPendingFunctors(), and if EventLoop replace the queue\nwith a stack, the program breaks mystically.","distinct":false,"url":"https://api.github.com/repos/chenshuo/muduo/commits/0502020488bc6d381f76fb6a1616cc58c8ffb903"}]}
{"actor":{"display_login":"chenshuo"}}