Skip to content

Commit 9d99586

Browse files
phoddiemkellner
authored andcommitted
allow read to be called outside of callback
1 parent f8e188d commit 9d99586

File tree

1 file changed

+86
-110
lines changed

1 file changed

+86
-110
lines changed

modules/network/socket/lwip/modSocket.c

Lines changed: 86 additions & 110 deletions
Original file line numberDiff line numberDiff line change
@@ -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)
11081120
void 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

12411213
void 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

Comments
 (0)