The docs claims that XmlRpcClient::execute() is a blocking call, but this isn't true. If you look in the code for XmlRpcClient::doConnect(), which gets called on the first execute() call, you see that it sets the socket to non-blocking. If you patch this call out:
Index: src/XmlRpcClient.cpp===================================================================--- src/XmlRpcClient.cpp (revision 2060)+++ src/XmlRpcClient.cpp (revision 2061)@@ -176,14 +176,6 @@
XmlRpcUtil::log(3, "XmlRpcClient::doConnect: fd %d.", fd);
this->setfd(fd);
- // Don't block on connect/reads/writes- if ( ! XmlRpcSocket::setNonBlocking(fd))- {- this->close();- XmlRpcUtil::error("Error in XmlRpcClient::doConnect: Could not set socket to non-blocking IO mode (%s).", XmlRpcSocket::getErrorMsg().c_str());- return false;- }-
if ( ! XmlRpcSocket::connect(fd, _host, _port))
{
this->close();
…the library starts hanging, because I/O is now blocking in places where the code didn't expect it to.
We want to make the library do blocking I/O safely, so we can get immediate error reports, such as when the library is given the IP of a nonexistent machine. Currently, if you do that, the execute() call fails without any diagnostics, because the connect(2) call doesn't block. The SYN goes out the Ethernet interface, nothing responds, but connect() has already returned, so XMLRPC++ marks the socket as connected and writeable.
A second-best alternative would be for the library to be truly non-blocking, but that would require an asynchronous event notification loop. (select(), poll(), etc.)
Has anyone forked XMLRPC++ in a way to sort this mess out?
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
The docs claims that XmlRpcClient::execute() is a blocking call, but this isn't true. If you look in the code for XmlRpcClient::doConnect(), which gets called on the first execute() call, you see that it sets the socket to non-blocking. If you patch this call out:
…the library starts hanging, because I/O is now blocking in places where the code didn't expect it to.
We want to make the library do blocking I/O safely, so we can get immediate error reports, such as when the library is given the IP of a nonexistent machine. Currently, if you do that, the execute() call fails without any diagnostics, because the connect(2) call doesn't block. The SYN goes out the Ethernet interface, nothing responds, but connect() has already returned, so XMLRPC++ marks the socket as connected and writeable.
A second-best alternative would be for the library to be truly non-blocking, but that would require an asynchronous event notification loop. (select(), poll(), etc.)
Has anyone forked XMLRPC++ in a way to sort this mess out?