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