LinuxQuestions.org
Review your favorite Linux distribution.
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Software
User Name
Password
Linux - Software This forum is for Software issues.
Having a problem installing a new program? Want to know which application is best for the job? Post your question in this forum.

Notices


Reply
  Search this Thread
Old 07-15-2004, 07:38 AM   #1
shilpig
LQ Newbie
 
Registered: May 2004
Posts: 8

Rep: Reputation: 0
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
 
Old 07-15-2004, 07:50 AM   #2
BluePyre
Member
 
Registered: Mar 2004
Location: London
Distribution: Mandrake 10
Posts: 172

Rep: Reputation: 30
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.
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
fork()'ed or multi threaded socket I/O? thedevilsjester Programming 5 09-24-2008 12:41 AM
pthreads - multi-threaded server elitecodex Programming 1 08-20-2005 03:58 PM
how to do waitpid() using a multi-threaded server? Thinking Linux - Software 1 04-13-2005 09:50 PM
how to debug multi threaded application sibtay Programming 3 10-15-2004 12:02 PM
Multi-Threaded C pragti Programming 1 06-01-2004 10:50 AM

LinuxQuestions.org > Forums > Linux Forums > Linux - Software

All times are GMT -5. The time now is 03:33 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration