Modify the cleanup procedure
Ashwin [Fri, 28 Aug 2015 21:47:42 +0000 (14:47 -0700)]
1. Use the cleanup sockets to communicate to the evnt thread to exit and rx a
ack for the same.
2. Added some missing cleanup on error during init.

Bug: 23537437

Change-Id: Iac42e28c79e5ddf8c1a6a57719c3b08904330107
Signed-off-by: Ashwin <ashwin.bhat@broadcom.com>

bcmdhd/wifi_hal/common.h
bcmdhd/wifi_hal/wifi_hal.cpp

index 8c09c16..118e0fc 100644 (file)
@@ -154,7 +154,7 @@ typedef struct {
     int cleanup_socks[2];                           // sockets used to implement wifi_cleanup
 
     bool in_event_loop;                             // Indicates that event loop is active
-    bool clean_up;                                  // Indication to clean up the socket
+    bool clean_up;                                  // Indication to exit since cleanup has started
 
     wifi_internal_event_handler event_handler;      // default event handler
     wifi_cleaned_up_handler cleaned_up_handler;     // socket cleaned up handler
index 09738a3..00f35d9 100644 (file)
@@ -179,12 +179,14 @@ wifi_error wifi_initialize(wifi_handle *handle)
     ALOGI("Creating socket");
     if (socketpair(AF_UNIX, SOCK_STREAM, 0, info->cleanup_socks) == -1) {
         ALOGE("Could not create cleanup sockets");
+        free(info);
         return WIFI_ERROR_UNKNOWN;
     }
 
     struct nl_sock *cmd_sock = wifi_create_nl_socket(WIFI_HAL_CMD_SOCK_PORT);
     if (cmd_sock == NULL) {
         ALOGE("Could not create handle");
+        free(info);
         return WIFI_ERROR_UNKNOWN;
     }
 
@@ -192,12 +194,16 @@ wifi_error wifi_initialize(wifi_handle *handle)
     if (event_sock == NULL) {
         ALOGE("Could not create handle");
         nl_socket_free(cmd_sock);
+        free(info);
         return WIFI_ERROR_UNKNOWN;
     }
 
     struct nl_cb *cb = nl_socket_get_cb(event_sock);
     if (cb == NULL) {
         ALOGE("Could not create handle");
+        nl_socket_free(cmd_sock);
+        nl_socket_free(event_sock);
+        free(info);
         return WIFI_ERROR_UNKNOWN;
     }
 
@@ -288,9 +294,28 @@ static void internal_cleaned_up_handler(wifi_handle handle)
 void wifi_cleanup(wifi_handle handle, wifi_cleaned_up_handler handler)
 {
     hal_info *info = getHalInfo(handle);
+    char buf[64];
+
     info->cleaned_up_handler = handler;
+    if (write(info->cleanup_socks[0], "Exit", 4) < 1) {
+        // As a fallback set the cleanup flag to TRUE
+        ALOGE("could not write to the cleanup socket");
+    } else {
+        // Listen to the response
+        // Hopefully we dont get errors or get hung up
+        // Not much can be done in that case, but assume that
+        // it has rx'ed the Exit message to exit the thread.
+        // As a fallback set the cleanup flag to TRUE
+        memset(buf, 0, sizeof(buf));
+        int result = read(info->cleanup_socks[0], buf, sizeof(buf));
+        ALOGE("%s: Read after POLL returned %d, error no = %d", __FUNCTION__, result, errno);
+        if (strncmp(buf, "Done", 4) == 0) {
+            ALOGE("Event processing terminated");
+        } else {
+            ALOGD("Rx'ed %s", buf);
+        }
+    }
     info->clean_up = true;
-
     pthread_mutex_lock(&info->cb_lock);
 
     int bad_commands = 0;
@@ -324,14 +349,8 @@ void wifi_cleanup(wifi_handle handle, wifi_cleaned_up_handler handler)
         WifiCommand *cmd = (WifiCommand *)cbi->cb_arg;
         ALOGE("Leaked command %p", cmd);
     }
-
     pthread_mutex_unlock(&info->cb_lock);
-
-    if (write(info->cleanup_socks[0], "T", 1) < 1) {
-        ALOGE("could not write to cleanup socket");
-    } else {
-        ALOGI("Wifi cleanup completed");
-    }
+    internal_cleaned_up_handler(handle);
 }
 
 static int internal_pollin_handler(wifi_handle handle)
@@ -384,16 +403,23 @@ void wifi_event_loop(wifi_handle handle)
             // ALOGI("Found some events!!!");
             internal_pollin_handler(handle);
         } else if (pfd[1].revents & POLLIN) {
-            ALOGI("Got a signal to exit!!!");
+            memset(buf, 0, sizeof(buf));
             int result2 = read(pfd[1].fd, buf, sizeof(buf));
-            ALOGE("Read after POLL returned %d, error no = %d", result2, errno);
+            ALOGE("%s: Read after POLL returned %d, error no = %d", __FUNCTION__, result2, errno);
+            if (strncmp(buf, "Exit", 4) == 0) {
+                ALOGD("Got a signal to exit!!!");
+                if (write(pfd[1].fd, "Done", 4) < 1) {
+                    ALOGE("could not write to the cleanup socket");
+                }
+                break;
+            } else {
+                ALOGD("Rx'ed %s on the cleanup socket\n", buf);
+            }
         } else {
             ALOGE("Unknown event - %0x, %0x", pfd[0].revents, pfd[1].revents);
         }
     } while (!info->clean_up);
-
-    ALOGI("Cleaning up");
-    internal_cleaned_up_handler(handle);
+    ALOGI("Exit %s", __FUNCTION__);
 }
 
 ///////////////////////////////////////////////////////////////////////////////////////
@@ -454,10 +480,9 @@ static int internal_valid_message_handler(nl_msg *msg, void *arg)
             if (cmd != NULL) {
                 cmd->addRef();
             }
-
             pthread_mutex_unlock(&info->cb_lock);
-
-            (*cb_func)(msg, cb_arg);
+            if (cb_func)
+                (*cb_func)(msg, cb_arg);
             if (cmd != NULL) {
                 cmd->releaseRef();
             }