info: Use an RW lock to protect the log functions and their list
Previously the code tried to be thread-safe by only locking when modifying the list and leaking the old list, but this was not sufficient. When removing a log function, its user_data would be freed but this log function and its user_data might afterwards still be used during logging which then could lead to memory corruption.
To avoid that, use an RW lock: get a write lock whenever modifying the list and get a read lock whenever only using the list of log functions for logging.
Fixes #3660 (closed)