Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

fs: cleanup requests after completion

  • Loading branch information...
commit 4b6031bda3cbdaaebe6926535f6379110c33a25b 1 parent 1f8f5db
@indutny authored
Showing with 76 additions and 13 deletions.
  1. +49 −0 lib/fs.can
  2. +27 −13 src/bindings/fs.cc
View
49 lib/fs.can
@@ -3,6 +3,55 @@ exports = {}
fs = global._bindings.fs
buffer = global._bindings.buffer
+exports.open = fs.open
+exports.close = fs.close
+exports.read = fs.read
+exports.write = fs.write
+
+exports.readFile = (filename, callback) {
+ fs.stat(filename, (err, stat) {
+ if (err) return callback(err)
+
+ buffs = []
+ buff_len = 0
+ total = 0
+ size = stat.size
+
+ onOpen(fd) {
+ if (size == 0) {
+ fs.close(fd, () {})
+
+ callback(nil, buffer.concat(buffs, total))
+ }
+
+ buff = buffer.new(size)
+ fs.read(fd, buff, size, -1, (err, bytesRead) {
+ if (bytesRead != size) {
+ size = 0
+ }
+ if (bytesRead == 0) return onOpen(fd)
+
+ buffs[buff_len++] = buff
+ total = total + bytesRead
+
+ if (bytesRead == size) {
+ size = 8 * 1024
+ } else {
+ size = 0
+ }
+
+ onOpen(fd)
+ })
+ }
+
+ fs.open(filename, fs.flags.O_RDONLY, 438, (err, fd) {
+ if (err) return callback(err)
+
+ onOpen(fd, stat)
+ })
+ })
+}
+
exports.readFileSync = (filename) {
stat = fs.stat(filename)
if (stat == nil) return
View
40 src/bindings/fs.cc
@@ -12,14 +12,26 @@ using namespace candor;
const int FSWrap::magic = 0;
+// This struct is only used on sync fs calls.
+// For async calls FSWrap is used.
+struct fs_req_wrap {
+ fs_req_wrap() {}
+ ~fs_req_wrap() { uv_fs_req_cleanup(&req); }
+ // Ensure that copy ctor and assignment operator are not used.
+ fs_req_wrap(const fs_req_wrap& req);
+ fs_req_wrap& operator=(const fs_req_wrap& req);
+ uv_fs_t req;
+};
+
#define SYNC_CALL(method, ...) \
- uv_fs_t _req; \
- _req.result = uv_fs_##method(uv_default_loop(), \
- &_req, \
- __VA_ARGS__, \
- NULL);
+ fs_req_wrap _req; \
+ int _req_res = uv_fs_##method(uv_default_loop(), \
+ &_req.req, \
+ __VA_ARGS__, \
+ NULL);
-#define SYNC_REQ (&_req)
+#define SYNC_REQ_RES (_req_res)
+#define SYNC_REQ (&_req.req)
#define ASYNC_CALL(method, cb, ...) \
FSWrap* wrap = new FSWrap(cb); \
@@ -45,6 +57,7 @@ FSWrap::FSWrap(Function* cb) : CWrapper(&magic), cb_(cb) {
FSWrap::~FSWrap() {
cb_.Unref();
if (req_ == NULL) return;
+ uv_fs_req_cleanup(req_);
delete req_;
}
@@ -52,8 +65,9 @@ FSWrap::~FSWrap() {
Object* FSWrap::GetStatObject(uv_fs_t* req) {
Object* res = Object::New();
- assert(req->fs_type == UV_FS_STAT);
- uv_statbuf_t* s = reinterpret_cast<uv_statbuf_t*>(req->ptr);
+ assert(req->fs_type == UV_FS_STAT ||
+ req->fs_type == UV_FS_LSTAT);
+ uv_statbuf_t* s = &req->statbuf;
res->Set("uid", Number::NewIntegral(s->st_uid));
res->Set("gid", Number::NewIntegral(s->st_gid));
@@ -120,7 +134,7 @@ Value* FS::Open(uint32_t argc, Value** argv) {
SYNC_CALL(open, path, flags, mode);
delete[] path;
- return Number::NewIntegral(SYNC_REQ->result);
+ return Number::NewIntegral(SYNC_REQ_RES);
}
}
@@ -139,7 +153,7 @@ Value* FS::Close(uint32_t argc, Value** argv) {
return Nil::New();
} else {
SYNC_CALL(close, fd);
- return Number::NewIntegral(SYNC_REQ->result);
+ return Number::NewIntegral(SYNC_REQ_RES);
}
}
@@ -167,7 +181,7 @@ Value* FS::Read(uint32_t argc, Value** argv) {
return Nil::New();
} else {
SYNC_CALL(read, fd, buff->data(), len, offset);
- return Number::NewIntegral(SYNC_REQ->result);
+ return Number::NewIntegral(SYNC_REQ_RES);
}
}
@@ -195,7 +209,7 @@ Value* FS::Write(uint32_t argc, Value** argv) {
return Nil::New();
} else {
SYNC_CALL(write, fd, buff->data(), len, offset);
- return Number::NewIntegral(SYNC_REQ->result);
+ return Number::NewIntegral(SYNC_REQ_RES);
}
}
@@ -218,7 +232,7 @@ Value* FS::Stat(uint32_t argc, Value** argv) {
SYNC_CALL(stat, path);
delete[] path;
- if (SYNC_REQ->result) return Nil::New();
+ if (SYNC_REQ_RES) return Nil::New();
return FSWrap::GetStatObject(SYNC_REQ);
}
Please sign in to comment.
Something went wrong with that request. Please try again.