I was recently tech editing a future article for CFDJ when I came across the following set of code (which has been turned into pseudo-code for brevity's sake):
if not defined("server.foo")
lock:exclusive
create server.foo
end the lock
end if
The idea was - if server.foo doesn't exist, create it, but wrap the creation inside an exclusive lock. However, this code has one problem. Can you see it? Imagine two threads, A and B, come into this page at the same time. They both hit the if not defined line at the same time. It's true for both, so both threads go to the next line. Thread B is ahead, so it gets the lock. It then creates the object and unlocks the code. Thread A then enters the lock as well and ALSO creates the object.
So what happaned? At the time when the threads checked for the object existence, it did not exist, but before the second thread could create it, another thread was ahead of it and made the object. So how would you change it?
if not defined("server.foo")
lock:exclusive
if still not defined,
create server.foo
end the lock
end if
Don't forget that most of the time, users define persistant variables that act as constants, i.e., application.dsn = "foo". In these cases, under MX only, locking is not needed at all.