PuTTY and its supporting tools, or at least the vast majority of them, run in only one OS thread.
This means that if you're devising some piece of internal mechanism, there's no need to use locks to make sure it doesn't get called by two threads at once. The only way code can be called re-entrantly is by recursion.
That said, most of Windows PuTTY's network handling is triggered off Windows messages requested by WSAAsyncSelect()
, so if you call MessageBox()
deep within some network event handling code you should be aware that you might be re-entered if a network event comes in and is passed on to our window procedure by the MessageBox()
message loop.
Also, the front ends (in particular Windows Plink) can use multiple threads if they like. However, Windows Plink keeps very tight control of its auxiliary threads, and uses them pretty much exclusively as a form of select()
. Pretty much all the code outside windows/winplink.c
is only ever called from the one primary thread; the others just loop round blocking on file handles and send messages to the main thread when some real work needs doing. This is not considered a portability hazard because that bit of windows/winplink.c
will need rewriting on other platforms in any case.
One important consequence of this: PuTTY has only one thread in which to do everything. That ‘everything’ may include managing more than one login session (section D.3), managing multiple data channels within an SSH session, responding to GUI events even when nothing is happening on the network, and responding to network requests from the server (such as repeat key exchange) even when the program is dealing with complex user interaction such as the re-configuration dialog box. This means that almost none of the PuTTY code can safely block.