I think that I figured this out.
There is a pause() command or similar somewhere in the modbus functions (read(),write()) that triggers the queue to execute. This is why it appeared that my TimerFcn was being interrupted.
As others have pointed out, a timer function will break a callback between lines, regardless of if it is interruptible, in order to execute "on time".
The reverse does not appear to be true. That is to say, the TimerFcn is non-interruptible as long as it does not contain a pause(), or drawnow, or any of the other commands that trigger the queue. This makes sense as the timer executes the queue before running the TImerFcn.
I still haven't found a clever way to prevent the queue from running when a pause() is encountered (basically a "do not run queue" hold). I have no clue how the app queue is maintained, or how to access and modify it.
Since I have several instruments communicating and multiple timers, I opted to have my callbacks and secondary timer functions schedule an update (basically an ad hoc queue that I control) and then an update function runs at the end of my primary timer callback and updates everything. The primary timer is set to 'drop' just in case the updates run long for some reason. Keeping commands that may have a significant lag out of non-primary callbacks works well.
Not a huge fan of maintaining my own bootleg queue, but until someone provides a more clever solution...