From 380c29e33c50acfb5396ecf5f4d9b4f6a1d82c2e Mon Sep 17 00:00:00 2001 From: nyatla Date: Tue, 21 May 2013 13:21:18 +0000 Subject: [PATCH] =?utf8?q?TCP=E3=82=BD=E3=82=B1=E3=83=83=E3=83=88=E3=81=AE?= =?utf8?q?=E3=83=AA=E3=82=BD=E3=83=BC=E3=82=B9=E6=8E=92=E4=BB=96mutex?= =?utf8?q?=E3=81=AE=E9=9B=86=E7=B4=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.osdn.jp/svnroot/mimic/trunk@243 47198e57-cb75-475f-84c4-a814cd6f29e0 --- lib/src/uip/NyLPC_cIPv4.c | 7 +- lib/src/uip/NyLPC_cIPv4.h | 14 ++-- lib/src/uip/NyLPC_cTcpSocket.c | 129 ++++++++++++++++-------------- lib/src/uip/NyLPC_cTcpSocket.h | 13 ++- lib/src/uip/NyLPC_cTcpSocket_protected.h | 8 ++ lib/src/uip/NyLPC_cUipService_protected.h | 2 +- 6 files changed, 97 insertions(+), 76 deletions(-) diff --git a/lib/src/uip/NyLPC_cIPv4.c b/lib/src/uip/NyLPC_cIPv4.c index d1aa95a..2cb9d3d 100644 --- a/lib/src/uip/NyLPC_cIPv4.c +++ b/lib/src/uip/NyLPC_cIPv4.c @@ -67,7 +67,7 @@ ***************************************************/ #define cSocketTbl_initialize(i_inst,buf) NyLPC_cPtrTbl_initialize(i_inst,buf,NyLPC_cIPv4_MAX_SOCKET) - +#define cSocketTbl_finalize(i_inst) /** * 条件に一致する、アクティブなTCPソケットオブジェクトを取得します。 @@ -170,6 +170,7 @@ void NyLPC_cIPv4_initialize( //内部テーブルの初期化 cSocketTbl_initialize(&(i_inst->_socket_tbl),(void**)(i_inst->_socket_array_buf)); //instanceの初期化 + NyLPC_cMutex_initialize(&(i_inst->_sock_mutex)); i_inst->_ref_config=NULL; return; } @@ -180,6 +181,8 @@ void NyLPC_cIPv4_initialize( void NyLPC_cIPv4_finalize( NyLPC_TcIPv4_t* i_inst) { + cSocketTbl_finalize(&(i_inst->_socket_tbl)); + NyLPC_cMutex_finalize(&(i_inst->_sock_mutex)); return; } @@ -345,8 +348,6 @@ static NyLPC_TBool tcp_rx( //Listen失敗。ドロップ goto DROP; } -// //Socketの割当に成功。管理リストへ追加 -// NyLPC_AbortIfNot(NyLPC_cPtrTbl_add(&(i_inst->_socket_tbl),sock)>=0); return NyLPC_TBool_FALSE;//LISTEN成功。送信データなし } return NyLPC_TBool_TRUE; diff --git a/lib/src/uip/NyLPC_cIPv4.h b/lib/src/uip/NyLPC_cIPv4.h index 7a10dc6..38482cd 100644 --- a/lib/src/uip/NyLPC_cIPv4.h +++ b/lib/src/uip/NyLPC_cIPv4.h @@ -111,15 +111,12 @@ struct NyLPC_TcIPv4 { /** 参照しているIPスタックの環境値です。この値は、start関数が設定します。*/ const NyLPC_TcIPv4Config_t* _ref_config; -// /** NyLPC_cTcpListernerを管理するポインタリストです。*/ -// NyLPC_TcPtrTbl_t _listener_tbl; + /** ソケットリソースの保護用。コールバック関数から呼び出されるソケット内部のリソース保護に使用する共通MUTEX*/ + NyLPC_TcMutex_t _sock_mutex; /** NyLPC_cTcpSocketを管理するポインタリストです。*/ NyLPC_TcPtrTbl_t _socket_tbl; -// /** _listener_tblが使用するメモリ領域です。*/ -// NyLPC_TcTcpListener_t* _listener_array_buf[NyLPC_cIPv4_MAX_TCP_LISTENER]; /** _socket_tblが使用するメモリ領域です。*/ NyLPC_TcBaseSocket_t* _socket_array_buf[NyLPC_cIPv4_MAX_SOCKET]; - }; /** @@ -215,8 +212,11 @@ NyLPC_TBool NyLPC_cIPv4_rx(NyLPC_TcIPv4_t* i_inst,void* i_rx,NyLPC_TUInt16 i_rx_ */ void NyLPC_cIPv4_periodec(NyLPC_TcIPv4_t* i_inst); - - +/** + * ソケットリソースとコールバックの排他処理に使う共通MUTEXを返します。 + * このMutexはソケット同士の干渉が起こらない処理にだけ使ってください。 + */ +#define NyLPC_cIPv4_getSockMutex(i_inst) (&((i_inst)->_sock_mutex)) #ifdef __cplusplus diff --git a/lib/src/uip/NyLPC_cTcpSocket.c b/lib/src/uip/NyLPC_cTcpSocket.c index f9a0d94..0f008e2 100644 --- a/lib/src/uip/NyLPC_cTcpSocket.c +++ b/lib/src/uip/NyLPC_cTcpSocket.c @@ -44,6 +44,12 @@ static NyLPC_TUInt32 iss32=3939; #define DEBUG_RTO_LOG(i_inst) #endif + +//#define lockResource(i_inst) NyLPC_cMutex_lock(&((i_inst)->_smutex)) +//#define unlockResource(i_inst) NyLPC_cMutex_unlock(&((i_inst)->_smutex)) +#define lockResource(i_inst) NyLPC_cMutex_lock(((i_inst)->_smutex)) +#define unlockResource(i_inst) NyLPC_cMutex_unlock(((i_inst)->_smutex)) + static void sendRst(NyLPC_TcTcpSocket_t* i_inst); @@ -139,7 +145,7 @@ static void resetTxQWithUnlock(NyLPC_TcTcpSocket_t* i_inst) } i_inst->txbuf.rp=i_inst->txbuf.wp=0; //ロック解除 - NyLPC_cMutex_unlock(&(i_inst->_smutex)); + unlockResource(i_inst); //セーブしたバッファを開放 for(i=0;itxbuf.wp+1)%NyLPC_TcTcpSocket_NUMBER_OF_TXQ)==i_inst->txbuf.rp){ //一時的なアンロック - NyLPC_cMutex_unlock(&(i_inst->_smutex)); + unlockResource(i_inst); //タスクスイッチ NyLPC_cThread_yield(); //ロック - NyLPC_cMutex_lock(&(i_inst->_smutex)); + lockResource(i_inst); continue; } i=i_inst->txbuf.wp; @@ -296,7 +302,6 @@ static struct NyLPC_TcTcpSocket_TxQItem* getTxQ(NyLPC_TcTcpSocket_t* i_inst,NyLP * public 関数 **********************************************************************/ - NyLPC_TBool NyLPC_cTcpSocket_initialize(NyLPC_TcTcpSocket_t* i_inst,void* i_rbuf,NyLPC_TUInt16 i_rbuf_len) { int i; @@ -306,7 +311,8 @@ NyLPC_TBool NyLPC_cTcpSocket_initialize(NyLPC_TcTcpSocket_t* i_inst,void* i_rbuf NyLPC_Assert(NyLPC_TcUipService_isInitService()); NyLPC_cFifoBuffer_initialize(&(i_inst->rxbuf),i_rbuf,i_rbuf_len); - NyLPC_AbortIfNot(NyLPC_cMutex_initialize(&(i_inst->_smutex))); + // NyLPC_AbortIfNot(NyLPC_cMutex_initialize(&(i_inst->_smutex))); + i_inst->_smutex=NyLPC_cIPv4_getSockMutex(&(srv->_tcpv4)); i_inst->tcpstateflags=UIP_CLOSED; i_inst->txbuf.rp=i_inst->txbuf.wp=0; for(i=0;itxbuf.rp!=i_inst->txbuf.wp){ - NyLPC_cMutex_lock(&(i_inst->_smutex)); + lockResource(i_inst); resetTxQWithUnlock(i_inst); } for(i=0;itxbuf.txq[i].data)); } NyLPC_cFifoBuffer_finalize(&(i_inst->rxbuf)); - NyLPC_cMutex_finalize(&(i_inst->_smutex)); +// NyLPC_cMutex_finalize(&(i_inst->_smutex)); NyLPC_cBaseSocket_finalize(&(i_inst->_super)); return; } @@ -350,7 +356,7 @@ NyLPC_TBool NyLPC_cTcpSocket_setSynPayload(NyLPC_TcTcpSocket_t* i_inst,const NyL { NyLPC_TUInt16 tmp16; //ソケットが無効であること。 - NyLPC_cMutex_lock(&(i_inst->_smutex)); + lockResource(i_inst); if(i_inst->tcpstateflags==UIP_CLOSED) { /* Fill in the necessary fields for the new connection. */ @@ -373,13 +379,13 @@ NyLPC_TBool NyLPC_cTcpSocket_setSynPayload(NyLPC_TcTcpSocket_t* i_inst,const NyL if(i_inst->txbuf.rp!=i_inst->txbuf.wp){ resetTxQWithUnlock(i_inst); }else{ - NyLPC_cMutex_unlock(&(i_inst->_smutex)); + unlockResource(i_inst); } //ここでステータスがかわる。 i_inst->tcpstateflags = UIP_SYN_RCVD; return NyLPC_TBool_TRUE; } - NyLPC_cMutex_unlock(&(i_inst->_smutex)); + unlockResource(i_inst); return NyLPC_TBool_FALSE; } /** @@ -401,22 +407,22 @@ NyLPC_TBool NyLPC_cTcpSocket_setSynPayload(NyLPC_TcTcpSocket_t* i_inst,const NyL static NyLPC_TBool waitForTxRemove(NyLPC_TcTcpSocket_t* i_inst,NyLPC_TUInt32 i_sq,NyLPC_TcStopwatch_t* i_timer) { NyLPC_TUInt8 f; - NyLPC_cMutex_lock(&(i_inst->_smutex)); + lockResource(i_inst); while(!NyLPC_cStopwatch_isExpired(i_timer)){ //パケットが送信中か調べる。 if(!isPacketAcked(i_inst,i_sq)){ //まだある場合は、タスクスイッチを繰り返して消失を待つ。 - NyLPC_cMutex_unlock(&(i_inst->_smutex)); + unlockResource(i_inst); NyLPC_cThread_yield(); - NyLPC_cMutex_lock(&(i_inst->_smutex)); + lockResource(i_inst); continue; } //なくなった場合は、原因を調べる。 f=i_inst->tcpstateflags; - NyLPC_cMutex_unlock(&(i_inst->_smutex)); + unlockResource(i_inst); return (f==UIP_CLOSED)?NyLPC_TBool_FALSE:NyLPC_TBool_TRUE; } - NyLPC_cMutex_unlock(&(i_inst->_smutex)); + unlockResource(i_inst); return NyLPC_TBool_FALSE; } @@ -453,17 +459,17 @@ static NyLPC_TInt32 sendWithRetransmit(NyLPC_TcTcpSocket_t* i_inst,NyLPC_TUInt8 return -1; } }; - NyLPC_cMutex_lock(&(i_inst->_smutex)); + lockResource(i_inst); //ペイロードがある場合のみ、相手のwindowサイズが0以上になるのを待つ。 if(i_len>0){ while(i_inst->uip_connr.peer_win==0){ - NyLPC_cMutex_unlock(&(i_inst->_smutex)); + unlockResource(i_inst); //時間切れならエラー。 if(NyLPC_cStopwatch_isExpired(i_timer)){ return -1; } NyLPC_cThread_yield(); - NyLPC_cMutex_lock(&(i_inst->_smutex)); + lockResource(i_inst); } } //送信キューの取得 @@ -471,7 +477,7 @@ static NyLPC_TInt32 sendWithRetransmit(NyLPC_TcTcpSocket_t* i_inst,NyLPC_TUInt8 //送信キューが取れなかった。 if(txq==NULL){ //シーケンス番号をロールバックできないので、エラーとする。 - NyLPC_cMutex_unlock(&(i_inst->_smutex)); + unlockResource(i_inst); NyLPC_cUipService_releaseTxBuf(buf); return -1; } @@ -505,7 +511,7 @@ static NyLPC_TInt32 sendWithRetransmit(NyLPC_TcTcpSocket_t* i_inst,NyLPC_TUInt8 i_inst->uip_connr.peer_win-=s; //ACK番号の返却 *o_ack=txq->ackno=NyLPC_HTONL(next_ack); - NyLPC_cMutex_unlock(&(i_inst->_smutex)); + unlockResource(i_inst); NyLPC_cUipService_sendIPv4Tx(buf); return s; } @@ -529,11 +535,11 @@ static void sendRst(NyLPC_TcTcpSocket_t* i_inst) do{ buf=NyLPC_cUipService_allocTxBuf((SIZE_OF_IPv4_TCPIP_HEADER)+5,&s); }while(buf==NULL); - NyLPC_cMutex_lock(&(i_inst->_smutex)); + lockResource(i_inst); NyLPC_cIPv4Payload_setTxBuf(&ipv4,buf); i_inst->uip_connr.snd_nxt32++; setPacket(i_inst,&ipv4,TCP_RST|TCP_ACK,buf,0); - NyLPC_cMutex_unlock(&(i_inst->_smutex)); + unlockResource(i_inst); NyLPC_cUipService_sendIPv4Tx(buf); NyLPC_cUipService_releaseTxBuf(buf); @@ -606,12 +612,12 @@ NyLPC_TBool NyLPC_cTcpSocket_accept(NyLPC_TcTcpSocket_t* i_inst,NyLPC_TUInt32 i_ } } //ロックして、強制的なステータス遷移 - NyLPC_cMutex_lock(&(i_inst->_smutex)); + lockResource(i_inst); f=i_inst->tcpstateflags; if(f!=UIP_CLOSED){ i_inst->tcpstateflags=UIP_CLOSED; } - NyLPC_cMutex_unlock(&(i_inst->_smutex)); + unlockResource(i_inst); //もし、強制CLOSE遷移であれば、RSTも送信。 if(f!=UIP_CLOSED){ sendRst(i_inst); @@ -640,12 +646,12 @@ NyLPC_TInt32 NyLPC_cTcpSocket_precv(NyLPC_TcTcpSocket_t* i_inst,const void** o_b //読み出しバッファ情報のコピー //MUTEX LOCK - NyLPC_cMutex_lock(&(i_inst->_smutex)); + lockResource(i_inst); st=i_inst->tcpstateflags; rlen=NyLPC_cFifoBuffer_getLength(&(i_inst->rxbuf)); *o_buf_ptr=NyLPC_cFifoBuffer_getPtr(&(i_inst->rxbuf)); //MUTEX UNLOCK - NyLPC_cMutex_unlock(&(i_inst->_smutex)); + unlockResource(i_inst); //バッファが空の場合は、ステータスチェック。ESTABLISHEDでなければ、エラー(PASVCLOSE等の場合) switch(st){ @@ -698,14 +704,14 @@ void NyLPC_cTcpSocket_pseek(NyLPC_TcTcpSocket_t* i_inst,NyLPC_TUInt16 i_seek) }while(buf==NULL); //MUTEX LOCK - NyLPC_cMutex_lock(&(i_inst->_smutex)); + lockResource(i_inst); //受信バッファを読み出しシーク NyLPC_cFifoBuffer_pop(&(i_inst->rxbuf),i_seek); //ACKパケットの生成 NyLPC_cIPv4Payload_setTxBuf(&ipv4payload,buf); setPacket(i_inst,&ipv4payload,TCP_ACK,buf,0); - NyLPC_cMutex_unlock(&(i_inst->_smutex)); + unlockResource(i_inst); //ACK送信 NyLPC_cUipService_sendIPv4Tx(buf); NyLPC_cUipService_releaseTxBuf(buf); @@ -739,11 +745,12 @@ void* NyLPC_cTcpSocket_allocSendBuf(NyLPC_TcTcpSocket_t* i_inst,NyLPC_TUInt16 i_ } } -//ここ、要求サイズとpeerのwinのうち、小さいほうを割り当てたほうが良くない? - NyLPC_cMutex_lock(&(i_inst->_smutex)); +//@todo 前段処理と順番を入れ替えて、要求サイズとpeerのwinのうち、小さいほうを割り当てたほうが良くない? +//ここで相手のwin待ちをする理由は、相手に確実に受け取れるサイズを決定する為。 + lockResource(i_inst); //ペイロードがある場合のみ、相手のwindowサイズが0以上になるのを待つ。 while(i_inst->uip_connr.peer_win==0){ - NyLPC_cMutex_unlock(&(i_inst->_smutex)); + unlockResource(i_inst); //ESTABLISHED以外に非同期遷移 orタイムアウト確認 if(NyLPC_cStopwatch_isExpired(&sw)||(i_inst->tcpstateflags!=UIP_ESTABLISHED)){ NyLPC_cUipService_releaseTxBuf(buf); @@ -751,7 +758,7 @@ void* NyLPC_cTcpSocket_allocSendBuf(NyLPC_TcTcpSocket_t* i_inst,NyLPC_TUInt16 i_ return NULL; } NyLPC_cThread_yield(); - NyLPC_cMutex_lock(&(i_inst->_smutex)); + lockResource(i_inst); } //送信バッファを基準とした送信サイズを計算 s-=SIZE_OF_IPv4_TCPIP_HEADER; @@ -763,7 +770,7 @@ void* NyLPC_cTcpSocket_allocSendBuf(NyLPC_TcTcpSocket_t* i_inst,NyLPC_TUInt16 i_ if(i_inst->uip_connr.peer_winuip_connr.peer_win; } - NyLPC_cMutex_unlock(&(i_inst->_smutex)); + unlockResource(i_inst); //バッファサイズ確定。 *o_buf_size=s; NyLPC_cStopwatch_finalize(&sw); @@ -806,13 +813,13 @@ NyLPC_TBool NyLPC_cTcpSocket_psend(NyLPC_TcTcpSocket_t* i_inst,void* i_buf_ptr,i //先頭ポインタは、i_buf-sizeof(SIZE_OF_IPv4_TCPIP_HEADER)固定 buf=(NyLPC_TUInt8*)i_buf_ptr-SIZE_OF_IPv4_TCPIP_HEADER; - NyLPC_cMutex_lock(&(i_inst->_smutex)); + lockResource(i_inst); //送信キューの取得 txq=getTxQ(i_inst,&sw); //送信キューが取れなかった。 if(txq==NULL){ //シーケンス番号をロールバックできないので、エラーとする。 - NyLPC_cMutex_unlock(&(i_inst->_smutex)); + unlockResource(i_inst); NyLPC_cStopwatch_finalize(&sw); return NyLPC_TBool_FALSE; } @@ -835,7 +842,7 @@ NyLPC_TBool NyLPC_cTcpSocket_psend(NyLPC_TcTcpSocket_t* i_inst,void* i_buf_ptr,i i_inst->uip_connr.peer_win-=i_len; //ACK番号の返却 txq->ackno=NyLPC_HTONL(i_inst->uip_connr.snd_nxt32); - NyLPC_cMutex_unlock(&(i_inst->_smutex)); + unlockResource(i_inst); NyLPC_cUipService_sendIPv4Tx(buf); NyLPC_cStopwatch_finalize(&sw); return NyLPC_TBool_TRUE; @@ -875,7 +882,7 @@ void NyLPC_cTcpSocket_close(NyLPC_TcTcpSocket_t* i_inst,NyLPC_TUInt32 i_wait_in_ NyLPC_TUInt32 sq; NyLPC_cStopwatch_initialize(&sw); NyLPC_cStopwatch_startExpire(&sw,i_wait_in_msec); - NyLPC_cMutex_lock(&(i_inst->_smutex)); + lockResource(i_inst); f=i_inst->tcpstateflags; //ステータスチェック @@ -888,7 +895,7 @@ void NyLPC_cTcpSocket_close(NyLPC_TcTcpSocket_t* i_inst,NyLPC_TUInt32 i_wait_in_ //アクティブクローズ。 i_inst->tcpstateflags=UIP_FIN_WAIT_1; //送信のために一旦解除 - NyLPC_cMutex_unlock(&(i_inst->_smutex)); + unlockResource(i_inst); //FINの送信 if(sendWithRetransmit(i_inst,TCP_FIN|TCP_ACK,NULL,0,&sw,&sq)==0){ //ちょっと待つ。 @@ -896,7 +903,7 @@ void NyLPC_cTcpSocket_close(NyLPC_TcTcpSocket_t* i_inst,NyLPC_TUInt32 i_wait_in_ //TXの消去待ち if(waitForTxRemove(i_inst,sq,&sw)){ //再ロック - NyLPC_cMutex_lock(&(i_inst->_smutex)); + lockResource(i_inst); //タイムアウトするか、UIP_CLOSED、もしくはTIME_WAITに遷移するのを待つ。(遷移はRxprocで自動的に実行。) while(!NyLPC_cStopwatch_isExpired(&sw)){ switch(i_inst->tcpstateflags) @@ -911,14 +918,14 @@ void NyLPC_cTcpSocket_close(NyLPC_TcTcpSocket_t* i_inst,NyLPC_TUInt32 i_wait_in_ case UIP_FIN_WAIT_2: case UIP_CLOSING: //一時的なアンロック - NyLPC_cMutex_unlock(&(i_inst->_smutex)); + unlockResource(i_inst); NyLPC_cThread_yield(); - NyLPC_cMutex_lock(&(i_inst->_smutex)); + lockResource(i_inst); default: break; } } - NyLPC_cMutex_unlock(&(i_inst->_smutex)); + unlockResource(i_inst); } } break; @@ -926,41 +933,41 @@ void NyLPC_cTcpSocket_close(NyLPC_TcTcpSocket_t* i_inst,NyLPC_TUInt32 i_wait_in_ //LAST_ACKへ遷移 i_inst->tcpstateflags=UIP_LAST_ACK; //送信のために一旦解除 - NyLPC_cMutex_unlock(&(i_inst->_smutex)); + unlockResource(i_inst); if(sendWithRetransmit(i_inst,TCP_FIN|TCP_ACK,NULL,0,&sw,&sq)==0){ //ちょっと待つ。 NyLPC_cThread_yield(); //TXの消去待ち if(waitForTxRemove(i_inst,sq,&sw)){ //再ロック - NyLPC_cMutex_lock(&(i_inst->_smutex)); + lockResource(i_inst); //TX消去後にCLOSEDに遷移していればOK if(i_inst->tcpstateflags==UIP_CLOSED) { NyLPC_Assert(i_inst->txbuf.rp==i_inst->txbuf.wp); goto ReturnWithUnlock; } - NyLPC_cMutex_unlock(&(i_inst->_smutex)); + unlockResource(i_inst); } } //エラー。RSTで切断。 break; default: - NyLPC_cMutex_unlock(&(i_inst->_smutex)); + unlockResource(i_inst); NyLPC_Warning(); break; } - if(i_inst->_smutex._lock_count>0){ - NyLPC_Warning(); - } +// if(i_inst->_smutex._lock_count>0){ +// NyLPC_Warning(); +// } //このパスに到達するのは、FIN送信/ACKに成功したにも拘らず、規定時間内にCLOSEDに遷移しなかった場合。 //コネクションを強制遷移して、RST - NyLPC_cMutex_lock(&(i_inst->_smutex)); + lockResource(i_inst); f=i_inst->tcpstateflags; if(f!=UIP_CLOSED){ i_inst->tcpstateflags=UIP_CLOSED; } - NyLPC_cMutex_unlock(&(i_inst->_smutex)); + unlockResource(i_inst); //もし、強制CLOSE遷移であれば、RSTも送信。 if(f!=UIP_CLOSED){ sendRst(i_inst); @@ -968,14 +975,14 @@ void NyLPC_cTcpSocket_close(NyLPC_TcTcpSocket_t* i_inst,NyLPC_TUInt32 i_wait_in_ NyLPC_cStopwatch_finalize(&sw); return; ReturnWithUnlock: - NyLPC_cMutex_unlock(&(i_inst->_smutex)); + unlockResource(i_inst); NyLPC_cStopwatch_finalize(&sw); return; } /** * 定期的に実行する関数。最低でも1s単位で実行してください。 - * 動作 + * uipサービスタスクが実行する関数です。 */ void NyLPC_cTcpSocket_periodic( NyLPC_TcTcpSocket_t* i_inst) @@ -988,17 +995,17 @@ void NyLPC_cTcpSocket_periodic( NyLPC_cStopwatch_initialize(&sw); now=NyLPC_cStopwatch_now(); //MUTEX LOCK - NyLPC_cMutex_lock(&(i_inst->_smutex)); + lockResource(i_inst); if(i_inst->tcpstateflags==UIP_CLOSED) { //CLOSEDなら、バッファ開放。 resetTxQWithUnlock(i_inst); }else if(i_inst->txbuf.rp==i_inst->txbuf.wp){ //再送信パケットがなければ何もしないよ。 - NyLPC_cMutex_unlock(&(i_inst->_smutex)); + unlockResource(i_inst); }else if(i_inst->uip_connr.peer_win==0){ //peer_winが0の場合は何もしない。 - NyLPC_cMutex_unlock(&(i_inst->_smutex)); + unlockResource(i_inst); }else{ //再送信処理 rp=i_inst->txbuf.rp; @@ -1020,10 +1027,10 @@ void NyLPC_cTcpSocket_periodic( for(i=rp;i!=i_inst->txbuf.wp;i=(i+1)%NyLPC_TcTcpSocket_NUMBER_OF_TXQ){ NyLPC_cUipService_sendIPv4Tx(NyLPC_cIPv4Payload_getBuf(&(q[i].data))); } - NyLPC_cMutex_unlock(&(i_inst->_smutex)); + unlockResource(i_inst); } }else{ - NyLPC_cMutex_unlock(&(i_inst->_smutex)); + unlockResource(i_inst); } } NyLPC_cStopwatch_finalize(&sw); @@ -1060,7 +1067,7 @@ NyLPC_TBool NyLPC_cTcpSocket_parseRx( tcp_data_offset=o_ipp->payload.rawbuf+tmp16; //インスタンスをロックする。 - NyLPC_cMutex_lock(&(i_inst->_smutex)); + lockResource(i_inst); //RSTのチェック。RST受信時は、状態にかかわらず、CLOSEDステータスに移行する。 if (in_tcpflag & TCP_RST) @@ -1197,7 +1204,7 @@ NyLPC_TBool NyLPC_cTcpSocket_parseRx( }else{ ret=NyLPC_TBool_FALSE; } - NyLPC_cMutex_unlock(&(i_inst->_smutex)); + unlockResource(i_inst); //取り外したTXメモリの開放 for(i=0;i_smutex)); + unlockResource(i_inst); NyLPC_Trace(); return NyLPC_TBool_FALSE; } diff --git a/lib/src/uip/NyLPC_cTcpSocket.h b/lib/src/uip/NyLPC_cTcpSocket.h index 0322eaf..33a4426 100644 --- a/lib/src/uip/NyLPC_cTcpSocket.h +++ b/lib/src/uip/NyLPC_cTcpSocket.h @@ -65,8 +65,8 @@ struct uip_conn NyLPC_TUInt16 rport; /**< The local remote TCP port, in network byte order. */ NyLPC_TUInt32 rcv_nxt32; /**< The sequence number that we expect to receive next. */ NyLPC_TUInt32 snd_nxt32; /**< 送信用sqカウンター*/ - NyLPC_TUInt16 peer_mss; /**< PeerのMSS*/ - NyLPC_TUInt16 default_mss; /**< Peerの初期MMS*/ + NyLPC_TUInt16 peer_mss; /**< PeerのMSS*/ + NyLPC_TUInt16 default_mss; /**< Peerの初期MMS*/ /**Peerのウインドウサイズ*/ NyLPC_TUInt16 peer_win; NyLPC_TUInt16 _padding; @@ -89,6 +89,11 @@ struct uip_conn /** * uipサービスを使用したTCPソケットクラスです。 + * この関数は2つのタスクから呼び出されます。 + * [uipTask] -> [cTcpSocket] <- [Application] + * ApplicationとuipTaskとの間での排他処理はインスタンスで制御されています。 + * Application側からのコールは内部でuipTaskとの間で排他処理を実行します。 + * Application側からのコールはリエントラントではありません。 */ struct NyLPC_TcTcpSocket @@ -105,8 +110,8 @@ struct NyLPC_TcTcpSocket struct NyLPC_TcTcpSocket_TxQItem txq[NyLPC_TcTcpSocket_NUMBER_OF_TXQ]; }txbuf; volatile NyLPC_TUInt8 tcpstateflags; /**< TCP state and flags. */ - - NyLPC_TcMutex_t _smutex; + /** 共通MUTEXへのポインタ(うまくいtったらこのままで)*/ + NyLPC_TcMutex_t* _smutex; }; /** diff --git a/lib/src/uip/NyLPC_cTcpSocket_protected.h b/lib/src/uip/NyLPC_cTcpSocket_protected.h index 3f3b112..68c1a18 100644 --- a/lib/src/uip/NyLPC_cTcpSocket_protected.h +++ b/lib/src/uip/NyLPC_cTcpSocket_protected.h @@ -63,6 +63,7 @@ void NyLPC_cTcpSocket_initConnection(NyLPC_TcTcpSocket_t* i_inst,const NyLPC_TcI /** * TCPペイロードを処理して、応答パケットをペイロードに返します。 + * uipサービスタスクが実行する関数です。 * @return * 応答ペイロードの有無を返します。 */ @@ -71,6 +72,13 @@ NyLPC_TBool NyLPC_cTcpSocket_parseRx( NyLPC_TcIPv4Payload_t* o_ipp); /** + * 定期的に実行する関数。最低でも1s単位で実行してください。 + * uipサービスタスクが実行する関数です。 + */ +void NyLPC_cTcpSocket_periodic( + NyLPC_TcTcpSocket_t* i_inst); + +/** * ソケットをlisten済みにマークします。cTcpListenerからコールします。 */ NyLPC_TBool NyLPC_cTcpSocket_setSynPayload(NyLPC_TcTcpSocket_t* i_inst,const NyLPC_TcIPv4Config_t* i_config,const NyLPC_TcIPv4Payload_t* i_ipp); diff --git a/lib/src/uip/NyLPC_cUipService_protected.h b/lib/src/uip/NyLPC_cUipService_protected.h index 3ec5aa2..ba8b92c 100644 --- a/lib/src/uip/NyLPC_cUipService_protected.h +++ b/lib/src/uip/NyLPC_cUipService_protected.h @@ -56,7 +56,7 @@ struct NyLPC_TcUipService NyLPC_TcIPv4_t _tcpv4; /** ICOMP処理インスタンス*/ NyLPC_TcIPv4IComp_t _icomp; - /** 排他制御用*/ + /** (Ethernetメモリ排他制御用)*/ NyLPC_TcMutex_t _mutex; const struct TiEthernetDevice* _ethif; /** ipタスクが使う小サイズ送信バッファ*/ -- 2.11.0