When running walletpassphrase on a large wallet.dat (ie about 300,000 segwit P2SH addresses) the command sometimes takes a very long time, and if command is run multiple times at once (while running slow) it causes bitcoin core to freeze (stops syncing and requires kill -9 to stop/restart)

During the locked up walletpassphrase commands being run the following messages start to appear in the debug.log:

`018-01-24 01:01:04 socket sending timeout: 1201s`

Note that this problem is intermittent, so sometimes the command runs instantly, other times it takes a few minutes, and other times it completely freezes the node.
virtual ~ScriptPubKeyMan() {};
    virtual bool GetNewDestination(const OutputType type, CTxDestination& dest, std::string& error) { return false; }
    virtual isminetype IsMine(const CScript& script) const { return ISMINE_NO; }
    
    virtual bool CheckDecryptionKey(const CKeyingMaterial& master_key, bool accept_no_keys = false) { return false; }
    virtual bool Encrypt(const CKeyingMaterial& master_key, WalletBatch* batch) { return false; }
    virtual bool GetReservedDestination(const OutputType type, bool internal, CTxDestination& address, int64_t& index, CKeyPool& keypool) { return false; }
    virtual void KeepDestination(int64_t index, const OutputType& type) {}
    virtual void ReturnDestination(int64_t index, bool internal, const CTxDestination& addr) {}
    /** Fills internal address pool. Use within ScriptPubKeyMan implementations should be used sparingly and only
      * when something from the address pool is removed, excluding GetNewDestination and GetReservedDestination.
      * External wallet code is primarily responsible for topping up prior to fetching new addresses
      */
    virtual bool TopUp(unsigned int size = 0) { return false; }
    
    virtual void MarkUnusedAddresses(const CScript& script) {}
    /** Sets up the key generation stuff, i.e. generates new HD seeds and sets them as active.
      * Returns false if already setup or setup fails, true if setup is successful
      * Set force=true to make it re-setup if already setup, used for upgrades
      */
    virtual bool SetupGeneration(bool force = false) { return false; }
    
    virtual bool IsHDEnabled() const { return false; }
    
    virtual bool CanGetAddresses(bool internal = false) const { return false; }
    
    virtual bool Upgrade(int prev_version, bilingual_str& error) { return false; }
    virtual bool HavePrivateKeys() const { return false; }
    
    virtual void RewriteDB() {}