Skip to content

Commit

Permalink
Use the new performInWorker to execute blocking I/O.
Browse files Browse the repository at this point in the history
Avoids using std.concurrency, which leaks TaskCondition instances to the GC.
  • Loading branch information
s-ludwig committed Dec 18, 2023
1 parent f665bd1 commit 73cf761
Showing 1 changed file with 10 additions and 33 deletions.
43 changes: 10 additions & 33 deletions source/vibe/core/file.d
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ void moveFile(NativePath from, NativePath to, bool copy_fallback = false)
/// ditto
void moveFile(string from, string to, bool copy_fallback = false)
{
auto fail = performInWorker((string from, string to) {
auto fail = performInIOWorker((string from, string to) {
try {
std.file.rename(from, to);
} catch (Exception e) {
Expand Down Expand Up @@ -287,7 +287,7 @@ void removeFile(NativePath path)
/// ditto
void removeFile(string path)
{
auto fail = performInWorker((string path) {
auto fail = performInIOWorker((string path) {
try {
std.file.remove(path);
} catch (Exception e) {
Expand All @@ -309,7 +309,7 @@ bool existsFile(NativePath path) nothrow
/// ditto
bool existsFile(string path) nothrow
{
try return performInWorker((string p) => std.file.exists(p), path);
try return performInIOWorker((string p) => std.file.exists(p), path);
catch (Exception e) {
logDebug("Failed to determine file existence for '%s': %s", path, e.msg);
return false;
Expand All @@ -329,7 +329,7 @@ FileInfo getFileInfo(string path)
{
import std.typecons : tuple;

auto ret = performInWorker((string p) {
auto ret = performInIOWorker((string p) {
try {
auto ent = DirEntry(p);
return tuple(makeFileInfo(ent), "");
Expand Down Expand Up @@ -428,7 +428,7 @@ void createDirectory(NativePath path, Flag!"recursive" recursive)
/// ditto
void createDirectory(string path, Flag!"recursive" recursive = No.recursive)
{
auto fail = performInWorker((string p, bool rec) {
auto fail = performInIOWorker((string p, bool rec) {
try {
if (rec) mkdirRecurse(p);
else mkdir(p);
Expand Down Expand Up @@ -472,7 +472,7 @@ void listDirectory(NativePath path, DirectoryListMode mode,
req.directoryPredicate = directory_predicate;

// NOTE: working around bogus "assigning scope variable warning on DMD 2.101.2 here with @trusted
ioWorkerTaskPool.runTask(ioTaskSettings, &performListDirectory, () @trusted { return req; } ());
ioWorkerTaskPool.runTask(&performListDirectory, () @trusted { return req; } ());

ListDirectoryData itm;
while (req.channel.tryConsumeOne(itm)) {
Expand Down Expand Up @@ -1026,32 +1026,11 @@ unittest {
}


private auto performInWorker(C, ARGS...)(C callable, auto ref ARGS args)
private auto performInIOWorker(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 : ioWorkerTaskPool;
import core.atomic : atomicFence;
import std.concurrency : Tid, send, receiveOnly, thisTid;

struct R {}

alias RET = typeof(callable(args));
shared(RET) ret;
ioWorkerTaskPool.runTask(ioTaskSettings, (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;
}
import vibe.core.concurrency : performInWorker;
import vibe.core.core : ioWorkerTaskPool;
return performInWorker(ioWorkerTaskPool, callable, args);
}

private void performListDirectory(ListDirectoryRequest req)
Expand Down Expand Up @@ -1261,8 +1240,6 @@ version (Posix) {
}
}

private immutable TaskSettings ioTaskSettings = { priority: 20 * Task.basePriority };

private struct ListDirectoryData {
FileInfo info;
string error;
Expand Down

0 comments on commit 73cf761

Please sign in to comment.