summaryrefslogtreecommitdiff
path: root/src/phFriNfc_LlcpTransport_Connectionless.c
diff options
context:
space:
mode:
authorMartijn Coenen <maco@google.com>2013-03-01 17:15:45 -0800
committerMartijn Coenen <maco@google.com>2013-03-05 17:06:36 -0800
commit7c4b4fadb66959c50c170182847886e83393eebf (patch)
treeb6536be965f31a86351a87f4e722c92bfb04e69a /src/phFriNfc_LlcpTransport_Connectionless.c
parent65e86fce1fe9e3f9aff98861c5e1e9d9ba6df9d5 (diff)
downloadlibnfc-nxp-7c4b4fadb66959c50c170182847886e83393eebf.tar.gz
Fix some LLCP threading issues.
On Android we now start connecting SNEP/other LLCP services as soon as the link comes up. That means we will have connect requests incoming, accept responses outgoing, connect requests outgoing and accept responses incoming. This lays bare a lot of threading issues in this lib. Since the receives come in serialized, those typically do not cause any issue. However, we may be sending something on a thread coming from the NfcService, while at the same time we'll receive for example a connect frame from the remote, to which the receive thread immediately wants to send a response. This is a first attempt at making sends thread-safe: already there was a lot of logic to deal with the fact that another send was in progress, in the form of the bSendPending variable. That variable was however not checked atomically, and some operations did not even set it correctly. This change tests and sets that variable atomically, more or less implementing a semaphore with try-acquires and fallbacks for the failure case. The generic structure is: if (testAndSetSendPending()) { // Another thread is sending, stash data // and most importantly do *NOT* change shared data } else { // We're now the only one sending, we're free // to change shared data until the callback is // called. } This is just a band-aid fix, but given the fact that this stack will be deprecated it is hopefully enough for our planned usecases. A decent fix would involve switching to a TX-queue per socket, and a generic TX-queue for the whole LLCP link. This allows us to fully decouple the connection layer from the transport layer, as it should be. Change-Id: Ibd8742f7350a58459771f5036a049af3a487f783
Diffstat (limited to 'src/phFriNfc_LlcpTransport_Connectionless.c')
-rw-r--r--src/phFriNfc_LlcpTransport_Connectionless.c4
1 files changed, 4 insertions, 0 deletions
diff --git a/src/phFriNfc_LlcpTransport_Connectionless.c b/src/phFriNfc_LlcpTransport_Connectionless.c
index b27f6de..99f01bc 100644
--- a/src/phFriNfc_LlcpTransport_Connectionless.c
+++ b/src/phFriNfc_LlcpTransport_Connectionless.c
@@ -30,6 +30,7 @@
#include <phFriNfc_Llcp.h>
static void phFriNfc_LlcpTransport_Connectionless_SendTo_CB(void* pContext,
+ uint8_t socketIndex,
NFCSTATUS status);
NFCSTATUS phFriNfc_LlcpTransport_Connectionless_HandlePendingOperations(phFriNfc_LlcpTransport_Socket_t *pSocket)
@@ -51,6 +52,7 @@ NFCSTATUS phFriNfc_LlcpTransport_Connectionless_HandlePendingOperations(phFriNfc
NULL,
&pSocket->sSocketSendBuffer,
phFriNfc_LlcpTransport_Connectionless_SendTo_CB,
+ pSocket->index,
pSocket);
}
else
@@ -125,6 +127,7 @@ void Handle_Connectionless_IncommingFrame(phFriNfc_LlcpTransport_t *pLlcpTr
/* TODO: comment function phFriNfc_LlcpTransport_Connectionless_SendTo_CB */
static void phFriNfc_LlcpTransport_Connectionless_SendTo_CB(void* pContext,
+ uint8_t socketIndex,
NFCSTATUS status)
{
phFriNfc_LlcpTransport_Socket_t * pLlcpSocket = (phFriNfc_LlcpTransport_Socket_t*)pContext;
@@ -271,6 +274,7 @@ NFCSTATUS phFriNfc_LlcpTransport_Connectionless_SendTo(phFriNfc_LlcpTransport_So
NULL,
psBuffer,
phFriNfc_LlcpTransport_Connectionless_SendTo_CB,
+ pLlcpSocket->index,
pLlcpSocket);
}