diff options
author | Omar Rizwan <omar.rizwan@gmail.com> | 2018-11-29 09:53:03 -0800 |
---|---|---|
committer | Omar Rizwan <omar.rizwan@gmail.com> | 2018-11-29 09:53:03 -0800 |
commit | 90181466bd12553abef43f165b7b8a2c7ad2f1c3 (patch) | |
tree | 32b78ae0aa0e9b85acce2aa28c569b95815aeecf /fs | |
parent | ed5419ae41747a7a6b0597f0f100f71057898cb3 (diff) |
Add opendir/releasedir support. Relieve ws thread CPU usage.
Diffstat (limited to 'fs')
-rw-r--r-- | fs/hello.c | 113 |
1 files changed, 92 insertions, 21 deletions
@@ -63,6 +63,7 @@ static request_id enqueue_request(cJSON *req) { /* printf("%s\n", queue[id].request); */ + pthread_cond_signal(&queue_cv); pthread_mutex_unlock(&queue_mutex); return id; @@ -164,32 +165,32 @@ hello_getattr(const char *path, struct stat *stbuf) } static int -hello_open(const char *path, struct fuse_file_info *fi) +hello_readlink(const char *path, char *buf, size_t size) { - MAKE_REQ("open", { + MAKE_REQ("readlink", { cJSON_AddStringToObject(req, "path", path); - cJSON_AddNumberToObject(req, "flags", fi->flags); }, { - cJSON *fh_item = cJSON_GetObjectItemCaseSensitive(resp, "fh"); - if (fh_item) fi->fh = fh_item->valueint; + cJSON *resp_buf_item = cJSON_GetObjectItemCaseSensitive(resp, "buf"); + // FIXME: fix + char *resp_buf = cJSON_GetStringValue(resp_buf_item); + size_t resp_buf_len = strlen(resp_buf); + size = resp_buf_len < size ? resp_buf_len : size; - ret = 0; + memcpy(buf, resp_buf, size); + + ret = size; }); } static int -hello_readdir(const char *path, void *buf, fuse_fill_dir_t filler, - off_t offset, struct fuse_file_info *fi) +hello_open(const char *path, struct fuse_file_info *fi) { - // send {op: "readdir", path} to the websocket handler - MAKE_REQ("readdir", { + MAKE_REQ("open", { cJSON_AddStringToObject(req, "path", path); + cJSON_AddNumberToObject(req, "flags", fi->flags); }, { - cJSON *entries = cJSON_GetObjectItemCaseSensitive(resp, "entries"); - cJSON *entry; - cJSON_ArrayForEach(entry, entries) { - filler(buf, cJSON_GetStringValue(entry), NULL, 0); - } + cJSON *fh_item = cJSON_GetObjectItemCaseSensitive(resp, "fh"); + if (fh_item) fi->fh = fh_item->valueint; ret = 0; }); @@ -208,7 +209,11 @@ hello_read(const char *path, char *buf, size_t size, off_t offset, cJSON_AddNumberToObject(req, "flags", fi->flags); }, { cJSON *resp_buf_item = cJSON_GetObjectItemCaseSensitive(resp, "buf"); + if (!resp_buf_item) return -EIO; + char *resp_buf = cJSON_GetStringValue(resp_buf_item); + if (!resp_buf) return -EIO; + size_t resp_buf_len = strlen(resp_buf); size = resp_buf_len < size ? resp_buf_len : size; @@ -227,12 +232,59 @@ static int hello_release(const char *path, struct fuse_file_info *fi) { }); } +static int +hello_opendir(const char *path, struct fuse_file_info *fi) +{ + MAKE_REQ("opendir", { + cJSON_AddStringToObject(req, "path", path); + cJSON_AddNumberToObject(req, "flags", fi->flags); + }, { + cJSON *fh_item = cJSON_GetObjectItemCaseSensitive(resp, "fh"); + if (fh_item) fi->fh = fh_item->valueint; + + ret = 0; + }); +} + +static int +hello_readdir(const char *path, void *buf, fuse_fill_dir_t filler, + off_t offset, struct fuse_file_info *fi) +{ + // send {op: "readdir", path} to the websocket handler + MAKE_REQ("readdir", { + cJSON_AddStringToObject(req, "path", path); + }, { + cJSON *entries = cJSON_GetObjectItemCaseSensitive(resp, "entries"); + cJSON *entry; + cJSON_ArrayForEach(entry, entries) { + filler(buf, cJSON_GetStringValue(entry), NULL, 0); + } + + ret = 0; + }); +} + +static int +hello_releasedir(const char *path, struct fuse_file_info *fi) +{ + MAKE_REQ("releasedir", { + cJSON_AddStringToObject(req, "path", path); + cJSON_AddNumberToObject(req, "fh", fi->fh); + }, { + ret = 0; + }); +} + static struct fuse_operations hello_filesystem_operations = { - .getattr = hello_getattr, /* To provide size, permissions, etc. */ - .open = hello_open, /* To enforce read-only access. */ - .read = hello_read, /* To provide file content. */ - .release = hello_release, - .readdir = hello_readdir, /* To provide directory listing. */ + .getattr = hello_getattr, /* To provide size, permissions, etc. */ + .readlink = hello_readlink, + .open = hello_open, /* To enforce read-only access. */ + .read = hello_read, /* To provide file content. */ + .release = hello_release, + + .opendir = hello_opendir, + .readdir = hello_readdir, /* To provide directory listing. */ + .releasedir = hello_releasedir }; static int @@ -339,6 +391,24 @@ test_log(const char* text) DEBUG("[debug] %s\n", text); } +int check_io_demand() { + if (con == NULL) return 1; + + for (request_id id = 0; id < REQUEST_RESPONSE_QUEUE_SIZE; id++) { + if (queue[id].state == SEND_REQUEST || queue[id].state == RECEIVE_RESPONSE) { + return 1; + } + } + return 0; +} +void await_io_demand() { + pthread_mutex_lock(&queue_mutex); + while (!check_io_demand()) { + pthread_cond_wait(&queue_cv, &queue_mutex); + } + pthread_mutex_unlock(&queue_mutex); +} + void *websocket_main(void *threadid) { void *memory = NULL; @@ -365,6 +435,8 @@ void *websocket_main(void *threadid) printf("Awaiting WebSocket connection from Chrome extension.\n"); for (;;) { + await_io_demand(); + send_any_enqueued_requests(); wby_update(&server); @@ -384,5 +456,4 @@ main(int argc, char **argv) pthread_t websocket_thread; pthread_create(&websocket_thread, NULL, websocket_main, NULL); return fuse_main(argc, argv, &hello_filesystem_operations, NULL); - } |