Remove potentially blocking file I/O code (upgrade to eventcore 0.9.0).
- file and pipe closing are now asynchronous operations - moveFile and removeFile are now executed in a worker thread - requires eventcore ~>0.9.0
This commit is contained in:
parent
d1340f9e10
commit
a4e87237e4
2
dub.sdl
2
dub.sdl
|
@ -4,7 +4,7 @@ authors "Sönke Ludwig"
|
|||
copyright "Copyright © 2016-2020, Sönke Ludwig"
|
||||
license "MIT"
|
||||
|
||||
dependency "eventcore" version="~>0.8.43"
|
||||
dependency "eventcore" version="~>0.9.0"
|
||||
dependency "stdx-allocator" version="~>2.77.0"
|
||||
|
||||
targetName "vibe_core"
|
||||
|
|
|
@ -190,16 +190,21 @@ void moveFile(NativePath from, NativePath to, bool copy_fallback = false)
|
|||
/// ditto
|
||||
void moveFile(string from, string to, bool copy_fallback = false)
|
||||
{
|
||||
if (!copy_fallback) {
|
||||
std.file.rename(from, to);
|
||||
} else {
|
||||
auto fail = performInWorker((string from, string to) {
|
||||
try {
|
||||
std.file.rename(from, to);
|
||||
} catch (FileException e) {
|
||||
copyFile(from, to);
|
||||
std.file.remove(from);
|
||||
} catch (Exception e) {
|
||||
return e.msg.length ? e.msg : "Failed to move file.";
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}, from, to);
|
||||
|
||||
if (!fail.length) return;
|
||||
|
||||
if (!copy_fallback) throw new Exception(fail);
|
||||
|
||||
copyFile(from, to);
|
||||
removeFile(from);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -236,6 +241,7 @@ void copyFile(NativePath from, NativePath to, bool overwrite = false)
|
|||
enforce(overwrite || !existsFile(to), "Destination file already exists.");
|
||||
auto dst = openFile(to, FileMode.createTrunc);
|
||||
scope(exit) dst.close();
|
||||
dst.truncate(src.size);
|
||||
dst.write(src);
|
||||
}
|
||||
|
||||
|
@ -267,7 +273,16 @@ void removeFile(NativePath path)
|
|||
/// ditto
|
||||
void removeFile(string path)
|
||||
{
|
||||
std.file.remove(path);
|
||||
auto fail = performInWorker((string path) {
|
||||
try {
|
||||
std.file.remove(path);
|
||||
} catch (Exception e) {
|
||||
return e.msg.length ? e.msg : "Failed to delete file.";
|
||||
}
|
||||
return null;
|
||||
}, path);
|
||||
|
||||
if (fail.length) throw new Exception(fail);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -567,12 +582,18 @@ struct FileStream {
|
|||
/// Closes the file handle.
|
||||
void close()
|
||||
{
|
||||
if (m_fd != FileFD.init) {
|
||||
eventDriver.files.close(m_fd); // FIXME: may leave dangling references!
|
||||
releaseHandle!"files"(m_fd, m_ctx.driver);
|
||||
m_fd = FileFD.init;
|
||||
m_ctx = null;
|
||||
}
|
||||
if (m_fd == FileFD.invalid) return;
|
||||
if (!eventDriver.files.isValid(m_fd)) return;
|
||||
|
||||
auto res = asyncAwaitUninterruptible!(FileCloseCallback,
|
||||
cb => eventDriver.files.close(m_fd, cb)
|
||||
);
|
||||
releaseHandle!"files"(m_fd, m_ctx.driver);
|
||||
m_fd = FileFD.invalid;
|
||||
m_ctx = null;
|
||||
|
||||
if (res[1] != CloseStatus.ok)
|
||||
throw new Exception("Failed to close file");
|
||||
}
|
||||
|
||||
@property bool empty() const { assert(this.readable); return ctx.ptr >= ctx.size; }
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
module vibe.core.internal.release;
|
||||
|
||||
import eventcore.core;
|
||||
import std.stdint : intptr_t;
|
||||
|
||||
/// Release a handle in a thread-safe way
|
||||
void releaseHandle(string subsys, H)(H handle, shared(NativeEventDriver) drv)
|
||||
|
@ -19,8 +20,8 @@ void releaseHandle(string subsys, H)(H handle, shared(NativeEventDriver) drv)
|
|||
|
||||
// in case the destructor was called from a foreign thread,
|
||||
// perform the release in the owner thread
|
||||
drv.core.runInOwnerThread((h) {
|
||||
__traits(getMember, eventDriver, subsys).releaseRef(cast(H)h);
|
||||
}, cast(size_t)handle);
|
||||
drv.core.runInOwnerThread((H handle) {
|
||||
__traits(getMember, eventDriver, subsys).releaseRef(handle);
|
||||
}, handle);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -453,7 +453,14 @@ struct PipeInputStream {
|
|||
*/
|
||||
void close()
|
||||
nothrow {
|
||||
eventDriver.pipes.close(m_pipe);
|
||||
if (m_pipe == PipeFD.invalid) return;
|
||||
|
||||
asyncAwaitUninterruptible!(PipeCloseCallback,
|
||||
cb => eventDriver.pipes.close(m_pipe, cb)
|
||||
);
|
||||
|
||||
eventDriver.pipes.releaseRef(m_pipe);
|
||||
m_pipe = PipeFD.invalid;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -528,7 +535,14 @@ struct PipeOutputStream {
|
|||
*/
|
||||
void close()
|
||||
nothrow {
|
||||
eventDriver.pipes.close(m_pipe);
|
||||
if (m_pipe == PipeFD.invalid) return;
|
||||
|
||||
asyncAwaitUninterruptible!(PipeCloseCallback,
|
||||
cb => eventDriver.pipes.close(m_pipe, cb)
|
||||
);
|
||||
|
||||
eventDriver.pipes.releaseRef(m_pipe);
|
||||
m_pipe = PipeFD.invalid;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue