AsyncJob: implement support for stdin as string

AsyncJob did not support filling the stdin pipe with a string input.
Resolve this by creating a new thread function to write stdin_string
in 512 byte chunks to the subprocess stdin PIPE.

Extract the drainer thread to be a protected staticmethod so we can
unittest it.

Refactor the thread functions to eliminate branches and lookups during
the while loop.

Instead of checking for None, check for the actual methods we use.
Only check once if Lock is None, otherwise in the case of None replace
acquire() and lock() with a noop like bool.

v2:
Remove lock from stdin_thread since no other thread will access stdin
Add try/finally to _fd_drainer to release the lock after an exception

Signed-off-by: Ross Brattain <ross.b.brattain@intel.com>