Добрый день, Stackoverflowers,
Я являюсь автором прагмы Perl autodie, которая изменяет встроенные модули 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
. Вместо этого возвращается ошибка 33 («Ошибка домена»), когда может произойти блокировка.
Очевидно, я могу жестко закодировать это как константу в autodie
, но это не то, что я хочу делать здесь, потому что это означает, что я облажался, если errno когда-либо изменится (или изменился). Я хотел бы сравнить его с Windows-эквивалентом POSIX::EWOULDBLOCK
, но я не могу найти, где такая вещь может быть определена. Если вы можете помочь, дайте мне знать.
Ответы, которых я конкретно не хочу:
- Предложения жестко закодировать его как константу (или, что еще хуже, оставить плавающее магическое число).
- Совсем не поддерживает функциональность
LOCK_NB
под Windows. - Предполагая, что любой сбой от вызова
LOCK_NB
кflock
должен возвращать просто false. - Предложения, которые я прошу на p5p или perlmonks. Я уже знаю о них.
- Объяснение того, как работает
flock
, исключения илиFatal
. Я уже знаю. Интимно.