【发布时间】:2010-09-12 23:42:00
【问题描述】:
G'day Stackoverflowers,
我是 Perl 的autodie pragma 的作者,它改变了 Perl 的内置函数,在失败时抛出异常。它类似于Fatal,但具有词法范围、可扩展的异常模型、更智能的返回检查以及更好的错误消息。它将在 Perl 的未来版本(临时 5.10.1+)中替换 Fatal 模块,但目前可以从 Perl 5.8.0 及更高版本的 CPAN 下载。
autodie 的下一个版本将使用LOCK_NB(非阻塞)选项添加对flock 的调用的特殊处理。虽然失败的flock 调用通常会导致autodie 下的异常,但如果返回的错误号($!)是EWOULDBLOCK,使用LOCK_NB 调用flock 失败只会返回false。
这样做的原因是人们可以继续编写如下代码:
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 仅返回一个 false 值。在我们正在使用不支持文件锁的文件系统或网络文件系统并且网络刚刚死机的情况下,当看到我们的 errno 不是 EWOULDBLOCK 时,自动染色 flock 会生成一个适当的异常.
这在我的 Unix 风格系统上的开发版本中运行良好,但在 Windows 下却严重失败。看起来虽然 Windows 下的 Perl 支持 LOCK_NB 选项,但它没有定义 EWOULDBLOCK。相反,当阻塞发生时,返回的 errno 是 33(“域错误”)。
显然我可以将它作为一个常量硬编码到autodie 中,但这不是我想要在这里做的,因为这意味着如果 errno 改变(或已经改变),我会搞砸的。我很想将它与POSIX::EWOULDBLOCK 的 Windows 等效项进行比较,但我终其一生都无法找到这样的定义。如果你能帮忙,请告诉我。
我特别不想要的答案:
- 建议将其硬编码为常量(或者更糟糕的是,留下一个浮动的幻数)。
- 在 Windows 下根本不支持
LOCK_NB功能。 - 假设从
LOCK_NB调用到flock的任何失败都应仅返回 false。 - 我在 p5p 或 perlmonks 上提出的建议。我已经知道他们了。
- 解释
flock、异常或Fatal如何工作。我已经知道了。亲密无间。
【问题讨论】:
标签: windows perl magic-numbers errno