To avoid the case that rfkill event happens in the following device
enable stage. It tends to cause racy issue in this case.
---
 src/rfkill.c |   49 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 49 insertions(+), 0 deletions(-)

diff --git a/src/rfkill.c b/src/rfkill.c
index 4b6a61d..e3f7bd9 100644
--- a/src/rfkill.c
+++ b/src/rfkill.c
@@ -101,11 +101,54 @@ static gboolean rfkill_event(GIOChannel *chan,
        return TRUE;
 }
 
+static int drain_rfkill(GIOChannel *chan)
+{
+       unsigned char buf[32];
+       struct rfkill_event *event = (void *) buf;
+       char sysname[32];
+       connman_bool_t blocked;
+       gsize len;
+       GIOStatus status = G_IO_STATUS_NORMAL;
+
+       DBG("");
+
+       while (status != G_IO_STATUS_AGAIN) {
+               memset(buf, 0, sizeof(buf));
+               status = g_io_channel_read_chars(chan, (gchar *) buf,
+                               sizeof(struct rfkill_event), &len, NULL);
+               if (status == G_IO_STATUS_ERROR)
+                       return -EIO;
+
+               if (len != sizeof(struct rfkill_event))
+                       continue;
+
+               DBG("idx %u type %u op %u soft %u hard %u",
+                                       event->idx, event->type, event->op,
+                                               event->soft, event->hard);
+
+               snprintf(sysname, sizeof(sysname) - 1, "rfkill%d", event->idx);
+
+               blocked = (event->soft || event->hard) ? TRUE : FALSE;
+
+               switch (event->type) {
+               case RFKILL_TYPE_ALL:
+               case RFKILL_TYPE_WLAN:
+                       __connman_udev_rfkill(sysname, blocked);
+                       break;
+               default:
+                       break;
+               }
+       }
+
+       return 0;
+}
+
 static GIOChannel *channel = NULL;
 
 int __connman_rfkill_init(void)
 {
        int fd;
+       GIOFlags flags;
 
        DBG("");
 
@@ -118,6 +161,12 @@ int __connman_rfkill_init(void)
        channel = g_io_channel_unix_new(fd);
        g_io_channel_set_close_on_unref(channel, TRUE);
 
+       flags = g_io_channel_get_flags(channel);
+       flags |= G_IO_FLAG_NONBLOCK;
+       g_io_channel_set_flags(channel, flags, NULL);
+
+       drain_rfkill(channel);
+
        g_io_add_watch(channel, G_IO_IN | G_IO_NVAL | G_IO_HUP | G_IO_ERR,
                                                        rfkill_event, NULL);
 
-- 
1.6.1.3

_______________________________________________
connman mailing list
[email protected]
http://lists.connman.net/listinfo/connman

Reply via email to