Keyboard Shortcuts
Likes
Search
questions about the two thread design (TWS c++ api)
I'm trying to reason about the c++ TWS API, and according to the documentation
One thread is used for sending messages to TWS, and another thread is used for reading returned messages. The second thread uses the API EReader class to read from the socket and add messages to a queue. Everytime a new message is added to the message queue, a notification flag is triggered to let other threads now that there is a message waiting to be processed. In the two-thread design of an API program, the message queue is also processed by the first thread.I'm trying to modify variables in callbacks that read information, and read them to send messages in other methods. Here are my questions: 1. Each callback is only controlled by one and only one thread, I hope. Is that right? 2. std::unique_ptr<EReader> m_pReader is the subordinate thread that triggers all these pure virtual methods that report information from TWS, right? The main thread calls methods explicitly in TestCppClient's definition, and I can see those. 3.? EClientSocket * const m_pClient sends information *to* TWS, but uses the same shared data structure as m_pReader (they both look at EReaderOSSignal m_osSignal, for example)? Is all the shared stuff written by IBKR thread safe? I think I would've heard about it by now they weren't. That would be pretty crazy. |
The call to EReader->start() creates a thread that listens for messages coming in from TWS. When a message comes in it is added to a queue. That is all that thread does. In your application you create a thread that loops waiting for the signal that something is on the queue. It is this thread that dispatches to your EWrapperImpl callbacks.? So in C++ the message reading and the callbacks are on separate threads.? |
You don't need to worry about contention between the message reader and sender but you do have to care about possible race conditions between your message dispatch loop and your main thread. i.e. The callbacks return data in one thread which you will likely use in your main thread. However that type of contention is related to your own app design rather than the API. On Sun, 8 Oct 2023, 22:14 , <tbrown122387@...> wrote: Oh, so I don't need to worry about race conditions at all do I? I'm just going through TestCppClient::processMessages() over and over again? Do something based on m_state, then receive information from callbacks. Got it. |
Thank you for following up because I actually did *not* understand.
so to confirm: callbacks like execDetails and orderStatus and tickByTickLast can get called by a separate thread, possibly leading to race conditions, which necessitates synchronization of state variables such as current position, etc. |
No |
To add to Gordon's answer: One thread does I/O, parsing of network messages and formatting of network messages.? The other thread gets callbacks, does your application logic and makes requests to the API. Hunter
On Tuesday, October 10, 2023 at 12:11:09 PM PDT, Gordon Eldest via groups.io <hymagik@...> wrote:
No |
Yes, I was able to find those callback invocations in all?EDecoder.cpp as well. However, this just proves that calling *is* done in the main thread, not that it *isn't done in the other thread*. Apologies for being pedantic.
The reasons I ask are? a.) some threads on this forum mention calls can be done from either thread, and b.) it's difficult to grep every single callback of my EWrapper implementation in the source code. I only grepped the ones I'm interested in and indeed they're all *only* being called in EDecoder.cpp, so you're probably right. |
It proves that callbacks CANNOT be process anywhere else. |