osmo_io: Move notify_connected function to backend

This relocation is necessary as the backend (osmo_io_fd or
osmo_io_uring) requires a different approach in handling connect
notifications. As a result, a function call has been introduced to
struct iofd_backend_ops.

In a subsequent patch, the process for the osmo_io_uring backend will
be modified to handle SCTP connect notifications using poll/select.

If connect notification is requested using poll/select, the file
descriptior must be registered to osmo_fd, using osmo_fd_register. If
read / write notification is requested by application, the file
descriptior must be registered also. A flag is used prevent calling
osmo_fd_register / osmo_fd_unregister multiple times, which would cause
a crash.

Change-Id: I905ec85210570aff8addadfc9603335d04eb057a
Related: OS#5751
diff --git a/src/core/osmo_io_poll.c b/src/core/osmo_io_poll.c
index d7f80c0..8398a30 100644
--- a/src/core/osmo_io_poll.c
+++ b/src/core/osmo_io_poll.c
@@ -119,20 +119,32 @@
 int iofd_poll_register(struct osmo_io_fd *iofd)
 {
 	struct osmo_fd *ofd = &iofd->u.poll.ofd;
+	int rc;
+
+	if (IOFD_FLAG_ISSET(iofd, IOFD_FLAG_FD_REGISTERED))
+		return 0;
 	osmo_fd_setup(ofd, iofd->fd, 0, &iofd_poll_ofd_cb_dispatch, iofd, 0);
-	return osmo_fd_register(ofd);
+	rc = osmo_fd_register(ofd);
+	if (!rc)
+		IOFD_FLAG_SET(iofd, IOFD_FLAG_FD_REGISTERED);
+	return rc;
 }
 
 int iofd_poll_unregister(struct osmo_io_fd *iofd)
 {
 	struct osmo_fd *ofd = &iofd->u.poll.ofd;
+
+	if (!IOFD_FLAG_ISSET(iofd, IOFD_FLAG_FD_REGISTERED))
+		return 0;
 	osmo_fd_unregister(ofd);
+	IOFD_FLAG_UNSET(iofd, IOFD_FLAG_FD_REGISTERED);
 
 	return 0;
 }
 
 int iofd_poll_close(struct osmo_io_fd *iofd)
 {
+	iofd_poll_unregister(iofd);
 	osmo_fd_close(&iofd->u.poll.ofd);
 
 	return 0;
@@ -158,6 +170,16 @@
 	osmo_fd_write_disable(&iofd->u.poll.ofd);
 }
 
+void iofd_poll_notify_connected(struct osmo_io_fd *iofd)
+{
+	int rc;
+
+	rc = iofd_poll_register(iofd);
+	if (rc < 0)
+		return;
+	osmo_fd_write_enable(&iofd->u.poll.ofd);
+}
+
 const struct iofd_backend_ops iofd_poll_ops = {
 	.register_fd = iofd_poll_register,
 	.unregister_fd = iofd_poll_unregister,
@@ -166,6 +188,7 @@
 	.write_disable = iofd_poll_write_disable,
 	.read_enable = iofd_poll_read_enable,
 	.read_disable = iofd_poll_read_disable,
+	.notify_connected = iofd_poll_notify_connected,
 };
 
 #endif /* defined(__linux__) */