diff options
author | dimitri staessens <dimitri.staessens@intec.ugent.be> | 2016-05-12 15:08:20 +0200 |
---|---|---|
committer | dimitri staessens <dimitri.staessens@intec.ugent.be> | 2016-05-12 15:08:20 +0200 |
commit | d6f20c13da9ef1aec966f2c0594dbf47a51d340e (patch) | |
tree | 9723ba8040cfcb543dadb1ef2417e700673977b6 | |
parent | ccf989a567acc91f8559ea67d69f2b952410010b (diff) | |
download | ouroboros-d6f20c13da9ef1aec966f2c0594dbf47a51d340e.tar.gz ouroboros-d6f20c13da9ef1aec966f2c0594dbf47a51d340e.zip |
lib: dev: implementation of flow_cntl
allows setting the oflags to make flow_read and flow_write blocking or
non-blocking (FLOW_O_NONBLOCK).
-rw-r--r-- | include/ouroboros/dev.h | 2 | ||||
-rw-r--r-- | include/ouroboros/flow.h | 3 | ||||
-rw-r--r-- | src/lib/dev.c | 43 | ||||
-rw-r--r-- | src/lib/shm_ap_rbuff.c | 1 |
4 files changed, 39 insertions, 10 deletions
diff --git a/include/ouroboros/dev.h b/include/ouroboros/dev.h index e857e211..d8e65144 100644 --- a/include/ouroboros/dev.h +++ b/include/ouroboros/dev.h @@ -31,7 +31,7 @@ /* These calls should be removed once we write the ouroboros OS. */ int ap_init(char * ap_name); -void ap_fini(); +void ap_fini(void); /* Returns file descriptor */ int ap_reg(char ** difs, size_t difs_size); diff --git a/include/ouroboros/flow.h b/include/ouroboros/flow.h index ff9085f7..380c671b 100644 --- a/include/ouroboros/flow.h +++ b/include/ouroboros/flow.h @@ -34,6 +34,9 @@ #define FLOW_O_INVALID (FLOW_O_WRONLY | FLOW_O_RDWR) +#define FLOW_F_GETFL 00000001 +#define FLOW_F_SETFL 00000002 + enum flow_state { FLOW_NULL = 0, FLOW_ALLOCATED, diff --git a/src/lib/dev.c b/src/lib/dev.c index 24e688ef..0adc2364 100644 --- a/src/lib/dev.c +++ b/src/lib/dev.c @@ -38,7 +38,7 @@ struct flow { struct shm_ap_rbuff * rb; int port_id; - uint32_t oflags; + int oflags; /* don't think this needs locking */ }; @@ -52,7 +52,6 @@ struct ap_data { struct flow flows[AP_MAX_FLOWS]; } * _ap_instance; - int ap_init(char * ap_name) { int i = 0; @@ -105,7 +104,7 @@ int ap_init(char * ap_name) return 0; } -void ap_fini() +void ap_fini(void) { int i = 0; @@ -402,7 +401,16 @@ int flow_dealloc(int fd) int flow_cntl(int fd, int cmd, int oflags) { - return -1; + int old = _ap_instance->flows[fd].oflags; + switch (cmd) { + case FLOW_F_GETFL: /* GET FLOW FLAGS */ + return _ap_instance->flows[fd].oflags; + case FLOW_F_SETFL: /* SET FLOW FLAGS */ + _ap_instance->flows[fd].oflags = oflags; + return old; + default: + return FLOW_O_INVALID; /* unknown command */ + } } ssize_t flow_write(int fd, void * buf, size_t count) @@ -417,9 +425,17 @@ ssize_t flow_write(int fd, void * buf, size_t count) if (index == -1) return -1; - if (shm_ap_rbuff_write(_ap_instance->flows[fd].rb, &e) < 0) { - shm_release_du_buff(_ap_instance->dum, index); - return -EPIPE; + if (_ap_instance->flows[fd].oflags & FLOW_O_NONBLOCK) + { + if (shm_ap_rbuff_write(_ap_instance->flows[fd].rb, &e) < 0) { + shm_release_du_buff(_ap_instance->dum, index); + return -EPIPE; + } + + return 0; + } else { + while (shm_ap_rbuff_write(_ap_instance->flows[fd].rb, &e) < 0) + ; } return 0; @@ -430,9 +446,18 @@ ssize_t flow_read(int fd, void * buf, size_t count) struct rb_entry * e = NULL; int n; uint8_t * sdu; - /* FIXME: move this to a thread */ - while (e == NULL || e->port_id != _ap_instance->flows[fd].port_id) + + if (_ap_instance->flows[fd].oflags & FLOW_O_NONBLOCK) { e = shm_ap_rbuff_read(_ap_instance->rb); + } else { + /* FIXME: move this to a thread */ + while (e == NULL || + e->port_id != _ap_instance->flows[fd].port_id) + e = shm_ap_rbuff_read(_ap_instance->rb); + } + + if (e == NULL) + return -1; n = shm_du_map_read_sdu(&sdu, _ap_instance->dum, diff --git a/src/lib/shm_ap_rbuff.c b/src/lib/shm_ap_rbuff.c index 34583d8e..aab6d78b 100644 --- a/src/lib/shm_ap_rbuff.c +++ b/src/lib/shm_ap_rbuff.c @@ -242,6 +242,7 @@ int shm_ap_rbuff_write(struct shm_ap_rbuff * rb, struct rb_entry * e) return 0; } + struct rb_entry * shm_ap_rbuff_read(struct shm_ap_rbuff * rb) { struct rb_entry * e = NULL; |