osmo_io: Support detecting non-blocking connect()

libosmo-netif does a non blocking connect(), which as per definition of
 the socket API is signalled from the OS to the user by marking the file
descriptor writable.

osmo_io needs to signal this somehow. Previously osmo_io would only call
the write_cb if actual data has been sent. This patch changes the behaviour
so that calling osmo_iofd_write_enable() will call write_cb() on a writable
socket even if the write queue is empty.

Change-Id: I893cbc3becd5e125f2f06b3654578aed0aacadf3
diff --git a/src/core/osmo_io.c b/src/core/osmo_io.c
index 857644d..9960fb4 100644
--- a/src/core/osmo_io.c
+++ b/src/core/osmo_io.c
@@ -395,8 +395,7 @@
 void osmo_iofd_write_enable(struct osmo_io_fd *iofd)
 {
 	iofd->write_enabled = true;
-	if (iofd->tx_queue.current_length > 0)
-		osmo_iofd_ops.write_enable(iofd);
+	osmo_iofd_ops.write_enable(iofd);
 }
 
 /*! Disable writing to this iofd
diff --git a/src/core/osmo_io_poll.c b/src/core/osmo_io_poll.c
index bc203c0..dd86f29 100644
--- a/src/core/osmo_io_poll.c
+++ b/src/core/osmo_io_poll.c
@@ -110,7 +110,15 @@
 
 			talloc_free(msghdr);
 			msgb_free(msg);
+		} else {
+			if (iofd->mode == OSMO_IO_FD_MODE_READ_WRITE)
+				/* Socket is writable, but we have no data to send. A non-blocking/async
+				   connect() is signalled this way. */
+				iofd->io_ops.write_cb(iofd, 0, NULL);
+			if (osmo_iofd_txqueue_len(iofd) == 0)
+				iofd_poll_ops.write_disable(iofd);
 		}
+
 	}
 }
 
diff --git a/tests/osmo_io/osmo_io_test.ok b/tests/osmo_io/osmo_io_test.ok
index 745e36a..43e5464 100644
--- a/tests/osmo_io/osmo_io_test.ok
+++ b/tests/osmo_io/osmo_io_test.ok
@@ -1,5 +1,6 @@
 Running test_connected
 ep1: write() returned rc=16
+ep2: write() returned rc=0
 ep2: read() msg with len=16
 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 
 Running test_unconnected