[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [lwip-users] lwip-users Digest, Vol 114, Issue 28
From: |
Ted Smith |
Subject: |
Re: [lwip-users] lwip-users Digest, Vol 114, Issue 28 |
Date: |
Thu, 28 Feb 2013 16:10:36 +0000 |
Thank you for the quick reply Stephane. Let me warn you that I'm not an LWIP
expert. I believe I am doing as you suggest. Here is some more information:
>>>>This thread gets into tcpip_apimsg() and posts to the mbox.
>>If you're talking about your netif driver giving the packets to the stack,
>>then I think this is wrong.
>>You should use tcpip_input().
>>This function will create a TCPIP_MSG_INPKT message and sys_mbox_trypost() it
>>to the tcpip thread.
I've set up my netif in the following way:
err_t EthernetInit(struct netif * netifPtr)
{
...
netifPtr->output = etharp_output; <== is this correct??
netifPtr->linkoutput = low_level_output; <== I've implemented this
one
...
}
void Initialize()
{
if(
netif_add( &lwipNetif, // a pre-allocated netif structure
&lwipIpaddr, // IP address for the new netif
&lwipNetMask, // network mask for the new netif
&lwipGateway, // default gateway IP address for the new netif
0, // opaque data passed to the new netif
EthernetInit, // callback function that initializes the interface
tcpip_input ) == 0)// callback function that is called to pass ingress
packets up in the protocol layer stack.
{
assert(0);
}
netif_set_default(&lwipNetif);
// initialize lwip
tcpip_init(0, 0);
}
And I do the following to feed raw packets into the stack:
static void ReceiveEthernetPktsThread(void *)
{
struct pbuf * newPbuf = 0;
while(1)
{
//create a new pbuf if needed (usual case)
if( newPbuf == 0 )
{
newPbuf = pbuf_alloc(PBUF_RAW, XEL_MAX_FRAME_SIZE, PBUF_POOL);
assert(newPbuf);
assert(newPbuf->len >= XEL_MAX_FRAME_SIZE); //entire payload had
better be in this pbuf!
}
EnterCritical();
unsigned length = XEmacLite_Recv(&emacInstance, (unsigned char
*)newPbuf->payload);
ExitCritical();
if(length)
{
struct eth_hdr * ethHdrPtr = (struct eth_hdr *)newPbuf->payload;
#if LINK_STATS
lwip_stats.link.recv++;
#endif
switch( htons( ethHdrPtr->type ) )
{
case ETHTYPE_IP:
case ETHTYPE_ARP:
#if PPPOE_SUPPORT
/* PPPoE packet? */
case ETHTYPE_PPPOEDISC:
case ETHTYPE_PPPOE:
#endif /* PPPOE_SUPPORT */
/* full packet send to tcpip_thread to process */
if (lwipNetif.input(newPbuf, &lwipNetif)!=ERR_OK)
{
printf("ethernetif_input: IP input error\n");
pbuf_free(newPbuf);
}
break;
default:
// unknown type
pbuf_free( newPbuf );
printf("unknown eth type rcvd\n");
break;
}
LINK_STATS_INC(link.recv);
newPbuf = 0; //indicate a new pbuf must be allocated
}
else
{
WaitForPacketReceivedSignal();
}
}
}
My TCP write function is simple calling lwip_write(socket, payload, size).
All of my testing is with one client server connection. I am trying to keep
the tcp window full at all times as a torture test. I intentionally vary the
execution times of the requests so the outbound responses come in bursts.
>>>Now a context switch occurs back to the outbound thread which finally makes
>>>it to the same sys_arch_sem_wait() call and blocks.
>>>Now context is switched to the tcpip_thread which finish the do_write()
>>>execution and calls TCPIP_APIMSG_ACK().
>>>This should have unblocked the outbound thread however the first one to
>>>block on that sem was the inbound thread (which still has it's message
>>>posted in the mbox) so the inbound thread receives the signal.
>>>Now the tcpip_thread() grabs the inbound msg (which container was on
>>>the inbound thread's stack which has been popped) and starts processing the
>>>message.? That container can now be corrupted since the stack has been
>>>popped.
>>>Bad things happen after this.....
>>Of course, and this is why LwIP does not support multiple threads using the
>>same socket (without the core locking option)
I'm only using a single thread to write to the socket. I'm using a different
thread to read from the socket. The race condition appeared to be from the
tcp_input() side which is in a 3rd thread. Do I need to write from the same
thread that is feeding the stack using tcp_input()?
Thank you for your help. I'm not clear on the threading limitations of LWIP.
I greatly appreciate your direction.
Ted
-------------------------------------------------------
CONFIDENTIALITY NOTICE:
This email and any attachments are confidential information of the sender and
are for the exclusive use of the intended recipient. If you are not the
intended recipient, be aware that any disclosure, copying, distribution, or use
of this email or any attachment is prohibited. If you have received this email
in error, please notify us immediately by returning it to the sender and delete
this copy from your system. Thank you for your cooperation.
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- Re: [lwip-users] lwip-users Digest, Vol 114, Issue 28,
Ted Smith <=