signal callback and pthread sync - c

On my app I have a pthread running a while(1) that read a socket client and a serial callback function. My app receive messages from a serial (like /dev/ttyS0) and receive messages from socket. The problem: the app crash after receive some messages from serial, on this moment the socket is receiving nothing. But if I comment the thread creation the app work fine.
code draft:
// Socket Thread
static void *Socket(void *arg)
{
// socket inicialization
while (1)
{
ret = read(client, buffer, sizeof(buffer)-1);
// do something
}
}
// serial callback
static void SerialCallback(int id, unsigned char *buffer, int length)
{
// do something
}
// main
int main (void)
{
// start and configure serial callback
cssl_start();
Serial = cssl_open(SERIAL_PORT, SerialCallback, 0, 115200, 8, 0, 1);
// create the pthread
// If I comment the line below the app work fine
pthread_create(&Thread_Socket, NULL, Socket, NULL);
while (1)
{
}
}
Notes:
I use the library cssl (http://sourceforge.net/projects/cssl/) to deal with serial. This library use a real time signal.
For tests purposes I use socat to generate pseudo-terminals (like /dev/pts/XX)
The serial callback is called each time that serial receive one or more bytes
I am using the cutecom to send messages to serial
Added new tests information in 2012.07.16
First test: I replace the line of read function by a while(1); and the problem follow (so, the problem is not related with read function).
Second test: Using the full code (above example), I use two external usb/serial converter loopback connected, work rightly.

How said #Nikolai N Fetissov, the program break because EINTR signal. I looked into cssl library code and change the flags of signal, from: sa.sa_flags = SA_SIGINFO; to sa.sa_flags = SA_SIGINFO | SA_RESTART;. Worked.
I contacted Marcin Siennicki, cssl project developer, and sent the link of this post for him.
Thanks for comments.

Related

FreeRTOS: Is semaphore appropriate for a proxy MCU node communication?

I am currently trying to develop a proxy program that takes data from a SPI bus to tcp and vice versa. I would like to know if the method i intend to do is a good/intended way of utilising freertos library. The program is running as a SPI master with GPIO pin trigger from slave if slave wants to send data over as SPI can only be initiated from master.
char buffer1 [128];
char buffer2[128];
static QueueHandle_t rdySem1 //semaphore
static QueueHandle_t rdySem2 //semaphore
volatile atomic int GPIO_interrupt_pin;
void SPI_task(void* arg)
{
while(1)
{
if (GPIO_interrupt_pin)
{
//TODO:read data from SPI bus and place in buffer1
xSemaphoreGive(rdySem1);
GPIO_interrupt_pin = 0;
}
xSemaphoreTake(rdySem2, portMAX_DELAY);
//TODO:send data from buffer2[] to SPI bus
}
}
void tcp_task(void* arg)
{
while(1)
{
int len;
char rx_buffer[128];
len = recv(sock, rx_buffer, sizeof(rx_buffer) - 1, 0);
if (len>0)
{
//TODO:process data from TCP socket and place in buffer2
xSemaphoreGive(rdySem2);
}
xSemaphoreTake(rdySem1, portMAX_DELAY);
//TODO:send data from buffer1[] to TCP
}
}
//only run when GPIO pin interrupt triggers
static void isr_handler(void* arg)
{
GPIO_interrupt_pin = 1;
}
Also, i am not very familiar with how freeRTOS work but i believe xSemaphoreTake is a blocking call and it would not work in this context unless i use a non-blocking call version if xSemaphoreTake(). Any kind soul that can point me in the right direction? Much appreciate.
Your current pattern has a few problems but the fundamental idea of using semaphores can solve part of this problem. However, I think it's worth looking at restructuring your code such that each thread only waits on it's respective receive and does the complementary transmit upon reception instead of trying to pass it off to the other thread. Trying to pass, for example, both TCP-recv waiting and SPI-packet-to-TCP-send waiting, which unless you are guaranteed that first you get data over TCP to send to SPI and then you get data back, doesn't really work very well; truly asynchronous communication involves being ready to wake on either event (ie, tcp_task can't be waiting on recv when a SPI packet comes in or it may never TCP send that SPI packet until something is TCP recieved).
Instead, let the tasks only wait on their respective receiving functions and send the data to the other side immediately. If there are mutual exclusion concerns, use a mutex to guard the actual transactions. Also note that even though it's atomic, there is a risk without using test and set that GPIO_interrupt_pin might be set to 0 incorrectly if an interrupt comes between the test and the clearing of the variable. Fortunately, FreeRTOS provides nicer mechanisms in the form of task notifications to do the same thing (and the API I am using here is very much like a semaphore).
void SPI_task(void *arg)
{
while (1) {
// Wait on SPI data ready pin
ulTaskNotifyTake(0, portMAX_DELAY);
// There is spi data, can grab a mutex to avoid conflicting SPI transactions
xSemaphoreTake(spi_mutex, portMAX_DELAY);
char data[128];
spi_recv(data, sizeof(data)); //whatever the spi function is, maybe get length out of it
xSemaphoreGive(spi_mutex);
// Send the data from this thread, no need to have the other thread handle (probably)
send(sock, data, sizeof(data));
}
}
void tcp_task(void *arg)
{
while (1) {
char data[128];
int len = recv(sock, data, sizeof(data));
if (len > 0) {
// Just grab the spi mutex and do the transfer here
xSemaphoreTake(spi_mutex, portMAX_DELAY);
spi_send(data, len);
xSemaphoreGive(spi_mutex);
}
}
}
static void isr_handler(void *arg)
{
vTaskNotifyGiveFromISR(SPI_task_handle, NULL);
}
The above is a simplified example, and there's a bit more depth to go into for task notifications which you can read about here:
https://www.freertos.org/RTOS-task-notifications.html

how to restart socket properly in a multithread c/c++ program

Background: My code structure: I have a master socket on main thread, then each time a new client is coming, the threadpool will be notified and let one pre allocated thread take the task.
Inside this thread, I will pass a slave socket to it, and let it using accept call to listen to the client.
Scenario: In my thread pool, thread A is listening to a client right now, now I want to stop all the pre-allocated thread and close all the connection to the client, the main thread is trying to close the connection using close the connection to the client, and trying to terminate thread A using pthread_join.
main() {
// create threadpool
// logic to create mastersocket
startServer(masterSock)
IwantToCloseServer() // this function is not directly called in main, but simulated by a terminal signal , like kill -quit pid.
}
int startServer(int msock) {
int ssock; // slaveSocket
struct sockaddr_in client_addr; // the address of the client...
unsigned int client_addr_len = sizeof(client_addr); // ... and its length
while (!stopCondition) {
// Accept connection:
ssock = ::accept((int)msock, (struct sockaddr*)&client_addr, &client_addr_len); // the return value is a socket
// I was trying to replace this line of code to poll(), but it's not does the same thing as before
if (ssock < 0) {
if (errno == EINTR) continue;
perror("accept");
running =0;
return 0;
// exit(0);
} else {
// push task to thread pool to deal with logic
}
// main thread continues with the loop...
}
return 1;
}
IwantToCloseServer(slaveSocket) {
// when i want to close() or shutdown() function to close connections, these 2 function always return -1, because the thread is blocked on accept call
// logic try to terminate all the preallocated threads, the pthread_join function is stuck because the thread is blocked on accept
}
Problem: The thread A is keeping blocking on the ::accept function , the close and shutdown function return -1, they won’t close the connection , and the pthread_join is not keep going because thread A is blocked on accept.
Things I tried:
I have try to change my while loop related accept function, for example, set a flag stopCondition,
while(!stopConditon) {
ssock = ::accept((int)msock, (struct sockaddr*)&client_addr, &client_addr_len);
}
However, when the main thread change stopCondtion, the thread A is blocked inside the accept function.
It won’t go inside the while loop, so this solution won’t affect the accept function, it’s not working
I have also tried to send a signal to this blocked Thread A, using
pthread_cancel or pthread_kill(Thread A, 9)
However, if I do this, the whole process gets killed.
3.try to use poll() to replace the line, where the accept functions at, with a timeout
however, the program doesn't behave like before, the program can't listen to client anymore.
How do I terminate thread A (which is blocked on accept function call right now), so that I can clean this pre allocated thread and restart my server ?
btw i can not use library like boost in my current program. And this is under linux system not winsocket
to check periodically stopConditon in your while(!stopConditon) { first call accept/pool with a timeout to know if there is something new about msock, then depending on the result call accept etc else do nothing
I was trying to replace this line of code to poll()
try to use poll() to replace the line, where the accept functions at, with a timeout
you cannot replace accept by poll, you have to call accept / pool first and of course check the result then may be call accept
Out of that
while(!stopConditon) {
if(!stopCondtion) {
is redundant and can be replaced by
while(!stopConditon) {

C - Debug mode won't acknowledge callback event

I'm trying to write a simple UDP transfer program in Labwindows/CVI.
The idea is it creates 2 UDP channels, uses one to write data to a port, and the other to receive the data and print it out.
Here's the receiving end:
//Called whenever data arrives on port
int CVICALLBACK udpCallback(unsigned channel, int eventType, int errCode, void *callbackData)
{
printf("Callback called\n");
//Gets the data from port
readChannel();
return 0;
}
void createReadChannel()
{
//Channel for given port, receiving from any IP address
CreateUDPChannelConfig(port, UDP_ANY_ADDRESS, 0, NULL, NULL, &readerChannel);
//Attach callback to channel (above)
SetUDPAttribute(readerChannel, ATTR_UDP_CALLBACK, udpCallback);
printf("Read channel created\n");
}
My main problem is just that when I run it in debug mode, the shown callback function is never called, i.e. "Callback called" is not printed, not is any data stored or printed in the resulting readChannel() call.
However, when compiled and executed as an .exe, it works as intended. Every time data is received on that port the callback executes.
What difference could there be between the debug and 'release' version that would cause this to happen?
EDIT: After much testing I believe it has to do with waiting for messages using functions like getchar() which caused the main thread to hang up. Why it worked in release mode I don't know, but it probably has something to do with the difference in output window(?). My solution was to remove the callbacks and run the receiving channel on it's own thread.
This way the thread is always waiting for a message, using:
UDPRead(readerChannel, 0, 0, UDP_WAIT_FOREVER, NULL, NULL)) < 0)
And then my main thread can pick up messages as needed.
If anyone has any additional info let me know.

write()/read() in a Client/Server, pthread application in C returns -1 always when on non-main thread?

So, I have this client/server application, where the server has a producer/consumer architecture. I have 2 functions that handle writting and reading to the socket. The main thread of the server (the Producer) handles connections and passes socket descriptors via a Stack to the second thread, the Consumer, for processing.
The problem is, whenever I try to write() or read() the socket from a different-than-main thread, it always returns -1 and causes a Connection reset by peer error on client and Transport endpoint is not connected error on the server. Surpirsingly, it works perfectly when socket is read/written from the main thread.
Why does this happen? Is this official behaviour? How do I go about replying to the client with the Consumer thread? I don't believe it's because of the code I wrote, since the Consumer thread only calls the read/write-to-socket functions.
If you have any suspicion on which part could be a culprit, ask me to post some of the code.
EDIT:
typedef struct s_stack {
int * c_stack;
int base;
int top;
unsigned char is_full;
unsigned char is_empty;
int max_size;
} s_stack_t;
s_stack_t stack;
void * producer_routine(void * arguments) {
/* socket(), bind(), listen(), etc.,
socket fd on "socket_fd",
new connection fd on "new_fd" */
for(;;) {
new_fd = accept(socket_fd, (struct sockaddr *)&client_addr, &clen);
pthread_mutex_lock(&mutex);
while (stack.is_full) {
pthread_cond_wait(&stack_not_full, &mutex);
}
if (stack.is_full){
push(&stack, new_fd);
pthread_cond_signal(&stack_not_empty);
}
pthread_mutex_unlock(&mutex);
}
close(new_fd);
}
void * consumer_routine(void *args) {
for(;;) {
int socket_fd;
/* same mutex lock as above, just reversed, pop to socket_fd */
write_a_message_to_client(socket_fd);
}
}
int main() {
stack_init(&stack, 1024); // (s_stack_t * stack, int max_size)
pthread_t tidp, tidc;
int prc = pthread_create(&tidp, NULL, producer_routine, NULL);
int crc = pthread_create(&tidc, NULL, consumer_routine, NULL);
stack_destroy(&stack);
return 0;
}
The client just sends a message, and waits to receive one. If write_a_message_to_client() is called within any of those threads, even with the socket_fd passed as a parameter, I get the same errors. If it's called directly in main, it has no problem.
EDIT #2:
I tested this, and found my stack implementation to not work on Cygwin. Cygwin adds gibberish after the 3rd element for some reason, so the socket fds were invalid. Also, I was testing this in a Debian 6 VM and the server was crashing after connection from client. But I tested it in Arch, Kali and my Uni servers (Debian 7) and works as it should have been. A whole lot of trouble for a whole lot of nothing. Thanks Cygwin!
You should not call stack_destroy() until after both threads have completed. I think your entire program is running using a destroyed stack.
Use pthread_join() to wait for the threads to complete before destroying the stack.

tcp server with multiple clients sending message back to all connected clients

I have a tcp chat program: server.c and client.c.
The server is in a while(1) loop and uses select to detect clients wanting to connect on it's socket. A new thread is then created for the accepted client and its socket descriptor is given as an argument for thread: pthread_create (&thread,NULL, do_something, (void *) &socket_descriptor);
When receiving a message from a client, the server should send this message to all connected clients. (not implemented this yet).
Now I'm wondering how to do this. I absolutely need each accepted connection to be in a thread.
I was thinking of using a select inside the do_something as well; will select detect if data is incoming on the socket descriptor? Or would you do it another way?
edit: added code
my code:
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include "tcp_comm.h"
#include <sys/time.h>
#include <sys/types.h>
#define BUFSIZE 1024
#define PORT 1234
void *do_something(void *a);
int main (void){
Socket server = tcp_passive_open( PORT );
MySocket *s = (MySocket *)server;
printf("Server socked_id (main): %i", s->sd);
pthread_t thread;
fd_set active_socketDescriptors,read_socketDescriptors;
FD_ZERO(&active_socketDescriptors);
FD_SET(s->sd,&active_socketDescriptors);
while (1){
read_socketDescriptors = active_socketDescriptors;
if (select (FD_SETSIZE, &read_socketDescriptors, NULL, NULL, NULL) < 0){
perror ("select");
exit (EXIT_FAILURE);
}
int i;
for (i = 0; i < FD_SETSIZE; ++i){
if (FD_ISSET (i, &read_socketDescriptors)){
if (i == s->sd){
Socket client = tcp_wait_for_connection( server );
pthread_create (&thread,NULL, do_something, (void *)client);
FD_SET (s->sd, &active_socketDescriptors);
} else {
}
}
}
}
tcp_close( server );
return 0;
}
void *do_something(void *client){
unsigned char input[BUFFER_SIZE];
pthread_detach(pthread_self());
MySocket *s = (MySocket *)client;
printf("Client socked_id (thread): %i", s->sd);
int j;
while (1){
int nbytes = tcp_receive(client, input, BUFSIZE );
if (nbytes <= 0){
if (nbytes ==0){
/* connection closed by client*/
printf("Client closed connection");
} else {
/* other error*/
perror("tcp_receive");
}
tcp_close(&client);
/*remove the socket descriptor from set in the main BRAINSTORM ABOUT THIS */
} else {
/*data incoming */
printf("\nMessage from client: %s",input);
}
}
return 0;
}
edit 2: reformulation of problem
I have to use threads (it not because of the system; linux) but because it's mandatory in the assignment to have a thread for each client.
The problem i have specifically is that only the main thread can send the data recieved in each thread from each client to all clients because only the main thread has access to the set which contains the socket descriptors.
edit3: what I need to add in each thread but I can't because of the s.thread and s.main being in different places & the thread not knowing the set of the main.
for (j=0; j<=FD_SETSIZE;j++){
if(FD_ISSET(j,&active_socketDescriptors)){
if (j != s.thead && j!=s.main){
tcp_send(j, (void*)input,nbytes);
}
}
}
edit 4: I solved it this way:
i have a dynamic array list where i put a list of connected clients with there socket descriptor. Inside the thread of the server (do something) I have the recieve blocking until it gets input then this input is send to all connected clients using there socket descriptor from the list which it loops trough. Inside the clients there is a thread listening and a thread sending.
If the client connection sockets are non-blocking, then using e.g. select to wait for the socket receive data is a possible way. However, since you already have the connected sockets in threads, you can keep them blocking, and just do a read call on them. The call to read will block until you receive data, which can then be spread to the other threads.
Edit
After better understanding your requirements, you should probably have the sockets non-blocking, and use a loop with select with a short timeout. When select timeouts (i.e. returns 0) then you check if there is data to send. If there is, then send the data, and go back to the select call.
Given your description it might be worth rethinking the architecture of your application. (Unless this has been dictated by limitations on your system). Let me explain this a little more...
By your description, if I understood you correctly, after a client has connected to the server any messages it (the client) sends will be relayed (by the server) to all other clients. So, rather than creating a new thread why not simply add the newly connected socket to the FDSET of the select. Then when a message comes in you can simply relay to the others.
If you expect a large number of clients for a single server you should see if the poll system call is available on your system (it's just like select but supports monitoring more clients). A good poll/select version ought to out-perform your threaded version.
If you really want to continue with your threaded version here's one way to accomplish what you are trying to do. When you create the thread for each accepted client you also create a pipe back to the server thread (and you add this to the server select/poll set.) and pass that to the client thread. So your server thread now not only receives new connections but relays the messages too.
Although you said that you absolutely must deal with each client in a separate thread, unless you are using a real time operating system, you will probably find that the thread context-switch/synchronization you need to do will soon dominate over the multiplexing overhead of the first solution I suggested. (But since you did not mention an OS I am guessing!)
This is related to your design.
If you only need to do one or two features for each connected client, then suggest you to use only one thread to implement your server.
If you has to do lots of features for each connected client, then multiple thread design is okay.
However, the question you asked should be how did I passing the data from receiving thread to all others. The suggested answer from me is ether:
a) use message queue to passing inter thread data: each thread has one message queue and each thread will listen to its own socket and this message queue. When receiving data from socket, the thread sending the data to all other message queues
b) use an single global buffer: if has any incoming data form socket, put this data into this global buffer and adding a tag to this data indicating where this data comes from.
my 2 cents.

Resources