aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorOmar Rizwan <omar.rizwan@gmail.com>2018-11-29 09:53:03 -0800
committerOmar Rizwan <omar.rizwan@gmail.com>2018-11-29 09:53:03 -0800
commit90181466bd12553abef43f165b7b8a2c7ad2f1c3 (patch)
tree32b78ae0aa0e9b85acce2aa28c569b95815aeecf /fs
parented5419ae41747a7a6b0597f0f100f71057898cb3 (diff)
Add opendir/releasedir support. Relieve ws thread CPU usage.
Diffstat (limited to 'fs')
-rw-r--r--fs/hello.c113
1 files changed, 92 insertions, 21 deletions
diff --git a/fs/hello.c b/fs/hello.c
index 66985e2..bb6a7b1 100644
--- a/fs/hello.c
+++ b/fs/hello.c
@@ -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);
-
}