I've been trying to figure out how to use libssh2's non-blocking API correctly, and I'm stuck. I can get it to work 99% of the time, but that last 1% is eludes me.
The main problem I'm battling is what happens when I need to do a read on a channel, and I don't know if there's going to be any data there to read. If there is, I want to read it. If there's no data, I want to be able to do other stuff like write to the channel or read or write to another channel. Seems pretty normal. So let's say I call libssh2_channel_read_ex() and it returns LIBSSH2_ERROR_EAGAIN. My problem is that I can't tell what this means. It could mean that: * there was no data on that channel, and it's safe to go write some data or service another channel. or, * in the process of doing the read, libssh2 wandered into _libssh2_channel_receive_window_adjust, sending a message to the ssh server. While sending the adjust message, the TCP send buffer filled up, and the OS level send(2) call returned EAGAIN Of course, this second case is the one that is giving me problems. Although I haven't seen it stated explicitly anywhere, it looks like if I get LIBSSH2_ERROR_EAGAIN due to a failed write, the only thing I can safely do with libssh2 is wait and call the same libssh2_channel_read_ex() function again with the same arguments until it manages to finish the write. If I were to make some other call to libssh2 which could result in network traffic, libssh2 will give me a slap on the wrist (in the form of a LIBSSH2_ERROR_BAD_USE) and then I'm in trouble. If I always assume that an LIBSSH2_ERROR_EAGAIN means that I can call other functions, my tests will usually run pretty well for a few minutes, maybe even hours, but eventually this error (or some variant of it) will bite me. If I assume that LIBSSH2_ERROR_EAGAIN means the only thing I can do is call the exact same function until it succeeds, I'm trapped because I can't safely read from a channel unless I know there will be data on it. Am I missing something that would let me use the public API safely? Right now I'm playing around with workarounds like only allowing my code to switch and call another function if session->packet.olen == 0 after an LIBSSH2_ERROR_EAGAIN, but that's ugly and I don't have much confidence that I'm on the right track. Thanks. _______________________________________________ libssh2-devel http://cool.haxx.se/cgi-bin/mailman/listinfo/libssh2-devel