In the Interactive Brokers TWS c++ API, (or in event-driven programming in general) when is it critical to change the state/mode (this is m_state
in TWS API) to a state of "acknowledgement?" Depending on the state of this variable, different class methods are called. Towards the end of the definition of one of these methods, the state is changed back to an acknowledgement state, which appears to allow messages to be received by the host. Can I change m_state
to something else, and skip the acknowledgement process altogether?
Interactive Brokers' TWS C++ API has tens of thousands of lines of code, so let me try to describe what I think the essential functionality is.
My programs entry point in Main.cpp
instantiates a client object, and then repeatedly calls its void TestCppClient::processMessages()
method over and over again in every iteration of a while loop.
On the one hand, there are a bunch of methods that get triggered by the broker whenever the broker decides to call them, and you, as a client, may or may not take advantage of the provided information.
But on the other hand, there are a bunch of methods that get triggered by my client code. Depending on the value of m_state
, a different class method is triggered. In the sample code provided by IB, that is, in my TestCppClient
class, most of these functions have some helpful demonstration code provided, and more to the point of my question, most of these functions have the last line setting the value of m_state
to something ending in _ACK
(which, I believe, is a socket programming convention that is short for "acknowledgement.")
For example, when m_state
is equal to ST_REUTERSFUNDAMENTALS
, TestCppClient::processMessages()
's switch
statement will trigger TestCppClient::reutersFundamentals()
. The last line of this method's definition is
m_state = ST_REUTERSFUNDAMENTALS_ACK;
The next time void TestCppClient::processMessages()
is triggered, (and it gets triggered all the time by the while loop, if you recall) the switch statement is skipped due to there only being a break
statement:
...
case ST_REUTERSFUNDAMENTALS:
reutersFundamentals();
break;
case ST_REUTERSFUNDAMENTALS_ACK:
break;
...
This switch statement code makes up the majority of the code in this function's definition, but there is a little at the end outside of the switch statement. The only code that runs in TestCppClient::procesMessages()
in this case is at the very end, which is
m_pReader->checkClient();
m_osSignal.waitForSignal();
m_pReader->processMsgs();
These lines apparently handle some low-level socket programming stuff.
So, if I didn't change the state to an acknowledgement state, these last three lines wouldn't run. But would that be a bad thing? Does anyone have experience with this? Any anecdotal pieces of information?
The TestCppClient
example is fairly complicated as IB/C++ applications go, but those three lines are important. m_pReader
is an instance of the EReader
class, which reads incoming data and produces messages. Because it runs in its own thread, it needs special handling.
The checkClient
function tells the EReader
to package incoming data into an EMessage
and store the message in the message queue. But the application can't access the queue until the waitForSignal
function returns. Afterward, processMsgs
reads the EMessage
and calls the appropriate callback function.
Dealing with the EReader
is a pain, but once you get an application working, you can copy and paste the code into further applications.