channels/smartcard: Fix race in channel cleanup
authorMartin Fleisz <martin.fleisz@thincast.com>
Thu, 21 Jan 2021 09:10:44 +0000 (10:10 +0100)
committerakallabeth <akallabeth@users.noreply.github.com>
Thu, 25 Feb 2021 08:51:41 +0000 (09:51 +0100)
(cherry picked from commit 1155aade7f52fb594463370004a7a2766787d0d7)

channels/smartcard/client/smartcard_main.c

index 46c0980..82fb587 100644 (file)
@@ -209,6 +209,7 @@ static void smartcard_release_all_contexts(SMARTCARD_DEVICE* smartcard)
         * Call SCardCancel on existing contexts, unblocking all outstanding SCardGetStatusChange calls.
         */
 
+       ListDictionary_Lock(smartcard->rgSCardContextList);
        if (ListDictionary_Count(smartcard->rgSCardContextList) > 0)
        {
                pKeys = NULL;
@@ -232,11 +233,17 @@ static void smartcard_release_all_contexts(SMARTCARD_DEVICE* smartcard)
 
                free(pKeys);
        }
+       ListDictionary_Unlock(smartcard->rgSCardContextList);
+
+       /* Put thread to sleep so that PC/SC can process the cancel requests. This fixes a race
+        * condition that sometimes caused the pc/sc daemon to crash on MacOS (_xpc_api_misuse) */
+       Sleep(100);
 
        /**
         * Call SCardReleaseContext on remaining contexts and remove them from rgSCardContextList.
         */
 
+       ListDictionary_Lock(smartcard->rgSCardContextList);
        if (ListDictionary_Count(smartcard->rgSCardContextList) > 0)
        {
                pKeys = NULL;
@@ -269,6 +276,7 @@ static void smartcard_release_all_contexts(SMARTCARD_DEVICE* smartcard)
 
                free(pKeys);
        }
+       ListDictionary_Unlock(smartcard->rgSCardContextList);
 }
 
 static UINT smartcard_free_(SMARTCARD_DEVICE* smartcard)