1
0
mirror of https://github.com/fuse-friends/fuse-native synced 2024-10-27 18:34:01 +00:00

Dokany find files fix (#51)

* call filler async

* support multiple files

* fix formatting
This commit is contained in:
Marinko 2017-04-02 09:30:11 +02:00 committed by Mathias Buus
parent 627e708064
commit 032ed16e23

View File

@ -88,6 +88,7 @@ struct bindings_t {
char mntopts[1024]; char mntopts[1024];
abstr_thread_t thread; abstr_thread_t thread;
bindings_sem_t semaphore; bindings_sem_t semaphore;
bindings_sem_t semaphore_readdir;
uv_async_t async; uv_async_t async;
// methods // methods
@ -191,12 +192,21 @@ NAN_INLINE v8::Local<v8::Object> bindings_buffer (char *data, size_t length) {
} }
#endif #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)); uv_async_send(&(b->async));
if (isreaddir) {
semaphore_wait(&(b->semaphore_readdir));
} else {
semaphore_wait(&(b->semaphore)); semaphore_wait(&(b->semaphore));
}
return b->result; return b->result;
} }
NAN_INLINE static int bindings_call (bindings_t *b) {
return bindings_call_ex(b, false);
}
static bindings_t *bindings_get_context () { static bindings_t *bindings_get_context () {
fuse_context *ctx = fuse_get_context(); fuse_context *ctx = fuse_get_context();
bindings_t *b = (bindings_t *) ctx->private_data; 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->data = buf;
b->filler = filler; 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) { static int bindings_readlink (const char *path, char *buf, size_t len) {
@ -772,13 +782,32 @@ 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(); 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) { class SetDirWorker : public Nan::AsyncWorker {
Nan::HandleScope scope; public:
for (uint32_t i = 0; i < dirs->Length(); i++) { SetDirWorker(bindings_t *b, char **dirs, int dirs_length)
Nan::Utf8String dir(dirs->Get(i)); : Nan::AsyncWorker(NULL), b(b), dirs(dirs), dirs_length(dirs_length) {}
if (b->filler(b->data, *dir, &empty_stat, 0)) break; ~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) { NAN_METHOD(OpCallback) {
bindings_t *b = bindings_mounted[info[0]->Uint32Value()]; bindings_t *b = bindings_mounted[info[0]->Uint32Value()];
@ -799,7 +828,22 @@ NAN_METHOD(OpCallback) {
break; break;
case OP_READDIR: { 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; break;
@ -854,9 +898,20 @@ NAN_METHOD(OpCallback) {
semaphore_signal(&(b->semaphore)); 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) { 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)); bindings_call_op_ex(b, fn, argc, argv, false);
else fn->Call(argc, argv);
} }
static void bindings_dispatch (uv_async_t* handle, int status) { static void bindings_dispatch (uv_async_t* handle, int status) {
@ -899,7 +954,7 @@ static void bindings_dispatch (uv_async_t* handle, int status) {
case OP_READDIR: { case OP_READDIR: {
Local<Value> tmp[] = {LOCAL_STRING(b->path), callback}; 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; return;
@ -1211,6 +1266,7 @@ NAN_METHOD(Mount) {
} }
semaphore_init(&(b->semaphore)); semaphore_init(&(b->semaphore));
semaphore_init(&(b->semaphore_readdir));
uv_async_init(uv_default_loop(), &(b->async), (uv_async_cb) bindings_dispatch); uv_async_init(uv_default_loop(), &(b->async), (uv_async_cb) bindings_dispatch);
b->async.data = b; b->async.data = b;