Fix getFileInfo's exception handling and reduce overhead of the background work.
Instead of asyncWork, now uses a worker task directly and signals the finalization of the result using message passing. This avoids the roundtrip required to return the task handle, as well as the heap allocated result buffer of Future!T.
This commit is contained in:
parent
d7dfb6cd23
commit
d9e545bf60
|
@ -7,7 +7,6 @@
|
||||||
*/
|
*/
|
||||||
module vibe.core.file;
|
module vibe.core.file;
|
||||||
|
|
||||||
import vibe.core.concurrency : asyncWork;
|
|
||||||
import eventcore.core : NativeEventDriver, eventDriver;
|
import eventcore.core : NativeEventDriver, eventDriver;
|
||||||
import eventcore.driver;
|
import eventcore.driver;
|
||||||
import vibe.core.internal.release;
|
import vibe.core.internal.release;
|
||||||
|
@ -282,7 +281,7 @@ bool existsFile(string path) nothrow
|
||||||
static if (__VERSION__ < 2067)
|
static if (__VERSION__ < 2067)
|
||||||
scope(failure) assert(0, "Error: existsFile should never throw");
|
scope(failure) assert(0, "Error: existsFile should never throw");
|
||||||
|
|
||||||
try return asyncWork((string p) => std.file.exists(p), path).getResult();
|
try return performInWorker((string p) => std.file.exists(p), path);
|
||||||
catch (Exception e) {
|
catch (Exception e) {
|
||||||
logDebug("Failed to determine file existence for '%s': %s", path, e.msg);
|
logDebug("Failed to determine file existence for '%s': %s", path, e.msg);
|
||||||
return false;
|
return false;
|
||||||
|
@ -300,10 +299,18 @@ FileInfo getFileInfo(NativePath path)
|
||||||
/// ditto
|
/// ditto
|
||||||
FileInfo getFileInfo(string path)
|
FileInfo getFileInfo(string path)
|
||||||
{
|
{
|
||||||
return asyncWork((string p) {
|
import std.typecons : tuple;
|
||||||
auto ent = DirEntry(p);
|
|
||||||
return makeFileInfo(ent);
|
auto ret = performInWorker((string p) {
|
||||||
}, path).getResult();
|
try {
|
||||||
|
auto ent = DirEntry(p);
|
||||||
|
return tuple(makeFileInfo(ent), "");
|
||||||
|
} catch (Exception e) {
|
||||||
|
return tuple(FileInfo.init, e.msg.length ? e.msg : "Failed to get file information");
|
||||||
|
}
|
||||||
|
}, path);
|
||||||
|
if (ret[1].length) throw new Exception(ret[1]);
|
||||||
|
return ret[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -316,7 +323,7 @@ void createDirectory(NativePath path)
|
||||||
/// ditto
|
/// ditto
|
||||||
void createDirectory(string path, Flag!"recursive" recursive = No.recursive)
|
void createDirectory(string path, Flag!"recursive" recursive = No.recursive)
|
||||||
{
|
{
|
||||||
auto fail = asyncWork((string p, bool rec) {
|
auto fail = performInWorker((string p, bool rec) {
|
||||||
try {
|
try {
|
||||||
if (rec) mkdirRecurse(p);
|
if (rec) mkdirRecurse(p);
|
||||||
else mkdir(p);
|
else mkdir(p);
|
||||||
|
@ -870,3 +877,32 @@ unittest {
|
||||||
|
|
||||||
assert(readFile(name) == "create, then append");
|
assert(readFile(name) == "create, then append");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private auto performInWorker(C, ARGS...)(C callable, auto ref ARGS args)
|
||||||
|
{
|
||||||
|
version (none) {
|
||||||
|
import vibe.core.concurrency : asyncWork;
|
||||||
|
return asyncWork(callable, args).getResult();
|
||||||
|
} else {
|
||||||
|
import vibe.core.core : runWorkerTask;
|
||||||
|
import core.atomic : atomicFence;
|
||||||
|
import std.concurrency : Tid, send, receiveOnly, thisTid;
|
||||||
|
|
||||||
|
struct R {}
|
||||||
|
|
||||||
|
alias RET = typeof(callable(args));
|
||||||
|
shared(RET) ret;
|
||||||
|
runWorkerTask((shared(RET)* r, Tid caller, C c, ref ARGS a) nothrow {
|
||||||
|
*() @trusted { return cast(RET*)r; } () = c(a);
|
||||||
|
// Just as a precaution, because ManualEvent is not well defined in
|
||||||
|
// terms of fence semantics
|
||||||
|
atomicFence();
|
||||||
|
try caller.send(R.init);
|
||||||
|
catch (Exception e) assert(false, e.msg);
|
||||||
|
}, () @trusted { return &ret; } (), thisTid, callable, args);
|
||||||
|
() @trusted { receiveOnly!R(); } ();
|
||||||
|
atomicFence();
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue