C - Debug mode won't acknowledge callback event - c

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.

Related

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) {

How to know if a WSASend() operation has been completed without calling GetQueuedCompletionStatus()?

When calling WSASend(), I have to pass it a WSAOVERLAPPED instance, and I cannot re-use this WSAOVERLAPPED instance until the previous WSASend() operation has been completed (i.e. when a completion packet has been placed in the completion port).
Is there a way I can know if the WSASend() operation has been completed without calling GetQueuedCompletionStatus()?
you need bind own socket to system created IOCP as result when operation finished your callback will be called automatic. you have 2 options here:
use BindIoCompletionCallback - this will be work from Windows
XP (really even from win2000)
use CreateThreadpoolIo - work from Windows Vista
after you create socket by
SOCKET socket = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, 0, 0, WSA_FLAG_OVERLAPPED)
you need call BindIoCompletionCallback((HANDLE)socket, *,0) or CreateThreadpoolIo((HANDLE)socket, *, 0, 0);
and all. you not need call GetQueuedCompletionStatus() or wait at all
You can use WSAGetOverlappedResult to get the WSASend progression:
/* size bytes to send */
WSASend(Sock, &aBuf, 1, NULL, 0, &overlap, NULL);
/* warning no test for error cases */
DWORD dummy;
DWORD sent;
do
{
/* Ask for the sending progression without waiting */
WSAGetOverlappedResult(Sock, &SendOverlapped, &sent, FALSE, &dummy);
/* to prevent too much CPU usage */
Sleep(15);
} while (size != sent);

Implementing a WatchDog timer

I need to implement a timer that checks for conditions every 35 seconds. My program is using IPC schemes to communicate information back and forth between client and server processes. The problem is that I am running msgrcv() function in a loop, which pauses the loop until it finds a message, which is no good because I need the timer to always be checking if a client has stopped sending messages. (if it only checks when it receives a message, this will be useless...)
The problem may seem unclear, but the basics of what I need is a way to implement a Watchdog timer that will check a condition every 35 seconds.
I currently have this code:
time_t start = time(NULL);
//Enter main processing loop
while(running)
{
size_t size = sizeof(StatusMessage) - sizeof(long);
if(msgrcv(messageID, &statusMessage, size, 0, 0) != -1)
{
printf("(SERVER) Message Data (ID #%ld) = %d : %s\n", statusMessage.machineID, statusMessage.status_code, statusMessage.status);
masterList->msgQueueID = messageID;
int numDCs = ++masterList->numberOfDCs;
masterList->dc[numDCs].dcProcessID = (pid_t) statusMessage.machineID;
masterList->dc[numDCs].lastTimeHeardFrom = 1000;
printf("%d\n", masterList->numberOfDCs);
}
printf("%.2f\n", (double) (time(NULL) - start));
}
The only problem is as I stated before, the code to check how much time has passed, won't be reached if there is no message to come in, as the msgrcv function will hold the process.
I hope I am making sense, and that someone will be able to assist me in my problem.
You may want to try the msgctl(msqid, IPC_STAT, struct msqid_ds *msgqdsbuf); If the call is successful, then the current number of messages can be found using msgdsbuf->msg_qnum. The caller needed read permissions, which I think you may have in here.

signal callback and pthread sync

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.

Creating and destroying threads

gcc (GCC) 4.6.3
c89
Hello,
I am just wondering if this is the best way to handle worker/background threads created by main?
I am doing this right? this is the first time I have done any multiple threading programs. Just want to make sure I am on the right track, as this will have to be extended to add more threads.
I have one thread for sending a message and another for receiving the message.
Many thanks for any suggestions,
int main(void)
{
pthread_t thread_send;
pthread_t thread_recv;
int status = TRUE;
/* Start thread that will send a message */
if(pthread_create(&thread_send, NULL, thread_send_fd, NULL) == -1) {
fprintf(stderr, "Failed to create thread, reason [ %s ]",
strerror(errno));
status = FALSE;
}
if(status != FALSE) {
/* Thread send started ok - join with the main thread when its work is done */
pthread_join(thread_send, NULL);
/* Start thread to receive messages */
if(pthread_create(&thread_recv, NULL, thread_receive_fd, NULL) == -1) {
fprintf(stderr, "Failed to create thread for receiving, reason [ %s ]",
strerror(errno));
status = FALSE;
/* Cancel the thread send if it is still running as the thread receive failed to start */
if(pthread_cancel(thread_send) != 0) {
fprintf(stderr, "Failed to cancel thread for sending, reason [ %s ]",
strerror(errno));
}
}
}
if(status != FALSE) {
/* Thread receive started ok - join with the main thread when its work is done */
pthread_join(thread_recv, NULL);
}
return 0;
}
Example of a worker/background thread to send a message, example only
void *thread_send_fd()
{
/* Send the messages when done exit */
pthread_exit(NULL);
}
The only time when this kind of construct might be justified is if there is only ever one message exchanged and, even then, there may be some problems.
If messages are to be exchanged continually during the app run, it's more usual to write both threads as loops and never terminate them. This means no continual create/terminate/destroy overhead and no deadlock-generator, (AKA join). It does have a downside - it means that you have to get involved with signals, queues and the like for inter-thread comms, but this is going to happen anyway if you write many multithreaded apps.
Either way, it's usual to start the rx thread first. If you start the tx thread first, there is a possibility that rx data will be retuned and discarded before the rx thread starts.
Is this done once per message? It seems like the call creates a thread to send 1 message and another thread to wait for 1 response. Then the call, and I'm assuming the entire program, just waits for the whole thing to finish. Assuming the receiver cannot do anything until the sender finishes sending, this does absolutely nothing to improve the real or perceived performance of your program. Now to be precise, we would need to know what the sender and the receiver are really doing before we can tell for sure if there is any benefit from this. For any benefit at all, the sender thread and the receiver thread would have to have work that they can do simultaneously....not serially. If the intent is to not make the program wait for the send and the receive transaction, then this does not do that at all.

Resources