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

  1. #1
    Registered User
    Join Date
    Dec 2010
    Posts
    13

    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__ );
    }

  2. #2
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    Threads and Timers

    Instead of using signals, use select or poll. Those will tell you when there is something read or write with timeouts.

    gg

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. How to make your Thread HOT
    By year2038bug in forum A Brief History of Cprogramming.com
    Replies: 29
    Last Post: 08-30-2005, 06:20 AM
  2. Simple thread object model (my first post)
    By Codeplug in forum Windows Programming
    Replies: 4
    Last Post: 12-12-2004, 11:34 PM
  3. Binary Search Trees Part III
    By Prelude in forum A Brief History of Cprogramming.com
    Replies: 16
    Last Post: 10-02-2004, 03:00 PM
  4. How to make a thread sleep or std::recv timeout?
    By BrianK in forum Linux Programming
    Replies: 3
    Last Post: 02-26-2003, 10:27 PM
  5. Sign up -- Contest Thread
    By ygfperson in forum A Brief History of Cprogramming.com
    Replies: 70
    Last Post: 05-27-2002, 06:46 PM

Tags for this Thread