memset(info, 0, sizeof(*info));\r
\r
ALOGI("Creating socket");\r
+ if (socketpair(AF_UNIX, SOCK_STREAM, 0, info->cleanup_socks) == -1) {\r
+ ALOGE("Could not create cleanup sockets");\r
+ free(info);\r
+ return WIFI_ERROR_UNKNOWN;\r
+ }\r
+\r
struct nl_sock *cmd_sock = wifi_create_nl_socket(WIFI_HAL_CMD_SOCK_PORT);\r
if (cmd_sock == NULL) {\r
ALOGE("Could not create handle");\r
+ free(info);\r
return WIFI_ERROR_UNKNOWN;\r
}\r
\r
if (event_sock == NULL) {\r
ALOGE("Could not create handle");\r
nl_socket_free(cmd_sock);\r
+ free(info);\r
return WIFI_ERROR_UNKNOWN;\r
}\r
\r
struct nl_cb *cb = nl_socket_get_cb(event_sock);\r
if (cb == NULL) {\r
ALOGE("Could not create handle");\r
+ nl_socket_free(cmd_sock);\r
+ nl_socket_free(event_sock);\r
+ free(info);\r
return WIFI_ERROR_UNKNOWN;\r
}\r
\r
wifi_cleaned_up_handler cleaned_up_handler = info->cleaned_up_handler;\r
\r
if (info->cmd_sock != 0) {\r
+ close(info->cleanup_socks[0]);\r
+ close(info->cleanup_socks[1]);\r
nl_socket_free(info->cmd_sock);\r
nl_socket_free(info->event_sock);\r
info->cmd_sock = NULL;\r
void wifi_cleanup(wifi_handle handle, wifi_cleaned_up_handler handler)\r
{\r
hal_info *info = getHalInfo(handle);\r
+ char buf[64];\r
+\r
info->cleaned_up_handler = handler;\r
+ if (write(info->cleanup_socks[0], "Exit", 4) < 1) {\r
+ ALOGE("could not write to the cleanup socket");\r
+ } else {\r
+ // Listen to the response\r
+ // Hopefully we dont get errors or get hung up\r
+ // Not much can be done in that case, but assume that\r
+ // it has rx'ed the Exit message to exit the thread.\r
+ // As a fallback set the cleanup flag to TRUE\r
+ memset(buf, 0, sizeof(buf));\r
+ int result = read(info->cleanup_socks[0], buf, sizeof(buf));\r
+ ALOGE("%s: Read after POLL returned %d, error no = %d", __FUNCTION__, result, errno);\r
+ if (strncmp(buf, "Done", 4) == 0) {\r
+ ALOGE("Event processing terminated");\r
+ } else {\r
+ ALOGD("Rx'ed %s", buf);\r
+ }\r
+ }\r
info->clean_up = true;\r
+ pthread_mutex_lock(&info->cb_lock);\r
\r
- ALOGI("Wifi cleanup completed");\r
+ int bad_commands = 0;\r
+\r
+ for (int i = 0; i < info->num_event_cb; i++) {\r
+ cb_info *cbi = &(info->event_cb[i]);\r
+ WifiCommand *cmd = (WifiCommand *)cbi->cb_arg;\r
+ }\r
+\r
+ while (info->num_cmd > bad_commands) {\r
+ int num_cmd = info->num_cmd;\r
+ cmd_info *cmdi = &(info->cmd[bad_commands]);\r
+ WifiCommand *cmd = cmdi->cmd;\r
+ if (cmd != NULL) {\r
+ pthread_mutex_unlock(&info->cb_lock);\r
+ cmd->cancel();\r
+ pthread_mutex_lock(&info->cb_lock);\r
+ /* release reference added when command is saved */\r
+ cmd->releaseRef();\r
+ if (num_cmd == info->num_cmd) {\r
+ bad_commands++;\r
+ }\r
+ }\r
+ }\r
+\r
+ for (int i = 0; i < info->num_event_cb; i++) {\r
+ cb_info *cbi = &(info->event_cb[i]);\r
+ WifiCommand *cmd = (WifiCommand *)cbi->cb_arg;\r
+ ALOGE("Leaked command %p", cmd);\r
+ }\r
+ pthread_mutex_unlock(&info->cb_lock);\r
+ internal_cleaned_up_handler(handle);\r
}\r
\r
static int internal_pollin_handler(wifi_handle handle)\r
info->in_event_loop = true;\r
}\r
\r
- pollfd pfd;\r
- memset(&pfd, 0, sizeof(pfd));\r
+ pollfd pfd[2];\r
+ memset(&pfd[0], 0, sizeof(pollfd) * 2);\r
\r
- pfd.fd = nl_socket_get_fd(info->event_sock);\r
- pfd.events = POLLIN;\r
+ pfd[0].fd = nl_socket_get_fd(info->event_sock);\r
+ pfd[0].events = POLLIN;\r
+ pfd[1].fd = info->cleanup_socks[1];\r
+ pfd[1].events = POLLIN;\r
\r
- /* TODO: Add support for timeouts */\r
+ char buf[2048];\r
\r
do {\r
int timeout = -1; /* Infinite timeout */\r
- pfd.revents = 0;\r
- ALOGI("Polling socket");\r
- int result = poll(&pfd, 1, -1);\r
+ pfd[0].revents = 0;\r
+ pfd[1].revents = 0;\r
+ int result = poll(pfd, 2, timeout);\r
if (result < 0) {\r
- ALOGE("Error polling socket");\r
- } else if (pfd.revents & POLLERR) {\r
+ } else if (pfd[0].revents & POLLERR) {\r
ALOGE("POLL Error; error no = %d", errno);\r
- char buf[2048];\r
- int result2 = read(pfd.fd, buf, sizeof(buf));\r
+ int result2 = read(pfd[0].fd, buf, sizeof(buf));\r
ALOGE("Read after POLL returned %d, error no = %d", result2, errno);\r
- } else if (pfd.revents & POLLHUP) {\r
+ } else if (pfd[0].revents & POLLHUP) {\r
ALOGE("Remote side hung up");\r
break;\r
- } else if (pfd.revents & POLLIN) {\r
- ALOGI("Found some events!!!");\r
+ } else if (pfd[0].revents & POLLIN) {\r
internal_pollin_handler(handle);\r
+ } else if (pfd[1].revents & POLLIN) {\r
+ memset(buf, 0, sizeof(buf));\r
+ int result2 = read(pfd[1].fd, buf, sizeof(buf));\r
+ ALOGE("%s: Read after POLL returned %d, error no = %d", __FUNCTION__, result2, errno);\r
+ if (strncmp(buf, "Exit", 4) == 0) {\r
+ ALOGD("Got a signal to exit!!!");\r
+ if (write(pfd[1].fd, "Done", 4) < 1) {\r
+ ALOGE("could not write to the cleanup socket");\r
+ }\r
+ break;\r
+ } else {\r
+ ALOGD("Rx'ed %s on the cleanup socket\n", buf);\r
+ }\r
} else {\r
- ALOGE("Unknown event - %0x", pfd.revents);\r
+ ALOGE("Unknown event - %0x, %0x", pfd[0].revents, pfd[1].revents);\r
}\r
} while (!info->clean_up);\r
-\r
-\r
- ALOGI("Cleaning up");\r
- internal_cleaned_up_handler(handle);\r
+ ALOGI("Exit %s", __FUNCTION__);\r
}\r
\r
///////////////////////////////////////////////////////////////////////////////////////\r
}\r
\r
pthread_mutex_unlock(&info->cb_lock);\r
-\r
- (*cb_func)(msg, cb_arg);\r
+ if (cb_func)\r
+ (*cb_func)(msg, cb_arg);\r
if (cmd != NULL) {\r
cmd->releaseRef();\r
}\r