LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Software (https://www.linuxquestions.org/questions/linux-software-2/)
-   -   Signal Handling in Multi-Threaded Applications (https://www.linuxquestions.org/questions/linux-software-2/signal-handling-in-multi-threaded-applications-205336/)

shilpig 07-15-2004 07:38 AM

Signal Handling in Multi-Threaded Applications
 
pls help me out in my program.

My probelm in the program-
I require all-together separate thread to do my work. But when create separate thread and invoke functionality from this thread, my signal handler doesnt return. But when work from main itself(single thread), the program works fine.

I shall be thankful if anyone cud resolve this.


My Program:
#define _POSIX_C_SOURCE 199506L

#include<pthread.h>
#include<unistd.h>
#include<signal.h>
#include<time.h>
#include<stdio.h>


// Typedefs go here

//------------------------------------------------------------------------------
/*! \def struct UIServiceData UIServiceData_t
* \brief Structure containing UI service information
*/
typedef struct UIServiceData UIServiceData_t;
typedef struct sigaction sigaction_t;
typedef struct UITimerStruct UITimerStruct_t;

//------------------------------------------------------------------------------
/*! \struct UITimerStruct
* \brief This structure holds the UI timer information.
*/
struct UITimerStruct
{
sigaction_t sa;
timer_t mytimer;
struct itimerspec iClockResolution;
struct timespec resolution;
struct sigevent sigTimerEvent;
};

//------------------------------------------------------------------------------
/*! \struct UIServiceData
* \brief This structure holds the UI Service Information
*/
struct UIServiceData
{
UITimerStruct_t uiTimer;
};

#define OUR_CLOCK CLOCK_REALTIME
#define UI_POLL_TIMER 5 //sec

// General Hash Defines
#define FALSE 0
#define TRUE 1


inline void* allocateZero (int size)
{
void* mem = malloc( (unsigned int)size );
if ( mem == NULL )
return NULL;

// Allocate Zero
bzero ( mem, sizeof (mem) );
return mem;
}



void uiTimerProc(int sig, siginfo_t *extra, void *cruft)
{
// Timer code for signalling go here TBD
printf("in timer proc\n");
return;
}



int intializeTimerSignal( UIServiceData_t* serviceData)
{
int iResult = TRUE;

sigemptyset( &serviceData->uiTimer.sa.sa_mask );
serviceData->uiTimer.sa.sa_flags = SA_SIGINFO; //real-time signal
serviceData->uiTimer.sa.sa_sigaction = uiTimerProc; //pointer to action

if(sigaction( SIGRTMIN, &serviceData->uiTimer.sa, NULL ) < 0)
{
printf("sigaction error \n");
iResult = FALSE;
}
return iResult;
}

int createUITimer( UIServiceData_t* serviceData)
{
timer_t *mytimer = &serviceData->uiTimer.mytimer;
struct itimerspec *itresolution = &serviceData->uiTimer.iClockResolution;
struct timespec *resolution = &serviceData->uiTimer.resolution;
struct sigevent *timer_event = &serviceData->uiTimer.sigTimerEvent;

int iResult = FALSE;
//First determine whether the desired clock exists
if ( clock_getres( OUR_CLOCK, resolution ) < 0 )
{
printf("clock_getres error\n");
return iResult;
}

// create a timer based upon the CLOCK_REALTIME clock
itresolution->it_interval.tv_sec = UI_POLL_TIMER;

// set resolution to one-tenth of the maximum allowed
itresolution->it_interval.tv_nsec = resolution->tv_nsec*10;
itresolution->it_value = itresolution->it_interval;

// this describes the asynchronous notification to be posted
// upon this timer's expiration:
// - use signals
// - send SIGRTMIN
// - send extra data consisting of a pointer back to the timer ID
// cannot pass the timer ID itself because we haven't created it yet.

timer_event->sigev_notify = SIGEV_SIGNAL;
timer_event->sigev_signo = SIGRTMIN;
timer_event->sigev_value.sival_ptr = (void *)mytimer;

if (timer_create(OUR_CLOCK, timer_event, mytimer) < 0)
{
printf("timer create error\n");
return iResult;
}

iResult = TRUE;
return iResult;
}

int initializeUITimer( UIServiceData_t* serviceData)
{
// Initialize a signal for Timer
if( intializeTimerSignal (serviceData) == FALSE )
{
printf("Error intializeTimerSignal \n");
return FALSE;
}

//create a timer based on this clock
if( createUITimer (serviceData) == FALSE )
{
printf("Error intializeTimerSignal \n");
return FALSE;
}

printf("Intialize UI Timer\n");
return TRUE;
}


unsigned int ProcessUIWait(UIServiceData_t* serviceData, sigset_t* allsigs)
{
// Go back to waiting for another event

// TBD This has to done for a specific signal
printf("About to sleep\n");
sigsuspend(allsigs);
printf("woke up\n");
return TRUE;
}


int setUITimer( UIServiceData_t* serviceData)
{
int iResult = FALSE;
timer_t *mytimer = &serviceData->uiTimer.mytimer;
struct itimerspec *itresolution = &serviceData->uiTimer.iClockResolution;

// relative timer, go off at the end of the interval
if(timer_settime(*mytimer, 0 , itresolution, NULL) < 0)
{
printf("settimer error\n");
}
else
{
printf("timer set\n");
iResult = TRUE;
}
return iResult;
}


void uiUSBAdaptorProc( void *lpParam )
{
sigset_t allsigs;
int iRes = 0;
unsigned int uiActive = TRUE;
unsigned int uiMoreToProcess = FALSE;
unsigned int uiRecvStatus = 0;

UIServiceData_t* serviceData = (UIServiceData_t*) lpParam;

if( serviceData == NULL )
{
// Log TBD
return ;
}

sigemptyset(&allsigs);

while ( uiActive)
{
/*
if ( uiOpen != TRUE)
{
iRes = openUIConnection(serviceData);

if(iRes == UI_OPEN_SUCCESS)
{
uiOpen = TRUE;
uiMoreToProcess = TRUE;
}
else
{
printf("\nOpen failed");
// Set poll timer TBD
if( setUITimer( serviceData) == FALSE)
{
printf("set TImer failed\n");
}
}
}
*/
if( setUITimer( serviceData) == FALSE)
{
printf("set TImer failed\n");
}

/*while( uiMoreToProcess)
{
//Transact with USB device
uiRecvStatus = readFromUIDevice(serviceData);

// read reults in error or If there is no data to read
if ( uiRecvStatus == UI_READ_ERROR
|| uiRecvStatus == UI_ERROR )
{
//do clean up TBD
uiOpen = FALSE;
uiMoreToProcess = FALSE;
break;
}
}*/

if (! ProcessUIWait(serviceData, &allsigs))
{
//break TBD
}

}
return;
}

pthread_t tdServiceId;

static int launchUSBAdaptor(UIServiceData_t* serviceData)
{
int iRet = 0;
int iResult = TRUE;

iRet = pthread_create( &tdServiceId,
NULL,
(void *)(&uiUSBAdaptorProc), // thread Proc
(void *) serviceData);
if ( iRet != 0 )
{
printf("Failed to create UI Adaptor thread : Err %d.\n", iRet);
iResult = FALSE;
}
return iResult;
}


main(int argc, char **argv)
{
UIServiceData_t* hUIService = NULL;

// Allocate Memory to hold UIService data
hUIService = (UIServiceData_t *) allocateZero ( sizeof(UIServiceData_t));

if (hUIService == NULL)
{
printf("Unable to allocate ui service data structures.\n");
return 1;
}

if( initializeUITimer(hUIService) == FALSE)
{
printf("Failed to initialize UI timer.\n");
return 1;
}

printf("SUCCESSSSSSSS\n");


/////////////////////////////////////
// If I uncomment this, the signal handler doesnot return to calling, and thus "woke up" is never printed
////////////////////////////////////
// Spawn Ui service/Adaptor thread with UI Service data info
if( launchUSBAdaptor(hUIService) == FALSE)
{
printf("Failed to launch ui service threads.\n");
return 1;
}


/////////////////////////////////////
// If I call this, the signal handler returns to calling, and thus "woke up" gets printed.
// But if I comment this, and call launchUSBAdaptor instead, then "woke up" is not printed.
////////////////////////////////////

//uiUSBAdaptorProc(hUIService);

printf("In main\n");

while(1) {sleep(100);}

return 0;
}




Makefile:
all:
cc -g -pthread -lrt -o try3.o try3.c
clean:
rm -f try3.o

BluePyre 07-15-2004 07:50 AM

This should be posted in the programming thread.
Please only post the relevant parts as well. Don't post your whole 200 line+ file, as not many people have the time or patience to do so (many respects to the people who do). If you have to post it all, keep your comments, just remove commented blocks of code. As there's no syntax highlighting it makes it a hastle to have all that extra code there.

Have you tried using a QThread instead of a thread? It makes these kinds of things relatively simple.


All times are GMT -5. The time now is 02:41 PM.