The shim must read from multiple inputs at arbitrary times, at a minimum both the downstream client and the upstream IB tws, and so it can not block for input from either one. Process threads are widely used for such multiplexed IO.
From the viewpoint of the downstream user, the client-shim system necessarily includes time-dependent control. Timeouts, the simplest case, are required if we are to detect lack of response, as when requests are ignored, and other requirements can lead to significantly more complicated reactive control. Such control is difficult to get right, and critically important; consider, e.g., a downstream client program updating a graph from the results of recurring history queries, where the program must either have current data, or signal that the data feed has dried up. Again, process threads are widely used for such reactive control.
Quite often, as here, threads save no time whatsoever, and in that case I prefer to use the select() system call, both for IO multiplexing, and as the foundation of reactive control. Once having abandoned the unecessary complexity of threads, a single thread of control and straight forward domain analysis lead naturally to a scheduling/dispatching control object, for the shim named the Router.
The Router plays a leading role in the read-route-write loop that provides the high-level control for the shim, controlling either directly or by its data members: the wait for input, using select(); the task scheduler, responsible for timeouts and periodic events, such as recurring history queries; and event dispatch, or routing, once events have been read from input.
The Router and its included children work efficiently to keep track of time by using multiple time scales of: seconds, 20 millisecond intervals, and the processor clock rate itself. The first time scale is from the downstream application domain, e.g. for timeouts; the second, from the maximum allowed sustained frequency for IB tws requests; and the third is chosen for implementation reasons.
Each of these clocks is read by the shim, and though none is ideal by itself, used together judiciously they provide accurate time-keeping and precise timestamps at low time cost. In brief, the select() timeout is set with the IB tws request period; the localtime() system call is used, for seconds, once the select call returns, to detect timeouts, and 1 second clock ticks; and the processor read time stamp counter instruction, also rtsc, provides fine granularity, both for event timestamps, and to check the select timeout. This test is to ensure that 20 milliseconds have actually passed, since although the processor rtsc result may rollover, or lose time depending on power-save settings, it can be trusted in any case not to be fast, and the 1 second timer serves as backup if it has been stopped by sleep.