public static function open($path, $flags, $cb, $mode = null, $pri = EIO_PRI_DEFAULT)
{
$cb = CallbackWrapper::forceWrap($cb);
if (!FileSystem::$supported) {
$mode = File::convertFlags($flags, true);
$fd = fopen($path, $mode);
if (!$fd) {
$cb(false);
return false;
}
$file = new File($fd, $path);
$cb($file);
return true;
}
$fdCacheKey = $path . "" . $flags;
$noncache = mb_orig_strpos($flags, '!') !== false;
$flags = File::convertFlags($flags);
if (!$noncache && ($item = FileSystem::$fdCache->get($fdCacheKey))) {
// cache hit
$file = $item->getValue();
if ($file === null) {
// operation in progress
$item->addListener($cb);
} else {
// hit
$cb($file);
}
return null;
} elseif (!$noncache) {
$item = FileSystem::$fdCache->put($fdCacheKey, null);
$item->addListener($cb);
}
return eio_open($path, $flags, $mode, $pri, function ($path, $fd) use($cb, $flags, $fdCacheKey, $noncache) {
if ($fd === -1) {
if ($noncache) {
$cb(false);
} else {
FileSystem::$fdCache->put($fdCacheKey, false, self::$badFDttl);
}
return;
}
$file = new File($fd, $path);
$file->append = ($flags | EIO_O_APPEND) === $flags;
if ($file->append) {
$file->stat(function ($file, $stat) use($cb, $noncache, $fdCacheKey) {
$file->offset = $stat['size'];
if (!$noncache) {
$file->fdCacheKey = $fdCacheKey;
FileSystem::$fdCache->put($fdCacheKey, $file);
} else {
$cb($file);
}
});
} else {
if (!$noncache) {
$file->fdCacheKey = $fdCacheKey;
FileSystem::$fdCache->put($fdCacheKey, $file);
} else {
$cb($file);
}
}
}, $path);
}