diff options
author | Adriana Kobylak <anoo@us.ibm.com> | 2017-05-08 13:58:02 -0500 |
---|---|---|
committer | Adriana Kobylak <anoo@us.ibm.com> | 2017-05-15 12:23:27 -0500 |
commit | b2f2681fc8289f1089fb616b1156802251f4721f (patch) | |
tree | a477544f42bc57f89675f8fee8cec85a65f54320 | |
parent | 025d7959543991259dcdf3a8fb5f144e1f4ba4ae (diff) | |
download | phosphor-objmgr-b2f2681fc8289f1089fb616b1156802251f4721f.tar.gz phosphor-objmgr-b2f2681fc8289f1089fb616b1156802251f4721f.zip |
libmapper: Add subtree callback functions
Implement subtree callback functions for match, getpaths,
and timeout.
Change-Id: I1037a52fced9e47aa630ebb9ae39b745349acb95
Signed-off-by: Adriana Kobylak <anoo@us.ibm.com>
-rw-r--r-- | libmapper/mapper.c | 105 |
1 files changed, 105 insertions, 0 deletions
diff --git a/libmapper/mapper.c b/libmapper/mapper.c index 8865bc7..34c053c 100644 --- a/libmapper/mapper.c +++ b/libmapper/mapper.c @@ -76,6 +76,7 @@ struct mapper_async_subtree sd_bus *conn; sd_bus_slot *slot; sd_event_source *event_source; + int finished; int op; int retry; }; @@ -90,6 +91,7 @@ static int async_wait_getobject_callback(sd_bus_message *, static int async_subtree_match_callback(sd_bus_message *, void *, sd_bus_error *); +static void async_subtree_done(int r, mapper_async_subtree *); static int async_subtree_getpaths(mapper_async_subtree *); static int async_subtree_getpaths_callback(sd_bus_message *, void *, sd_bus_error *); @@ -399,10 +401,91 @@ free_wait: return r; } +static int async_subtree_timeout_callback(sd_event_source *s, + uint64_t usec, void *userdata) +{ + int r; + struct mapper_async_subtree *subtree = userdata; + + sd_event_source_unref(subtree->event_source); + r = sd_bus_call_method_async( + subtree->conn, + NULL, + MAPPER_BUSNAME, + MAPPER_PATH, + MAPPER_INTERFACE, + "GetSubTreePaths", + async_subtree_getpaths_callback, + subtree, + "sias", + subtree->namespace, + 0, 1, + subtree->interface); + if(r < 0) + async_subtree_done(r, subtree); + + return 0; +} + static int async_subtree_getpaths_callback(sd_bus_message *m, void *userdata, sd_bus_error *e) { + int r; + char *intf = NULL; + struct mapper_async_subtree *subtree = userdata; + uint64_t now; + + if(subtree->finished) + goto exit; + + r = sd_bus_message_get_errno(m); + + if(r == ENOENT) { + if (subtree->op == MAPPER_OP_REMOVE) + r = 0; + else + goto exit; + } + + if(r == EBUSY && subtree->retry < mapper_busy_retries) { + r = sd_event_now(subtree->loop, + CLOCK_MONOTONIC, + &now); + if(r < 0) { + async_subtree_done(r, subtree); + goto exit; + } + + ++subtree->retry; + r = sd_event_add_time(subtree->loop, + &subtree->event_source, + CLOCK_MONOTONIC, + now + mapper_busy_delay_interval_usec, + 0, + async_subtree_timeout_callback, + subtree); + if(r < 0) { + async_subtree_done(r, subtree); + goto exit; + } + + return 0; + } + + if(r) { + async_subtree_done(-r, subtree); + goto exit; + } + + sd_bus_message_read(m, "as", 1, &intf); + if (subtree->op == MAPPER_OP_REMOVE) { + /* For remove, operation is complete when the interface is not present */ + if (intf == NULL) + async_subtree_done(0, subtree); + } + +exit: return 0; } @@ -437,9 +520,31 @@ static int async_subtree_match_callback(sd_bus_message *m, void *t, sd_bus_error *e) { + int r; + + mapper_async_subtree *subtree = t; + if(subtree->finished) + return 0; + + r = async_subtree_getpaths(subtree); + if(r < 0) + async_subtree_done(r, subtree); + return 0; } +static void async_subtree_done(int r, mapper_async_subtree *t) +{ + if(t->finished) + return; + + t->finished = 1; + sd_bus_slot_unref(t->slot); + + if(t->callback) + t->callback(r, t->userdata); +} + int mapper_subtree_async(sd_bus *conn, sd_event *loop, char *namespace, |