G'day Stackoverflowers,
Я являюсь автором прагмы autodie в Perl, которая изменяет встроенные функции Perl для создания исключений при сбое. Это похоже на Fatal , но с лексической областью действия, расширяемой моделью исключений, более интеллектуальной проверкой возврата и многими, более приятными сообщениями об ошибках. Он заменит модуль Fatal
в будущих выпусках Perl (предварительно 5.10.1+), но в настоящее время его можно загрузить из CPAN для Perl 5.8.0 и выше.
В следующем выпуске autodie
будет добавлена специальная обработка вызовов на flock
с опцией LOCK_NB
(неблокирующая). Хотя неудачный вызов flock
обычно приводит к исключению в autodie
, неудачный вызов flock
с использованием LOCK_NB
просто возвращает false, если возвращаемое значение errno ($!
) равно EWOULDBLOCK
.
Причина этого в том, что люди могут продолжать писать код вроде:
use Fcntl qw(:flock);
use autodie; # All perl built-ins now succeed or die.
open(my $fh, '<', 'some_file.txt');
my $lock = flock($fh, LOCK_EX | LOCK_NB); # Lock the file if we can.
if ($lock) {
# Opportuntistically do something with the locked file.
}
В приведенном выше коде блокировка, которая завершается неудачей из-за того, что кто-то уже заблокировал файл (EWOULDBLOCK
), не считается серьезной ошибкой, поэтому автоматическое смещение flock
просто возвращает ложное значение. В ситуации, когда мы работаем с файловой системой, которая не поддерживает файловые блокировки, или с сетевой файловой системой и сетью, которая просто умерла, автоматическое смещение flock
генерирует соответствующее исключение, когда он видит, что наше errno не EWOULDBLOCK
.
Это прекрасно работает в моей версии для разработчиков на Unix-системах, но в Windows происходит ужасно. Похоже, что хотя Perl под Windows поддерживает параметр LOCK_NB
, он не определяет EWOULDBLOCK
. Вместо этого возвращается errno 33 («Ошибка домена»), когда происходит блокировка.
Очевидно, я могу жестко закодировать это как константу в autodie
, но это не то, что я хочу здесь сделать, потому что это означает, что я облажался, если ошибка когда-либо изменится (или изменилась). Я бы с удовольствием сравнил его с Windows-эквивалентом POSIX::EWOULDBLOCK
, но не могу на всю жизнь найти, где такая вещь будет определена. Если вы можете помочь, дайте мне знать.
Ответы, которые я специально не хочу:
- Предложения жестко закодировать его как константу (или, что еще хуже, оставить магическое число плавающим).
- Не поддерживает
LOCK_NB
функциональность вообще под Windows.
- Предполагая, что любой сбой от
LOCK_NB
вызова flock
должен возвращать просто ложь.
- Предложения, которые я спрашиваю на p5p или perlmonks . Я уже знаю о них.
- Объяснение того, как
flock
, или исключения, или Fatal
работают. Я уже знаю. Тесно.