ipa: Allow signalling fd destroyed in ipa_server_conn_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: I4b968b72285f23a9552519cea67398a43d5003d2
This commit is contained in:
Pau Espin 2018-08-28 17:53:38 +02:00
parent 2775798edb
commit 082876bb65
2 changed files with 9 additions and 7 deletions

View File

@ -37,6 +37,7 @@ struct ipa_server_conn {
int (*closed_cb)(struct ipa_server_conn *peer);
int (*ccm_cb)(struct ipa_server_conn *peer, struct msgb *msg,
struct tlv_parsed *tlvp, struct ipaccess_unit *ud);
/* Callback when ofd has something to be read. -EBADF must be returned if the osmo_fd is destroyed. */
int (*cb)(struct ipa_server_conn *peer, struct msgb *msg);
void *data;
struct msgb *pending_msg;

View File

@ -328,7 +328,7 @@ void ipa_server_link_close(struct ipa_server_link *link)
close(link->ofd.fd);
}
static void ipa_server_conn_read(struct ipa_server_conn *conn)
static int ipa_server_conn_read(struct ipa_server_conn *conn)
{
struct osmo_fd *ofd = &conn->ofd;
struct msgb *msg;
@ -339,18 +339,18 @@ static void ipa_server_conn_read(struct ipa_server_conn *conn)
ret = ipa_msg_recv_buffered(ofd->fd, &msg, &conn->pending_msg);
if (ret <= 0) {
if (ret == -EAGAIN)
return;
return 0;
else if (ret == -EPIPE || ret == -ECONNRESET)
LOGIPA(conn, LOGL_ERROR, "lost connection with server\n");
else if (ret == 0)
LOGIPA(conn, LOGL_ERROR, "connection closed with server\n");
ipa_server_conn_destroy(conn);
return;
return -EBADF;
}
if (conn->cb)
conn->cb(conn, msg);
return conn->cb(conn, msg);
return;
return 0;
}
static void ipa_server_conn_write(struct ipa_server_conn *conn)
@ -376,11 +376,12 @@ static void ipa_server_conn_write(struct ipa_server_conn *conn)
static int ipa_server_conn_cb(struct osmo_fd *ofd, unsigned int what)
{
struct ipa_server_conn *conn = ofd->data;
int rc = 0;
LOGP(DLINP, LOGL_DEBUG, "connected read/write\n");
if (what & BSC_FD_READ)
ipa_server_conn_read(conn);
if (what & BSC_FD_WRITE)
rc = ipa_server_conn_read(conn);
if (rc != -EBADF && (what & BSC_FD_WRITE))
ipa_server_conn_write(conn);
return 0;