The following simple error logging code in Global.asax looks thread safe:
static object errorLogLock = new object();
protected void Application_Error()
{
    Exception ex = Server.GetLastError();
    lock (errorLogLock)
        System.IO.File.AppendAllText(errorLogPath, ex.ToString());
}
but I believe it's not, since this question proves that it's possible for there to be multiple IIS processes at the same time, and each one will have its own errorLogLock.
How can I make this thread safe? Or alternatively, how can I prevent concurrent IIS processes?
I could use a mutex, but I'm wondering whether it's really necessary.
(Please do not advise me about better ways to log errors, I am well aware of them. Neither about using FileShare.Write.)