From 69bc2879918f413ea4dce64aadfc798225807c25 Mon Sep 17 00:00:00 2001 From: Alexander Couzens Date: Tue, 17 Oct 2017 10:11:19 +0200 Subject: [PATCH] call-list: fix a race condition in ofono_call_list_dial_callback If ofono_call_list_dial_callback is called later than ofono_call_list_notify, the new call is added, removed, added again. --- src/call-list.c | 10 ++++++++++ unit/test-call-list.c | 27 +++++++++++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/src/call-list.c b/src/call-list.c index fd39719a..b7f1650a 100644 --- a/src/call-list.c +++ b/src/call-list.c @@ -32,6 +32,16 @@ void ofono_call_list_dial_callback(struct ofono_voicecall *vc, int call_id) { struct ofono_call *call; + GSList *list; + + /* check if call_id already present */ + list = g_slist_find_custom(*call_list, + GINT_TO_POINTER(call_id), + ofono_call_compare_by_id); + + if (list) { + return; + } call = g_new0(struct ofono_call, 1); call->id = call_id; diff --git a/unit/test-call-list.c b/unit/test-call-list.c index 980038ab..6b0ec387 100644 --- a/unit/test-call-list.c +++ b/unit/test-call-list.c @@ -213,11 +213,38 @@ static void test_dial_callback(void) g_slist_free_full(call_list, g_free); } +static void test_dial_callback_race(void) +{ + struct ofono_voicecall *vc = NULL; + struct ofono_phone_number ph; + struct ofono_call *call; + GSList *call_list, *calls; + + /* reset test */ + reset_notified(); + call_list = NULL; + + strcpy(ph.number, "0099301234567890"); + ph.type = 0; + + /* outgoing call */ + calls = create_call(NULL, 1, CALL_STATUS_DIALING, + CALL_DIRECTION_MOBILE_ORIGINATED); + ofono_call_list_notify(vc, &call_list, calls); + ofono_call_list_dial_callback(vc, &call_list, &ph, 1); + + g_assert(call_list->next == NULL); + + /* check how many items in the variable */ + g_slist_free_full(call_list, g_free); +} + int main(int argc, char **argv) { g_test_init(&argc, &argv, NULL); g_test_add_func("/test-call-list/dial_callback", test_dial_callback); + g_test_add_func("/test-call-list/dial_callback_race", test_dial_callback_race); g_test_add_func("/test-call-list/test_notify", test_notify); g_test_add_func("/test-call-list/test_notify_disconnected", test_notify_disconnected);