I use Microsoft RPC for interprocess communications. I have an interface with a set of methods accepting a byte pipe as an ‘in’ parameter (IDL description):
[ uuid(ActualGuidHere), version(1.0), pointer_default(unique) ] interface IMyInterface { //other irrelevant methods here error_status_t rpcDoAction( [in] pipe byte params ); //more irrelevant methods here }
every once in a while when I invoke such methods on a client side through a client stub generated by MIDL and delegated to NdrClientCall2(), it doesn’t reach the server side, but NdrClientCall2() returns RPC_S_ALREADY_LISTENING (‘The server is already listening’) which is really confusing.
I added logging into the functions used for push/pull operations during transfer – they are not ever called for any of the calls that fail this way. This implies that the transmission is not even started.
I never encounter such behaviour when calling methods that don’t have pipes as parameters.
What might be the reason and the workaround?
The documentation seems quite minimal – I don’t think there is a huge user community for direct use of the RPC APIs – but my guess is that in order to set up the pipe parameter, it is necessary for RPC to internally call
RpcServerListen. Only one call to that API is able to block at a time.The fact that you see the problem only occasionally suggests that it is time-related, so is it possible that you are making two such calls on different threads and sometimes they will be simultaneous?
Either that or there is a timing-related bug in the RPC library’s implementation and you will have to work around it by retrying the call (that may be an effective workaround in any case).