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.
bool AddWatchOnlyWithDB(WalletBatch &batch, const CScript& dest, int64_t create_time) EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore);
    
    bool AddKeyPubKeyWithDB(WalletBatch &batch,const CKey& key, const CPubKey &pubkey) EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore);
    void AddKeypoolPubkeyWithDB(const CPubKey& pubkey, const bool internal, WalletBatch& batch);
    
    bool AddCScriptWithDB(WalletBatch& batch, const CScript& script);
    
    bool AddKeyOriginWithDB(WalletBatch& batch, const CPubKey& pubkey, const KeyOriginInfo& info);
    
    CHDChain hdChain;
    
    void DeriveNewChildKey(WalletBatch& batch, CKeyMetadata& metadata, CKey& secret, bool internal = false) EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore);
    std::set<int64_t> setInternalKeyPool GUARDED_BY(cs_KeyStore);
    std::set<int64_t> setExternalKeyPool GUARDED_BY(cs_KeyStore);
    std::set<int64_t> set_pre_split_keypool GUARDED_BY(cs_KeyStore);
    int64_t m_max_keypool_index GUARDED_BY(cs_KeyStore) = 0;
    std::map<CKeyID, int64_t> m_pool_key_to_index;
    
    std::map<int64_t, CKeyID> m_index_to_reserved_key;
    
    bool GetKeyFromPool(CPubKey &key, const OutputType type, bool internal = false);
    /**
     * Reserves a key from the keypool and sets nIndex to its index
     *
     * @param[out] nIndex the index of the key in keypool
     * @param[out] keypool the keypool the key was drawn from, which could be the
     *     the pre-split pool if present, or the internal or external pool
     * @param fRequestedInternal true if the caller would like the key drawn
     *     from the internal keypool, false if external is preferred
     *