diff options
author | Pau Espin Pedrol <pespin@sysmocom.de> | 2018-08-28 17:32:29 +0200 |
---|---|---|
committer | Pau Espin Pedrol <pespin@sysmocom.de> | 2018-08-28 18:08:59 +0200 |
commit | 2775798edb2ea72dbe683cf61700b61426e67bf5 (patch) | |
tree | 2aa0c210bfc3a84390b13769094ea76d810a029b | |
parent | 3750dea96852b453029f91d4b3a66912745290d9 (diff) |
ipa: Allow signalling fd destroyed in ipa_client_read
Similar to what we do in other osmo_fd cb, check for read_cb returning
-EBADF and in that case don't attempt using the osmo_fd anymore, either
because the fd was already closed (no need to then signal WRITE) or
because osmo_fd struct itself has been freed.
Change-Id: I0e449a2bdf7f0411feeccd262cd731ca6fba3fc1
-rw-r--r-- | include/osmocom/abis/ipa.h | 1 | ||||
-rw-r--r-- | src/input/ipa.c | 15 |
2 files changed, 9 insertions, 7 deletions
diff --git a/include/osmocom/abis/ipa.h b/include/osmocom/abis/ipa.h index a157889..4359268 100644 --- a/include/osmocom/abis/ipa.h +++ b/include/osmocom/abis/ipa.h @@ -71,6 +71,7 @@ struct ipa_client_conn { const char *addr; uint16_t port; void (*updown_cb)(struct ipa_client_conn *link, int up); + /* Callback when ofd has something to be read. -EBADF must be returned if the osmo_fd is destroyed. */ int (*read_cb)(struct ipa_client_conn *link, struct msgb *msg); int (*write_cb)(struct ipa_client_conn *link); void *data; diff --git a/src/input/ipa.c b/src/input/ipa.c index 554644c..d0363e2 100644 --- a/src/input/ipa.c +++ b/src/input/ipa.c @@ -47,7 +47,7 @@ void ipa_client_conn_close(struct ipa_client_conn *link) link->pending_msg = NULL; } -static void ipa_client_read(struct ipa_client_conn *link) +static int ipa_client_read(struct ipa_client_conn *link) { struct osmo_fd *ofd = link->ofd; struct msgb *msg; @@ -58,7 +58,7 @@ static void ipa_client_read(struct ipa_client_conn *link) ret = ipa_msg_recv_buffered(ofd->fd, &msg, &link->pending_msg); if (ret <= 0) { if (ret == -EAGAIN) - return; + return 0; else if (ret == -EPIPE || ret == -ECONNRESET) LOGIPA(link, LOGL_ERROR, "lost connection with server\n"); else if (ret == 0) @@ -66,10 +66,11 @@ static void ipa_client_read(struct ipa_client_conn *link) ipa_client_conn_close(link); if (link->updown_cb) link->updown_cb(link, 0); - return; + return -EBADF; } if (link->read_cb) - link->read_cb(link, msg); + return link->read_cb(link, msg); + return 0; } static void ipa_client_write(struct ipa_client_conn *link) @@ -111,7 +112,7 @@ static int ipa_client_write_default_cb(struct ipa_client_conn *link) static int ipa_client_fd_cb(struct osmo_fd *ofd, unsigned int what) { struct ipa_client_conn *link = ofd->data; - int error, ret; + int error, ret = 0; socklen_t len = sizeof(error); switch(link->state) { @@ -132,9 +133,9 @@ static int ipa_client_fd_cb(struct osmo_fd *ofd, unsigned int what) case IPA_CLIENT_LINK_STATE_CONNECTED: if (what & BSC_FD_READ) { LOGIPA(link, LOGL_DEBUG, "connected read\n"); - ipa_client_read(link); + ret = ipa_client_read(link); } - if (what & BSC_FD_WRITE) { + if (ret != -EBADF && (what & BSC_FD_WRITE)) { LOGIPA(link, LOGL_DEBUG, "connected write\n"); ipa_client_write(link); } |