Вопрос

Добрый день, Stackoverflowers,

Я автор Perl автоумирание прагма, которая изменяет встроенные функции Perl, чтобы они выдавали исключения в случае сбоя.Это похоже на Фатальный, но с лексической областью видимости, расширяемой моделью исключений, более интеллектуальной проверкой возврата и гораздо более приятными сообщениями об ошибках.Он будет заменять 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 генерирует соответствующее исключение, когда видит, что наша ошибка не является EWOULDBLOCK.

Это прекрасно работает в моей версии для разработчиков в системах с поддержкой Unix, но ужасно не работает под Windows.Похоже, что хотя Perl под Windows поддерживает LOCK_NB опция, она не определяет EWOULDBLOCK.Вместо этого при возникновении блокировки возвращается ошибка 33 («Ошибка домена»).

Очевидно, я могу жестко запрограммировать это как константу в autodie, но это не то, что я хочу здесь делать, потому что это означает, что я облажался, если ошибка когда-либо изменится (или изменилась).Я хотел бы сравнить его с эквивалентом Windows POSIX::EWOULDBLOCK, но я не могу хоть убей найти, где бы такая вещь была определена.Если вы можете помочь, дайте мне знать.

Ответы, которые мне конкретно не нужны:

  • Предложения жестко запрограммировать его как константу (или, что еще хуже, оставить плавающее магическое число).
  • Не поддерживает LOCK_NB функциональность вообще под Windows.
  • Предполагая, что любой отказ от LOCK_NB позвонить flock должен возвращать просто false.
  • Предложения, которые я задаю на p5p или Перлмонкс.Я уже знаю о них.
  • Объяснение того, как flock, или исключения, или Fatal работа.Я уже знаю.Интимно.
Это было полезно?

Решение

Обратите внимание, что в «родном» Perl Win32 $^E имеет более наглядное значение 33: «Процесс не может получить доступ к файлу, потому что другой процесс заблокировал часть файла», что ERROR_LOCK_VIOLATION (Доступна с Win32::WinError).

Другие советы

Для кода ошибки, специфичного для Windows, вы хотите использовать $^E.В данном случае это 33:"Процесс не может получить доступ к файлу, поскольку другой процесс заблокировал часть файла" (ERROR_LOCK_VIOLATION в winerror.h).

К сожалению, я не думаю Win32::WinError находится в ядре.С другой стороны, если бы Microsoft когда-нибудь изменила нумерацию кодов ошибок Windows, почти каждая когда-либо написанная программа для Windows перестанет работать, поэтому я не думаю, что возникнут проблемы с ее жестким кодированием.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top