@@ -91,6 +91,7 @@ struct xsSocketRecord {
9191
9292 unsigned char * buf ;
9393 struct pbuf * pb ;
94+ struct pbuf * pbWalker ;
9495 uint16 bufpos ;
9596 uint16 buflen ;
9697 uint16 port ;
@@ -820,12 +821,23 @@ void xs_socket_read(xsMachine *the)
820821 xss -> bufpos += srcBytes ;
821822
822823 if (xss -> bufpos == xss -> buflen ) {
823- if (xss -> pb )
824+ if (xss -> pbWalker -> next )
825+ socketSetPending (xss , kPendingReceive );
826+ else {
824827 pbuf_free_safe (xss -> pb );
825- xss -> pb = NULL ;
828+ xss -> pb = NULL ;
829+ xss -> pbWalker = NULL ;
826830
827- xss -> bufpos = xss -> buflen = 0 ;
828- xss -> buf = NULL ;
831+ xss -> bufpos = xss -> buflen = 0 ;
832+ xss -> buf = NULL ;
833+
834+ if (xss -> reader [0 ]) {
835+ modLog ("READ - schedule next readable" );
836+ socketSetPending (xss , kPendingReceive );
837+ }
838+ else if (xss -> suspendedDisconnect )
839+ socketSetPending (xss , kPendingDisconnect );
840+ }
829841 }
830842}
831843
@@ -1108,134 +1120,94 @@ void socketMsgError(xsSocket xss)
11081120void socketMsgDataReceived (xsSocket xss )
11091121{
11101122 xsMachine * the = xss -> the ;
1111- unsigned char i , readerCount ;
1112- uint16_t tot_len , bufpos = 0 ;
1113- struct pbuf * pb , * walker ;
1114- uint8_t one = 0 ;
1123+ struct pbuf * pb ;
1124+ uint8_t i ;
11151125
1116- if (xss -> suspended )
1117- return ;
1126+ if (xss -> buflen && (xss -> bufpos < xss -> buflen ))
1127+ return ; // haven't finished reading current pbuf
1128+
1129+ if (xss -> pb ) {
1130+ if (xss -> pbWalker -> next ) {
1131+ xss -> pbWalker = xss -> pbWalker -> next ;
1132+
1133+ xss -> buf = xss -> pbWalker -> payload ;
1134+ xss -> bufpos = 0 ;
1135+ xss -> buflen = xss -> pbWalker -> len ;
1136+
1137+ goto callback ;
1138+ }
1139+
1140+ pbuf_free_safe (xss -> pb );
1141+ xss -> pb = NULL ;
1142+ xss -> pbWalker = NULL ;
1143+ xss -> buflen = 0 ;
1144+ }
11181145
11191146 modCriticalSectionBegin ();
1120- for (readerCount = 0 ; xss -> reader [readerCount ] && (readerCount < kReadQueueLength ); readerCount ++ )
1121- ;
1122- modCriticalSectionEnd ();
11231147
1124- if (xss -> suspendedBuf ) {
1125- pb = xss -> suspendedBuf ;
1126- walker = xss -> suspendedFragment ;
1127- bufpos = xss -> suspendedBufpos ;
1128- xss -> suspendedBuf = xss -> suspendedFragment = NULL ;
1129- readerCount += 1 ;
1130- goto resumeBuffer ;
1148+ pb = xss -> reader [0 ];
1149+ if (NULL == pb ) {
1150+ modCriticalSectionEnd (); // no more to read
1151+ return ;
11311152 }
11321153
1133- while (readerCount -- ) {
1134- modCriticalSectionBegin ();
1135- pb = xss -> reader [0 ];
1136- if (!pb ) {
1137- modCriticalSectionEnd ();
1138- break ;
1139- }
1154+ for (i = 0 ; i < kReadQueueLength - 1 ; i ++ )
1155+ xss -> reader [i ] = xss -> reader [i + 1 ];
1156+ xss -> reader [kReadQueueLength - 1 ] = NULL ;
11401157
1141- for (i = 0 ; i < kReadQueueLength - 1 ; i ++ )
1142- xss -> reader [i ] = xss -> reader [i + 1 ];
1143- xss -> reader [kReadQueueLength - 1 ] = NULL ;
1144- modCriticalSectionEnd ();
1158+ modCriticalSectionEnd ();
11451159
1146- walker = pb ;
1147- resumeBuffer :
1148- xsBeginHost (the );
1160+ xss -> pb = pb ;
1161+ xss -> pbWalker = pb ;
1162+ xss -> buf = pb -> payload ;
1163+ xss -> bufpos = 0 ;
1164+ xss -> buflen = pb -> len ;
11491165
1150- tot_len = pb -> tot_len ;
1166+ if (kTCP == xss -> kind )
1167+ tcp_recved_safe (xss , pb -> tot_len );
11511168
1152- if (NULL == pb -> next ) {
1153- one = 1 ;
1154- xss -> pb = pb ;
1155- }
1169+ callback :
1170+ xsBeginHost (the );
11561171
1157- for (; walker && !xss -> suspended ; walker = walker -> next ) {
1158- xss -> buf = walker -> payload ;
1159- xss -> bufpos = bufpos ;
1160- xss -> buflen = walker -> len ;
1161- bufpos = 0 ;
1172+ if (kTCP == xss -> kind ) {
11621173
1163- xsTry {
1164- if (kTCP == xss -> kind ) {
11651174#if !ESP32
1166- system_soft_wdt_stop (); //@@
1175+ system_soft_wdt_stop (); //@@
11671176#endif
1168- xsCall2 (xss -> obj , xsID_callback , xsInteger (kSocketMsgDataReceived ), xsInteger (xss -> buflen - xss -> bufpos ));
1177+ xsCall2 (xss -> obj , xsID_callback , xsInteger (kSocketMsgDataReceived ), xsInteger (xss -> buflen ));
11691178#if !ESP32
1170- system_soft_wdt_restart (); //@@
1179+ system_soft_wdt_restart (); //@@
11711180#endif
1172- }
1173- else {
1174- ip_addr_t address = xss -> remote [0 ].address ;
1175- char * out ;
1181+ }
1182+ else {
1183+ ip_addr_t address = xss -> remote [0 ].address ;
1184+ char * out ;
1185+ uint16_t port = xss -> remote [0 ].port ;
11761186
1177- xsResult = xsStringBuffer (NULL , 4 * 5 );
1178- out = xsmcToString (xsResult );
1187+ xsResult = xsStringBuffer (NULL , 4 * 5 );
1188+ out = xsmcToString (xsResult );
11791189#if LWIP_IPV4 && LWIP_IPV6
1180- itoa (ip4_addr1 (& address .u_addr .ip4 ), out , 10 ); out += strlen (out ); * out ++ = '.' ;
1181- itoa (ip4_addr2 (& address .u_addr .ip4 ), out , 10 ); out += strlen (out ); * out ++ = '.' ;
1182- itoa (ip4_addr3 (& address .u_addr .ip4 ), out , 10 ); out += strlen (out ); * out ++ = '.' ;
1183- itoa (ip4_addr4 (& address .u_addr .ip4 ), out , 10 ); out += strlen (out ); * out = 0 ;
1190+ itoa (ip4_addr1 (& address .u_addr .ip4 ), out , 10 ); out += strlen (out ); * out ++ = '.' ;
1191+ itoa (ip4_addr2 (& address .u_addr .ip4 ), out , 10 ); out += strlen (out ); * out ++ = '.' ;
1192+ itoa (ip4_addr3 (& address .u_addr .ip4 ), out , 10 ); out += strlen (out ); * out ++ = '.' ;
1193+ itoa (ip4_addr4 (& address .u_addr .ip4 ), out , 10 ); out += strlen (out ); * out = 0 ;
11841194#else
1185- itoa (ip4_addr1 (& address ), out , 10 ); out += strlen (out ); * out ++ = '.' ;
1186- itoa (ip4_addr2 (& address ), out , 10 ); out += strlen (out ); * out ++ = '.' ;
1187- itoa (ip4_addr3 (& address ), out , 10 ); out += strlen (out ); * out ++ = '.' ;
1188- itoa (ip4_addr4 (& address ), out , 10 ); out += strlen (out ); * out = 0 ;
1195+ itoa (ip4_addr1 (& address ), out , 10 ); out += strlen (out ); * out ++ = '.' ;
1196+ itoa (ip4_addr2 (& address ), out , 10 ); out += strlen (out ); * out ++ = '.' ;
1197+ itoa (ip4_addr3 (& address ), out , 10 ); out += strlen (out ); * out ++ = '.' ;
1198+ itoa (ip4_addr4 (& address ), out , 10 ); out += strlen (out ); * out = 0 ;
11891199#endif
1190- if (kUDP == xss -> kind )
1191- xsCall4 (xss -> obj , xsID_callback , xsInteger (kSocketMsgDataReceived ), xsInteger (xss -> buflen ), xsResult , xsInteger (xss -> remote [0 ].port ));
1192- else
1193- xsCall3 (xss -> obj , xsID_callback , xsInteger (kSocketMsgDataReceived ), xsInteger (xss -> buflen ), xsResult );
1194- }
1195- }
1196- xsCatch {
1197- }
1198-
1199- if (kTCP != xss -> kind ) {
1200- xss -> remoteCount -= 1 ;
1201- c_memmove (& xss -> remote [0 ], & xss -> remote [1 ], xss -> remoteCount * sizeof (xsSocketUDPRemoteRecord ));
1202- }
1203-
1204- if (one )
1205- break ;
1206- }
1207-
1208- xsEndHost (the );
12091200
1210- if (xss -> suspended ) {
1211- if (xss -> bufpos != xss -> buflen ) {
1212- xss -> suspendedBuf = pb ;
1213- xss -> suspendedFragment = walker ;
1214- xss -> suspendedBufpos = xss -> bufpos ;
1215- }
1216- else if (!one && walker -> next ) {
1217- xss -> suspendedBuf = pb ;
1218- xss -> suspendedFragment = walker -> next ;
1219- xss -> suspendedBufpos = 0 ;
1220- }
1221- }
1222-
1223- if (xss -> skt && tot_len && !xss -> suspendedBuf )
1224- tcp_recved_safe (xss , tot_len );
1225-
1226- xss -> buf = NULL ;
1227-
1228- if (xss -> suspendedBuf )
1229- break ;
1201+ xss -> remoteCount -= 1 ;
1202+ c_memmove (& xss -> remote [0 ], & xss -> remote [1 ], xss -> remoteCount * sizeof (xsSocketUDPRemoteRecord ));
12301203
1231- if (one ) {
1232- if (xss -> pb )
1233- pbuf_free_safe (xss -> pb );
1234- xss -> pb = NULL ;
1235- }
1204+ if (kUDP == xss -> kind )
1205+ xsCall4 (xss -> obj , xsID_callback , xsInteger (kSocketMsgDataReceived ), xsInteger (xss -> buflen ), xsResult , xsInteger (port ));
12361206 else
1237- pbuf_free_safe ( pb );
1207+ xsCall3 ( xss -> obj , xsID_callback , xsInteger ( kSocketMsgDataReceived ), xsInteger ( xss -> buflen ), xsResult );
12381208 }
1209+
1210+ xsEndHost (the );
12391211}
12401212
12411213void socketMsgDataSent (xsSocket xss )
@@ -1266,7 +1238,7 @@ void didError(void *arg, err_t err)
12661238{
12671239 xsSocket xss = arg ;
12681240
1269- xss -> skt = NULL ;
1241+ xss -> skt = NULL ; // "pcb is already freed when this callback is called"
12701242 socketSetPending (xss , kPendingError );
12711243}
12721244
@@ -1303,7 +1275,10 @@ err_t didReceive(void * arg, struct tcp_pcb * pcb, struct pbuf * p, err_t err)
13031275#if ESP32
13041276 xss -> skt = NULL ; // no close on socket if disconnected.
13051277#endif
1306- socketSetPending (xss , kPendingDisconnect );
1278+ if (xss -> reader [0 ] || xss -> buflen )
1279+ xss -> suspendedDisconnect = true;
1280+ else
1281+ socketSetPending (xss , kPendingDisconnect );
13071282 }
13081283
13091284 return ERR_OK ;
@@ -1321,6 +1296,7 @@ err_t didReceive(void * arg, struct tcp_pcb * pcb, struct pbuf * p, err_t err)
13211296 if (kReadQueueLength == i ) {
13221297 modLog ("tcp read overflow!" );
13231298 pbuf_free_safe (p );
1299+ socketSetPending (xss , kPendingError ); //@@ test
13241300 return ERR_MEM ;
13251301 }
13261302
0 commit comments