Hello,
I am working on a shared socket solution where one task sends and one task receives data from a shared socket. I used the contest.c for the starting point and I realized that something is wrong with fdshare(). Each time when I instantiate a new rx and tx tasks and using fdShare in them, the HeapMemory is increasing more and more.
Could you help me why?
I have attached the whole project. For the tests you can use the tcpSendReceive.exe in the ti package.
Some hint: When I remove the fdShare from the code, I can run it without any error for a while.
Looking forward your kind reply,
And here is the code also,
#include <string.h>
#include <xdc/std.h>
#include <xdc/runtime/Error.h>
#include <xdc/runtime/System.h>
#include <ti/sysbios/BIOS.h>
#include <ti/sysbios/knl/Task.h>
#include <ti/drivers/GPIO.h>
#include <ti/sysbios/knl/Mailbox.h>
#include <xdc/cfg/global.h>
/* NDK BSD support */
#include <sys/socket.h>
/* Example/Board Header file */
#include "Board.h"
#define TCPPACKETSIZE 256
#define NUMTCPWORKERS 3
typedef struct mbdata{
uint8_t code;
uint8_t buff[TCPPACKETSIZE];
}Mbdata_t;
/*
* ======== tcpWorker ========
* Task to handle TCP connection. Can be multiple Tasks running
* this function.
*/
Void tcpWorker(UArg arg0, UArg arg1)
{
int clientfd = (int)arg0;
int bytesRcvd;
char buffer[TCPPACKETSIZE];
int bytesSent;
if(fdShare((SOCKET)clientfd)){
System_printf("share failed\n");
System_flush();
}
Mbdata_t mbData = {.code = 7};
while ((bytesRcvd = recv(clientfd, buffer, TCPPACKETSIZE, 0)) > 0) {
/*
bytesSent = send(clientfd, buffer, TCPPACKETSIZE, 0);
if (bytesSent < 0 || bytesSent != TCPPACKETSIZE) {
System_printf("Error: send failed: %d.\n",bytesSent);
System_flush();
break;
}
*/
memcpy(mbData.buff,buffer,TCPPACKETSIZE);
Mailbox_post(transmitMb,&mbData,BIOS_WAIT_FOREVER);
}
mbData.code = 6;
Mailbox_post(transmitMb,&mbData,BIOS_WAIT_FOREVER);
if(fdClose((SOCKET)clientfd)){
System_printf("fdClose failed\n");
System_flush();
}
}
Void tcptransmit(UArg arg0, UArg arg1)
{
int clientfd = (int)arg0;
int bytesSent;
Mbdata_t mbData;
if(fdShare((SOCKET)clientfd)){
System_printf("share failed\n");
System_flush();
}
while(1){
Mailbox_pend(transmitMb,&mbData,BIOS_WAIT_FOREVER);
if(mbData.code == 6)
break;
else{
bytesSent = send(clientfd, mbData.buff, TCPPACKETSIZE, 0);
if (bytesSent < 0 || bytesSent != TCPPACKETSIZE) {
System_printf("Error: send failed: %d.\n",bytesSent);
System_flush();
break;
}
}
}
if(fdClose((SOCKET)clientfd)){
System_printf("fdClose failed\n");
System_flush();
}
System_printf("transmit ended\n");
System_flush();
}
/*
* ======== tcpHandler ========
* Creates new Task to handle new TCP connections.
*/
Void tcpHandler(UArg arg0, UArg arg1)
{
int status;
int clientfd;
int server;
struct sockaddr_in localAddr;
struct sockaddr_in clientAddr;
int optval;
int optlen = sizeof(optval);
socklen_t addrlen = sizeof(clientAddr);
Task_Handle taskHandle;
Task_Params taskParams;
Error_Block eb;
server = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (server == -1) {
System_printf("Error: socket not created.\n");
goto shutdown;
}
memset(&localAddr, 0, sizeof(localAddr));
localAddr.sin_family = AF_INET;
localAddr.sin_addr.s_addr = htonl(INADDR_ANY);
localAddr.sin_port = htons(arg0);
status = bind(server, (struct sockaddr *)&localAddr, sizeof(localAddr));
if (status == -1) {
System_printf("Error: bind failed.\n");
goto shutdown;
}
status = listen(server, NUMTCPWORKERS);
if (status == -1) {
System_printf("Error: listen failed.\n");
goto shutdown;
}
optval = 1;
if (setsockopt(server, SOL_SOCKET, SO_KEEPALIVE, &optval, optlen) < 0) {
System_printf("Error: setsockopt failed\n");
goto shutdown;
}
/*
struct timeval tv;
tv.tv_sec = 3;
tv.tv_usec = 0;
if (setsockopt(server, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)) < 0) {
System_printf("Error: setsockopt failed\n");
goto shutdown;
}
*/
while ((clientfd = accept(server, (struct sockaddr *)&clientAddr, &addrlen)) != -1) {
//System_printf("tcpHandler: Creating thread clientfd = %d\n", clientfd);
/* Init the Error_Block */
Error_init(&eb);
/* Initialize the defaults and set the parameters. */
Task_Params_init(&taskParams);
taskParams.arg0 = (UArg)clientfd;
taskParams.stackSize = 2048;
taskHandle = Task_create((Task_FuncPtr)tcpWorker, &taskParams, &eb);
if (taskHandle == NULL) {
System_printf("Error: Failed to create new Task\n");
close(clientfd);
}
Task_Params_init(&taskParams);
taskParams.arg0 = (UArg)clientfd;
taskParams.stackSize = 2048;
taskHandle = Task_create((Task_FuncPtr)tcptransmit, &taskParams, &eb);
if (taskHandle == NULL) {
System_printf("Error: Failed to create new Task\n");
close(clientfd);
}
/* addrlen is a value-result param, must reset for next accept call */
addrlen = sizeof(clientAddr);
}
System_printf("Error: accept failed.\n");
System_flush();
shutdown:
if (server > 0) {
close(server);
}
}
/*
* ======== main ========
*/
int main(void)
{
/* Call board init functions */
Board_initGeneral();
Board_initGPIO();
Board_initEMAC();
System_printf("Starting the TCP Echo example\nSystem provider is set to "
"SysMin. Halt the target to view any SysMin contents in"
" ROV.\n");
/* SysMin will only print to the console when you call flush or exit */
System_flush();
/* Start BIOS */
BIOS_start();
return (0);
}