diff --git a/src/utils/eloop.c b/src/utils/eloop.c index ddddcf17c..2d6aac7e0 100644 --- a/src/utils/eloop.c +++ b/src/utils/eloop.c @@ -599,6 +599,37 @@ int eloop_is_timeout_registered(eloop_timeout_handler handler, } +int eloop_deplete_timeout(unsigned int req_secs, unsigned int req_usecs, + eloop_timeout_handler handler, void *eloop_data, + void *user_data) +{ + struct os_time now, requested, remaining; + struct eloop_timeout *tmp; + + dl_list_for_each(tmp, &eloop.timeout, struct eloop_timeout, list) { + if (tmp->handler == handler && + tmp->eloop_data == eloop_data && + tmp->user_data == user_data) { + requested.sec = req_secs; + requested.usec = req_usecs; + os_get_time(&now); + os_time_sub(&tmp->time, &now, &remaining); + if (os_time_before(&requested, &remaining)) { + eloop_cancel_timeout(handler, eloop_data, + user_data); + eloop_register_timeout(requested.sec, + requested.usec, + handler, eloop_data, + user_data); + return 1; + } + } + } + + return 0; +} + + int eloop_replenish_timeout(unsigned int req_secs, unsigned int req_usecs, eloop_timeout_handler handler, void *eloop_data, void *user_data) diff --git a/src/utils/eloop.h b/src/utils/eloop.h index befb0703e..274714f88 100644 --- a/src/utils/eloop.h +++ b/src/utils/eloop.h @@ -222,6 +222,22 @@ int eloop_cancel_timeout_one(eloop_timeout_handler handler, int eloop_is_timeout_registered(eloop_timeout_handler handler, void *eloop_data, void *user_data); +/** + * eloop_deplete_timeout - Deplete a timeout that is already registered + * @req_secs: Requested number of seconds to the timeout + * @req_usecs: Requested number of microseconds to the timeout + * @handler: Matching callback function + * @eloop_data: Matching eloop_data + * @user_data: Matching user_data + * Returns: 1 if the timeout is depleted, 0 if no change is made + * + * Find a registered matching timeout. If found, + * deplete the timeout if remaining time is more than the requested time. + */ +int eloop_deplete_timeout(unsigned int req_secs, unsigned int req_usecs, + eloop_timeout_handler handler, void *eloop_data, + void *user_data); + /** * eloop_replenish_timeout - Replenish a timeout that is already registered * @req_secs: Requested number of seconds to the timeout diff --git a/src/utils/eloop_win.c b/src/utils/eloop_win.c index 1f40530cf..e87d82ac9 100644 --- a/src/utils/eloop_win.c +++ b/src/utils/eloop_win.c @@ -354,6 +354,37 @@ int eloop_is_timeout_registered(eloop_timeout_handler handler, } +int eloop_deplete_timeout(unsigned int req_secs, unsigned int req_usecs, + eloop_timeout_handler handler, void *eloop_data, + void *user_data) +{ + struct os_time now, requested, remaining; + struct eloop_timeout *tmp; + + dl_list_for_each(tmp, &eloop.timeout, struct eloop_timeout, list) { + if (tmp->handler == handler && + tmp->eloop_data == eloop_data && + tmp->user_data == user_data) { + requested.sec = req_secs; + requested.usec = req_usecs; + os_get_time(&now); + os_time_sub(&tmp->time, &now, &remaining); + if (os_time_before(&requested, &remaining)) { + eloop_cancel_timeout(handler, eloop_data, + user_data); + eloop_register_timeout(requested.sec, + requested.usec, + handler, eloop_data, + user_data); + return 1; + } + } + } + + return 0; +} + + int eloop_replenish_timeout(unsigned int req_secs, unsigned int req_usecs, eloop_timeout_handler handler, void *eloop_data, void *user_data) diff --git a/wpa_supplicant/scan.c b/wpa_supplicant/scan.c index cfac768fb..47827f442 100644 --- a/wpa_supplicant/scan.c +++ b/wpa_supplicant/scan.c @@ -907,6 +907,13 @@ void wpa_supplicant_update_scan_int(struct wpa_supplicant *wpa_s, int sec) */ void wpa_supplicant_req_scan(struct wpa_supplicant *wpa_s, int sec, int usec) { + if (eloop_deplete_timeout(sec, usec, wpa_supplicant_scan, wpa_s, NULL)) + { + wpa_dbg(wpa_s, MSG_DEBUG, "Rescheduling scan request: %d sec %d usec", + sec, usec); + return; + } + /* If there's at least one network that should be specifically scanned * then don't cancel the scan and reschedule. Some drivers do * background scanning which generates frequent scan results, and that