Dokany find files fix (#51)

* call filler async

* support multiple files

* fix formatting
Marinko 7 years ago committed by Mathias Buus
parent 627e708064
commit 032ed16e23

@ -88,6 +88,7 @@ struct bindings_t {
char mntopts[1024];
abstr_thread_t thread;
bindings_sem_t semaphore;
bindings_sem_t semaphore_readdir;
uv_async_t async;
// methods
@ -191,12 +192,21 @@ NAN_INLINE v8::Local<v8::Object> bindings_buffer (char *data, size_t length) {
}
#endif
NAN_INLINE static int bindings_call (bindings_t *b) {
NAN_INLINE static int bindings_call_ex (bindings_t *b, bool isreaddir) {
uv_async_send(&(b->async));
semaphore_wait(&(b->semaphore));
if (isreaddir) {
semaphore_wait(&(b->semaphore_readdir));
} else {
semaphore_wait(&(b->semaphore));
}
return b->result;
}
NAN_INLINE static int bindings_call (bindings_t *b) {
return bindings_call_ex(b, false);
}
static bindings_t *bindings_get_context () {
fuse_context *ctx = fuse_get_context();
bindings_t *b = (bindings_t *) ctx->private_data;
@ -299,7 +309,7 @@ static int bindings_readdir (const char *path, void *buf, fuse_fill_dir_t filler
b->data = buf;
b->filler = filler;
return bindings_call(b);
return bindings_call_ex(b, true);
}
static int bindings_readlink (const char *path, char *buf, size_t len) {
@ -413,7 +423,7 @@ static int bindings_removexattr (const char *path, const char *name) {
static int bindings_statfs (const char *path, struct statvfs *statfs) {
bindings_t *b = bindings_get_context();
b->op = OP_STATFS;
b->path = (char *) path;
b->data = statfs;
@ -772,19 +782,38 @@ NAN_INLINE static void bindings_set_statfs (struct statvfs *statfs, Local<Object
if (obj->Has(LOCAL_STRING("namemax"))) statfs->f_namemax = obj->Get(LOCAL_STRING("namemax"))->Uint32Value();
}
NAN_INLINE static void bindings_set_dirs (bindings_t *b, Local<Array> dirs) {
Nan::HandleScope scope;
for (uint32_t i = 0; i < dirs->Length(); i++) {
Nan::Utf8String dir(dirs->Get(i));
if (b->filler(b->data, *dir, &empty_stat, 0)) break;
class SetDirWorker : public Nan::AsyncWorker {
public:
SetDirWorker(bindings_t *b, char **dirs, int dirs_length)
: Nan::AsyncWorker(NULL), b(b), dirs(dirs), dirs_length(dirs_length) {}
~SetDirWorker() {}
void Execute () {
fuse_fill_dir_t fillerToCall = b->filler;
void *data = b->data;
for (int i = 0; i < dirs_length; i++) {
fillerToCall(data, dirs[i], &empty_stat, 0);
}
}
}
void WorkComplete(){
semaphore_signal(&(b->semaphore_readdir));
for (int i = 0; i < dirs_length; i++) {
free(dirs[i]);
}
free(dirs);
}
private:
bindings_t *b;
char **dirs;
int dirs_length;
};
NAN_METHOD(OpCallback) {
bindings_t *b = bindings_mounted[info[0]->Uint32Value()];
b->result = (info.Length() > 1 && info[1]->IsNumber()) ? info[1]->Uint32Value() : 0;
bindings_current = NULL;
if (!b->result) {
switch (b->op) {
case OP_STATFS: {
@ -799,7 +828,22 @@ NAN_METHOD(OpCallback) {
break;
case OP_READDIR: {
if (info.Length() > 2 && info[2]->IsArray()) bindings_set_dirs(b, info[2].As<Array>());
if (info.Length() > 2 && info[2]->IsArray()) {
Local<Array> dirs = info[2].As<Array>();
char **dirs_alloc = (char**)malloc(sizeof(char*)*dirs->Length());
for (uint32_t i = 0; i < dirs->Length(); i++) {
Nan::Utf8String dir(dirs->Get(i));
dirs_alloc[i] = (char *) malloc(1024);
strcpy(dirs_alloc[i], *dir);
}
Nan::AsyncQueueWorker(new SetDirWorker(b, dirs_alloc, dirs->Length()));
return;
}
}
break;
@ -854,14 +898,25 @@ NAN_METHOD(OpCallback) {
semaphore_signal(&(b->semaphore));
}
NAN_INLINE static void bindings_call_op_ex (bindings_t *b, Nan::Callback *fn, int argc, Local<Value> *argv, bool isreaddir) {
if (fn == NULL){
if (isreaddir) {
semaphore_signal(&(b->semaphore_readdir));
} else {
semaphore_signal(&(b->semaphore));}
}
else {
fn->Call(argc, argv);
}
}
NAN_INLINE static void bindings_call_op (bindings_t *b, Nan::Callback *fn, int argc, Local<Value> *argv) {
if (fn == NULL) semaphore_signal(&(b->semaphore));
else fn->Call(argc, argv);
bindings_call_op_ex(b, fn, argc, argv, false);
}
static void bindings_dispatch (uv_async_t* handle, int status) {
Nan::HandleScope scope;
bindings_t *b = bindings_current = (bindings_t *) handle->data;
Local<Function> callback = b->callback->GetFunction();
b->result = -1;
@ -899,7 +954,7 @@ static void bindings_dispatch (uv_async_t* handle, int status) {
case OP_READDIR: {
Local<Value> tmp[] = {LOCAL_STRING(b->path), callback};
bindings_call_op(b, b->ops_readdir, 2, tmp);
bindings_call_op_ex(b, b->ops_readdir, 2, tmp, true);
}
return;
@ -1211,6 +1266,7 @@ NAN_METHOD(Mount) {
}
semaphore_init(&(b->semaphore));
semaphore_init(&(b->semaphore_readdir));
uv_async_init(uv_default_loop(), &(b->async), (uv_async_cb) bindings_dispatch);
b->async.data = b;

Loading…
Cancel
Save