lwip-users
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [lwip-users] recv function BLOCK because recv_mbox is full: can youg


From: Piero 74
Subject: Re: [lwip-users] recv function BLOCK because recv_mbox is full: can yougive me a solution?
Date: Fri, 7 Mar 2008 18:07:08 +0100



2008/3/7, Jonathan Larmour <address@hidden>:
Piero 74 wrote:
>
>
> 2008/3/7, Bill Auerbach <address@hidden

> <mailto:address@hidden>>:

>
>     Should receive have blocked at all since there is data in the
>     recv_mbox?  Overflowing has no bearing on a thread waiting for data
>     when there is data already in the mbox.
>
>
> yes... it has blocked.... i tried to  use  a recv_mbox with more
> elemets, and the problem dosn't  happen... but  i'm thinking something
> to avoid this block...
>
> i don't know if can help you to understand the problem, but i saw:
>
> tcp fast timer was running and calling sys_mbox_trypost, but mbox was
> full...


But that's the thing - if you have a recv blocked, then the mbox should not
be full.

lwip_recv calls netconn_recv which directly calls sys_arch_mbox_fetch to
receive pending data. If the mbox is full, then your thread should have
extracted data from the mbox immediately.

yes... i know,,, but all  was blocked iin a deadlock situation... i don't know why... and a big recv_mbox has removed the problem....

> so tcp_ip thread was running, but application task was
> blocked... in think in sys_arch_mbox_fetch (called with timeout =0) in
> netconn_recv.
>
> Do you think could be usefull this:
>
> enable LWIP_SO_RCVTIMEO
> set SO_RCVTIMEO option for a socket


I think you have a more fundamental problem with your mbox implementation.

i used queue of  freertos for mbox...
this is the code:


sys_mbox_t
sys_mbox_new(int size)
{
  xQueueHandle mbox;
 
  size = (size) ? size : archMESG_QUEUE_LENGTH; // if size = 0, use costant
  mbox = xQueueCreate( size, sizeof( void * ) );
  LWIP_ASSERT("new_mbox != NULL", mbox != NULL);
 
#if LWIP_STATS
  if(mbox == NULL)
  {
    lwip_stats.sys.mbox.err++;
  }else
  {
    lwip_stats.sys.mbox.used++;
    LWIP_ASSERT("sys_mbox_new() counter overflow", lwip_stats.sys.mbox.used != 0 );
    if (lwip_stats.sys.mbox.used > lwip_stats.sys.mbox.max)
    {
      lwip_stats.sys.mbox.max = lwip_stats.sys.mbox.used;
    }
  }
#endif /* LWIP_STATS */
 
 
  return mbox;
}



void
sys_mbox_free(sys_mbox_t mbox)
{
  /* parameter check */
  LWIP_ASSERT("sys_mbox_free ", mbox != SYS_MBOX_NULL );
 
  if( uxQueueMessagesWaiting( mbox ) )
  {
    /* Should never break here! */
    __asm ( "NOP" );
    LWIP_ASSERT("sys_mbox_free: message in Q!", 0 );
  }
 
  vQueueDelete( mbox );
#if LWIP_STATS
  lwip_stats.sys.mbox.used--;
  LWIP_ASSERT( "sys_mbox_free() ", lwip_stats.sys.mbox.used!= (u16_t)-1 );
#endif /* LWIP_STATS */
}


void
sys_mbox_post(sys_mbox_t mbox, void *msg)
{  
  /* parameter check */
  LWIP_ASSERT("sys_mbox_post ", mbox != SYS_MBOX_NULL );
 
  if(mbox != NULL)
  {
    while (xQueueSend( mbox, &msg, ( portTickType ) ( archPOST_BLOCK_TIME_MS * portTICK_RATE_MS ) ) != pdTRUE)
    {
      // loop for ever
      // if task blocks here for a long time: error. External actions are needed!
    }   
  }
}






err_t
sys_mbox_trypost(sys_mbox_t mbox, void *msg)
{
  LWIP_ASSERT("sys_mbox_trypost ", mbox != SYS_MBOX_NULL );
 
  if(mbox != NULL)
  {
    // try post without timeout
    if (xQueueSend( mbox, &msg, ( portTickType ) 0 ) == pdTRUE)
    {
      return(ERR_OK);     
    }else
    {
     return(ERR_MEM);
    }
  }
}





u32_t sys_arch_mbox_fetch(sys_mbox_t mbox, void **msg, u32_t timeout)
{
  void *dummyptr;
  portTickType StartTime, EndTime, Elapsed;
 
  StartTime = xTaskGetTickCount();
  LWIP_ASSERT("sys_mbox_fetch ", mbox != SYS_MBOX_NULL );
 
  if( msg == NULL )
  {
    msg = &dummyptr;
  }
 
  if (mbox != SYS_MBOX_NULL)
  {
    if(    timeout != 0 )
    {
      if(pdTRUE == xQueueReceive( mbox, &(*msg), timeout * portTICK_RATE_MS) )
      {
        EndTime = xTaskGetTickCount();
        Elapsed = EndTime - StartTime;
        if( Elapsed == 0 )
        {
          Elapsed = 1;
        }
        return ( Elapsed );
      }
      else // timed out blocking for message
      {
        *msg = NULL;
        return SYS_ARCH_TIMEOUT;
      }
    }
    else // block forever for a message.
    {
      while( pdTRUE != xQueueReceive( mbox, &(*msg), LWIPARCH_NOTIMEOUTMS * portTICK_RATE_MS) )
      {
        // loop for ever - call user function
        SYSTEM_BLOCKWHILE_CALLBACK;
      }
      EndTime = xTaskGetTickCount();
      Elapsed = EndTime - StartTime;
      if( Elapsed == 0 )
      {
        Elapsed = 1;
      }
      return ( Elapsed ); // return time blocked     
    } 
  }
  // code should never pass here (mbox = NULL)
  LWIP_ASSERT("should not come here", 0); 
  return(SYS_ARCH_TIMEOUT);
}



u32_t
sys_arch_mbox_tryfetch(sys_mbox_t mbox, void **msg)
{
  void *dummyptr;
 
  LWIP_ASSERT("sys_mbox_tryfetch ", mbox != SYS_MBOX_NULL );
 
  if( msg == NULL )
  {
    msg = &dummyptr;
  }
 
  if (mbox != SYS_MBOX_NULL)
  { 
    // try fetch without block
    if(pdTRUE == xQueueReceive( mbox, &(*msg), 0) )
    {
      return ( 0 );
    }
    else // no blocking for message
    {
      return SYS_MBOX_EMPTY;
    }
  }
  // code should never pass here (mbox = NULL)
  LWIP_ASSERT("should not come here", 0);
  return(SYS_MBOX_EMPTY);
}

if you can... please check the code.

Thanks,
Piero
 

Jifl

--
eCosCentric Limited      http://www.eCosCentric.com/     The eCos experts
  **  Visit us at ESC Silicon Valley <http://www.embedded.com/esc/sv>  **
  **  April 15-17 2008, Booth 3012, San Jose McEnery Convention Center **
Barnwell House, Barnwell Drive, Cambridge, UK.       Tel: +44 1223 245571
Registered in England and Wales: Reg No 4422071.
------["Si fractum non sit, noli id reficere"]------       Opinions==mine



_______________________________________________
lwip-users mailing list
address@hidden
http://lists.nongnu.org/mailman/listinfo/lwip-users


reply via email to

[Prev in Thread] Current Thread [Next in Thread]