Visit Our UNIX and Linux User Community


How to use sigmask in order to make signals can be processed by a thread


 
Thread Tools Search this Thread
Top Forums Programming How to use sigmask in order to make signals can be processed by a thread
# 1  
Old 03-06-2011
How to use sigmask in order to make signals can be processed by a thread

Hi,

I have a UDP server and client program, and they must run within a program, so I decided two threads, one for UDP server and another for UDP client.

The simple architecture is shown in attachment.

However, I can't send the packets out on the UDP client, no any time message and sigaction is triggered. Is any sigmask needs? If it is, then where should I put the mask?

The following are the source codes

The UDP server
Code:
static void SIGIOHandler( int signalType ) {
    struct sockaddr_in clntAddr;
    unsigned int clntLen;
    int recvMsgSize;
    UINT8 buf[ MSG_SIZE ];
    do {
        clntLen = sizeof( clntAddr );
        if ( ( recvMsgSize = recvfrom( srvSock, buf, MSG_SIZE, 0, ( struct sockaddr* )&clntAddr,&clntLen ) ) < 0 ) {
            if ( errno != EWOULDBLOCK ) {
                      ...Error handler
            }
        } else {
            printf( "Handling client %s\n", inet_ntoa( clntAddr.sin_addr ) );
            if ( Sendto( srvSock, buf, recvMsgSize, 0, ( struct sockaddr* )&clntAddr, sizeof( clntAddr ),
            __FILE__, __LINE__ ) != recvMsgSize ) {
               ...Error handler
            }
        }
    }  while ( recvMsgSize >= 0 );
    printf( "%s completed\n", inet_ntoa( clntAddr.sin_addr ) );
}


void Server_Constructor () {
    char buf[ 128 ];
    struct sockaddr_in echoServAddr;
    struct sigaction handler;

    /* Initiating socket. */
    srvSock = socket( PF_INET, SOCK_DGRAM, IPPROTO_UDP );
    memset( &echoServAddr, 0, sizeof( echoServAddr ) );
    echoServAddr.sin_family = AF_INET;
    echoServAddr.sin_addr.s_addr = htonl( INADDR_ANY );
    echoServAddr.sin_port = htons( ( unsigned short )23456 );
    Bind( srvSock, ( struct sockaddr* )&echoServAddr, sizeof( echoServAddr ) );

    /* Initiating signal handler. */
    handler.sa_handler = SIGIOHandler;
    if ( sigfillset( &handler.sa_mask ) < 0 ) {
      ...Error handler
    }
    handler.sa_flags = 0;   /* No flags */
    if ( sigaction( SIGIO, &handler, 0 ) < 0 ) {
      ...Error handler
    }
    if ( fcntl( srvSock, F_SETOWN, getpid() ) < 0 ) {
      ...Error handler
    }
    if ( fcntl ( srvSock, F_SETFL, O_NONBLOCK | FASYNC ) < 0 ) {
      ...Error handler
    }

    /* Wait forever. */
   ....
}

The UDP client
Code:
static void CatchAlarm ( int ignored ) {
    tries += 1;
}

void Client_Sendto ( const struct sockaddr* dest_addr, const void* message ) {
    int sock;                        /* Socket descriptor */
    struct sockaddr_in echoServAddr; /* Echo server address */
    struct sockaddr_in fromAddr;     /* Source address of echo */
    unsigned int fromSize;           /* In-out of address size for recvfrom() */
    struct sigaction myAction;       /* For setting signal handler */
    char *servIP;                    /* IP address of server */
    char echoString[ MSG_SIZE ] = "123";                /* String to send to echo server */
    char recvbuf[ MSG_SIZE ];
    int respStringLen;               /* Size of received datagram */

    servIP = "127.0.0.1";           /* First arg:  server IP address (dotted quad) */

    sock = Socket( PF_INET, SOCK_DGRAM, IPPROTO_UDP, __FILE__, __LINE__ );

    /* Set signal handler for alarm signal */
    myAction.sa_handler = CatchAlarm;
    if (sigfillset(&myAction.sa_mask) < 0) /* block everything in handler */
        DieWithError("sigfillset() failed");
    myAction.sa_flags = 0;

    if (sigaction(SIGALRM, &myAction, 0) < 0)
        DieWithError("sigaction() failed for SIGALRM");

    /* Construct the server address structure */
    memset(&echoServAddr, 0, sizeof(echoServAddr));    /* Zero out structure */
    echoServAddr.sin_family = AF_INET;
    echoServAddr.sin_addr.s_addr = inet_addr(servIP);  /* Server IP address */
    echoServAddr.sin_port = htons( ( unsigned short )UDP_PORT );       /* Server port */

The UDP client unable send packet out, I think it can't receive the signal in the thread, so how to do that? 

    /* Send the string to the server */
    if (sendto(sock, echoString, MSG_SIZE, 0, (struct sockaddr *)
               &echoServAddr, sizeof(echoServAddr)) != MSG_SIZE)
        DieWithError("sendto() sent a different number of bytes than expected");

    /* Get a response */
    fromSize = sizeof( fromAddr );
    alarm( TIMEOUT_SECS );  /* Set the timeout */
    while ((respStringLen = recvfrom(sock, recvbuf, MSG_SIZE, 0,
           (struct sockaddr *) &fromAddr, &fromSize)) < 0)
        if (errno == EINTR)     /* Alarm went off  */
        {
            if (tries < MAXTRIES)      /* incremented by signal handler */
            {
                printf("timed out, %d more tries...\n", MAXTRIES-tries);
                if (sendto(sock, echoString, MSG_SIZE, 0, (struct sockaddr *)
                            &echoServAddr, sizeof(echoServAddr)) != MSG_SIZE)
                    DieWithError("sendto() failed");
                alarm(TIMEOUT_SECS);
            }
            else
                DieWithError("No Response");
        }
        else
            DieWithError("recvfrom() failed");
    alarm( 0 ); /* Cancel the timeout. */
    Close( sock, __FILE__, __LINE__ );
    printf( "Received: %s\n", recvbuf );    /* Print the received data */
}


static void* SENDER ( void* null ) {
    do {
        Client_Sendto( NULL, NULL );
        sleep( 1 );
    } while ( 1 );
    return NULL;
}


void Client_DebugThread () {
    pthread_t tid;              /* Thread ID. */
    pthread_attr_t rx;          /* Parameter of thread. */
    pthread_attr_init( &rx );   /* Free resources immediately if a thread is terminated. */
    pthread_attr_setdetachstate( &rx, PTHREAD_CREATE_DETACHED );
    pthread_create( &tid, &rx, SENDER, NULL, __FILE__, __LINE__ ); 
}

How to use sigmask in order to make signals can be processed by a thread-udppng
# 2  
Old 03-06-2011
First, never, ever, ever make calls like "printf()" within a signal handler. The only system calls you can safely make from within a signal handler are those listes as async-signal safe. On Linux. see the man page for "signal" for a list.

Calling a non-async-signal-safe call from within a signal handler results in "undefined" behavior. In practice that usually means a deadlock because your signal handler will attempt to acquire a lock already held by the thread that the signal interrupted.

Second, don't call sigfillset() on your sigaction structure. If anything, call sigemptyset().
# 3  
Old 03-06-2011
Worse, you can't even count on being able to safely set the value of a variable in a signal handler unless it can be done atomically (such as with volatile sig_atomic_t). You really want to do as little as possible in a sighandler. If possible, set an atomic flag and get out.

Regards,
Alister

Previous Thread | Next Thread
Test Your Knowledge in Computers #427
Difficulty: Easy
JavaScript supports only explicit delegation.
True or False?

10 More Discussions You Might Find Interesting

1. Shell Programming and Scripting

Check the file processed Completion

Hi, I have a wierd requirement where i need to check for a file transfered to my Server and once it is completed i need to start processing my jobs. My server is AIX 6.0 and i want to know is there some way in unix i can keep on checking the file and once it is completed successfully i can... (5 Replies)
Discussion started by: prasson_ibm
5 Replies

2. UNIX for Advanced & Expert Users

Problem With UTF8 Byte Order Make

Hi Im migrating a few websites from my old webserver (CentOS-5) to a new server (CentOS6) , one of these websites is multilingual and has a lot of utf8 files(html,php) with different languages (i.e arabic, persian, russian ,etc). In old server when i do: file mailer.php I get : ... (6 Replies)
Discussion started by: mohs3n
6 Replies

3. Shell Programming and Scripting

Running sed and counting number of lines processed

/bin/sed -n ';4757335,$ p' | wc -l /bin/sed -n ';4757335,$ p' | egrep "Failed" | egrep -c "PM late arrrival" how can i combine the above two sed commands into one? i want to count the number of lines between the specified line number and the end of the file. AND and i want to count how many... (5 Replies)
Discussion started by: SkySmart
5 Replies

4. Shell Programming and Scripting

Downloading processed HTML of PHP page

Hi, I am trying to obtain the HTML code of a PHP page (http:// areferee .com/soccer/test1.php?quiz=50&ran=1&t=5) after the page has been processed; I want pure HTML. Is there a Unix command I can use to do this? I have tried wget, GET, curl but I am getting odd behaviour i.e. it is not... (9 Replies)
Discussion started by: djcas
9 Replies

5. Shell Programming and Scripting

remember processed files

Hello dear community! I have the following task to accomplish: there is a directory with approximately 2 thousand files. I have to write a script which would randomly extract 200 files on the first run. On the second run it should extract again 200 files but that files mustn't intersect with... (5 Replies)
Discussion started by: sidorenko
5 Replies

6. Shell Programming and Scripting

Deleting processed lines

I have a log file that I am processing. This contains messages from and to a server (requests and responses). The responses to requests may not be in order i.e. we can have a response to a request after several requests are sent, and in some error cases there may not be any response message. ... (2 Replies)
Discussion started by: BootComp
2 Replies

7. Programming

How can I make the parent thread wait

Hi All, I will be glad if you could help me resolve this problem. I have created two detachable threads and wanted to them execute independent of the parent thread ( the main task which creates the detachable threads). But I see no output coming from the execution of two detachable threads.... (4 Replies)
Discussion started by: jayfriend
4 Replies

8. Programming

Question About Multi-Processed Applications... fork()

Assume we have an application built on *nix that uses fork()...then the processes procedure is going to act as follow: X is considered a parent process (first click on application) Y is considered a child process of X (second click on application) Z is considered a child process of Y (third... (6 Replies)
Discussion started by: f.ben.isaac
6 Replies

9. Shell Programming and Scripting

Awk: first line not processed correctly

Hey, I've made a little awk-script which reorders lines. Works okay, only problem is that is doesn't process the first line correctly. If I switch lines in the Input file it doesn't proces this first line either. Somebody please help! Here's is the code and the input file! thanx ... (1 Reply)
Discussion started by: BartleDuc
1 Replies

10. UNIX for Dummies Questions & Answers

Deleting access_log.processed in crontab

Hi, I've worked out that my server was getting clogged with the access_log.processed file. I deleted it using the command > /var/www/vhosts/domain.com/statistics/logs/access_log.processed I also set that up as a crontab job for every Wednesday. What I was wondering is the version using... (4 Replies)
Discussion started by: chickenhouse
4 Replies

Featured Tech Videos