diff --git a/dub.sdl b/dub.sdl index 1dcfb87..462843c 100644 --- a/dub.sdl +++ b/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" diff --git a/source/vibe/core/file.d b/source/vibe/core/file.d index d679b22..697f439 100644 --- a/source/vibe/core/file.d +++ b/source/vibe/core/file.d @@ -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; } diff --git a/source/vibe/core/internal/release.d b/source/vibe/core/internal/release.d index 33dac9c..a99a428 100644 --- a/source/vibe/core/internal/release.d +++ b/source/vibe/core/internal/release.d @@ -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); } } diff --git a/source/vibe/core/process.d b/source/vibe/core/process.d index aa3b20b..0d0d4f8 100644 --- a/source/vibe/core/process.d +++ b/source/vibe/core/process.d @@ -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; } }