(повторяя то, что я сказал в PerlMonks ...)
BEGIN {
my $mutex;
sub that {
$mutex ||= APR::ThreadMutex->new( $r->pool() );
$mutex->lock();
$ENV{TZ}= ...;
...
$mutex->unlock();
}
}
Но, конечно, lock () должна происходить в c'tor, а unlock () должна происходить в d'tor, за исключением одноразовых хаков.
Обновление: обратите внимание, что существует условие гонки в том, как $ mutex инициализируется в подпрограмме (два потока могут вызывать это () в первый раз почти одновременно). Скорее всего, вы захотите инициализировать $ mutex перед созданием (дополнительных) потоков, но мне неясно, как обстоят дела с «рабочим» Apache MPM и как вам это легко сделать. Если есть какой-то код, который запускается «рано», простой вызов that () оттуда исключит гонку.
Что предполагает гораздо более безопасный интерфейс для APR :: ThreadMutex:
BEGIN {
my $mutex;
sub that {
my $autoLock= APR::ThreadMutex->autoLock( \$mutex );
...
# Mutex automatically released when $autoLock destroyed
}
}
Обратите внимание, что autoLock (), получая ссылку на undef, заставит его использовать мьютекс для предотвращения гонки при инициализации $ mutex.