Hi
I’m trying to implement a socket server in a legato app where I, for each accepted connection spawn a control and an event thread. The control thread will start reading from the socket and act upon the received commands whereas the event thread is meant for forwarding different events through the socket.
My problem is now that when the control thread determines that the socket has been closed, it signals to the event thread that it must shut down, and then the thought is to wait for a semaphore before it actually closes the socket.
My problem is that as soon as I let the read thread wait for the semaphore it segmentation faults.
Can someone help me figure out what is wrong:
typedef struct context_t
{
int connfd;
bool shutdownEventLoop;
le_sem_Ref_t waitForEventLoopToClose;
} context_t;
void* connection_control(void *context)
{
...
while(1)
{
int read_bytes = read(connected_context->connfd, Buff, 1000);
if (read_bytes > 0)
{
handle_inpacket(connected_context, Buff, read_bytes);
}
else
{
LE_INFO("Socket disconnected, closing down threads");
LE_INFO("Informing event thread that it must close");
connected_context->shutdownEventLoop = true;
LE_INFO("Waiting for event thread to exit");
le_sem_Wait(connected_context->waitForEventLoopToClose);
LE_INFO("event thread exited, deleting semaphore");
le_sem_Delete(connected_context->waitForEventLoopToClose);
LE_INFO("closing socket");
close(connected_context->connfd);
LE_INFO("exiting control thread");
le_thread_Exit((void*) connected_context);
return (void*) connected_context;
}
sleep(1);
}
void* connection_event(void *context)
{
context_t* connected_context = (context_t*) context;
LE_INFO("Started event thread");
while(1)
{
if (connected_context->shutdownEventLoop)
{
LE_INFO("Closing down event thread");
le_sem_Post(connected_context->waitForEventLoopToClose);
le_thread_Exit((void*) connected_context);
return (void*) connected_context;
}
sleep(1);
}
}
main()
{
...
context_t connected_context;
memset(&connected_context, 0, sizeof(context_t));
connected_context.connfd = accept(listenfd, (struct sockaddr*)NULL, NULL);
connected_context.waitForEventLoopToClose = le_sem_Create("waitForEventLoopToClose", 0);
le_thread_Ref_t con_conn_thread = le_thread_Create("connection_controlThread", connection_control, (void*) &connected_context);
le_thread_Ref_t event_conn_thread = le_thread_Create("connection_EventThread", connection_event, (void*) &connected_context);
le_thread_Start(con_conn_thread);
le_thread_Start(event_conn_thread);
}