aboutsummaryrefslogtreecommitdiff
path: root/src/kernel/user/ipc.c
diff options
context:
space:
mode:
authorAlex Auvolat <alex.auvolat@ens.fr>2015-03-08 19:07:48 +0100
committerAlex Auvolat <alex.auvolat@ens.fr>2015-03-08 19:07:48 +0100
commit6dd488b87fdc47fb377ba648a6cd598bdab87f59 (patch)
tree2e69225353054eb43a9869af4ca9766a0f39c828 /src/kernel/user/ipc.c
parentbcee004478c6448541ce583e75c706e185190800 (diff)
downloadkogata-6dd488b87fdc47fb377ba648a6cd598bdab87f59.tar.gz
kogata-6dd488b87fdc47fb377ba648a6cd598bdab87f59.zip
Implement select ; add two tests for channels.
Diffstat (limited to 'src/kernel/user/ipc.c')
-rw-r--r--src/kernel/user/ipc.c22
1 files changed, 21 insertions, 1 deletions
diff --git a/src/kernel/user/ipc.c b/src/kernel/user/ipc.c
index 648fdf2..dce1847 100644
--- a/src/kernel/user/ipc.c
+++ b/src/kernel/user/ipc.c
@@ -11,6 +11,7 @@
static size_t channel_read(fs_handle_t *c, size_t offset, size_t len, char* buf);
static size_t channel_write(fs_handle_t *c, size_t offset, size_t len, const char* buf);
+static int channel_poll(fs_handle_t *c, void** out_wait_obj);
static bool channel_stat(fs_node_ptr c, stat_t *st);
static void channel_close(fs_handle_t *c);
@@ -18,6 +19,7 @@ static fs_node_ops_t channel_ops = {
.read = channel_read,
.write = channel_write,
.close = channel_close,
+ .poll = channel_poll,
.open = 0,
.readdir = 0,
.ioctl = 0,
@@ -157,6 +159,20 @@ size_t channel_write(fs_handle_t *h, size_t offset, size_t req_len, const char*
return ret;
}
+int channel_poll(fs_handle_t *h, void** out_wait_obj) {
+ channel_t *c = (channel_t*)h->data;
+
+ int ret = 0;
+
+ if (c->other_side == 0) ret |= SEL_ERROR;
+ if (c->other_side && c->other_side->buf_used < CHANNEL_BUFFER_SIZE) ret |= SEL_WRITE;
+ if (c->buf_used > 0) ret |= SEL_READ;
+
+ if (out_wait_obj) *out_wait_obj = c;
+
+ return ret;
+}
+
bool channel_stat(fs_node_ptr ch, stat_t *st) {
channel_t *c = (channel_t*)ch;
@@ -176,7 +192,11 @@ void channel_close(fs_handle_t *ch) {
mutex_lock(&c->lock);
- c->other_side->other_side = 0;
+ if (c->other_side) {
+ resume_on(c->other_side);
+ c->other_side->other_side = 0;
+ }
+
free(c);
}