diff options
author | Aleksander Morgado <aleksander@lanedo.com> | 2012-05-03 14:53:56 +0200 |
---|---|---|
committer | Aleksander Morgado <aleksander@lanedo.com> | 2012-07-03 16:08:49 +0200 |
commit | a4347d4d226da32f0b18c2e263e6f0cf7d0bb691 (patch) | |
tree | c92f043562d97fd7d27b5f01bcac4ba54afaba07 /src/qmi-device.c | |
parent | a580711cdf974d1b695388c07f2c6c993ca15b99 (diff) | |
download | external_libqmi-a4347d4d226da32f0b18c2e263e6f0cf7d0bb691.zip external_libqmi-a4347d4d226da32f0b18c2e263e6f0cf7d0bb691.tar.gz external_libqmi-a4347d4d226da32f0b18c2e263e6f0cf7d0bb691.tar.bz2 |
device: handle EAGAIN errors when writing to the channel
If the non-blocking socket's write buffers are full, the non-blocking write may
fail with EAGAIN errors, which we should just treat as a request to retry the
write.
Diffstat (limited to 'src/qmi-device.c')
-rw-r--r-- | src/qmi-device.c | 44 |
1 files changed, 32 insertions, 12 deletions
diff --git a/src/qmi-device.c b/src/qmi-device.c index adde6f2..b4edbce 100644 --- a/src/qmi-device.c +++ b/src/qmi-device.c @@ -1156,6 +1156,7 @@ qmi_device_command (QmiDevice *self, gconstpointer raw_message; gsize raw_message_len; gsize written; + GIOStatus write_status; g_return_if_fail (QMI_IS_DEVICE (self)); g_return_if_fail (message != NULL); @@ -1209,18 +1210,37 @@ qmi_device_command (QmiDevice *self, device_store_transaction (self, tr, timeout); written = 0; - if (g_io_channel_write_chars (self->priv->iochannel, - raw_message, - (gssize)raw_message_len, - &written, - &error) != G_IO_STATUS_NORMAL) { - g_prefix_error (&error, "Cannot write message: "); - - /* Match transaction so that we remove it from our tracking table */ - tr = device_match_transaction (self, message); - transaction_complete_and_free (tr, NULL, error); - g_error_free (error); - return; + write_status = G_IO_STATUS_AGAIN; + while (write_status == G_IO_STATUS_AGAIN) { + write_status = g_io_channel_write_chars (self->priv->iochannel, + raw_message, + (gssize)raw_message_len, + &written, + &error); + switch (write_status) { + case G_IO_STATUS_ERROR: + g_prefix_error (&error, "Cannot write message: "); + + /* Match transaction so that we remove it from our tracking table */ + tr = device_match_transaction (self, message); + transaction_complete_and_free (tr, NULL, error); + g_error_free (error); + return; + + case G_IO_STATUS_EOF: + /* We shouldn't get EOF when writing */ + g_assert_not_reached (); + break; + + case G_IO_STATUS_NORMAL: + /* All good, we'll exit the loop now */ + break; + + case G_IO_STATUS_AGAIN: + /* We're in a non-blocking channel and therefore we're up to receive + * EAGAIN; just retry in this case. TODO: in an idle? */ + break; + } } /* Just return, we'll get response asynchronously */ |