Bug 31814 - pthread_cleanup_push() generates compiler errors in subsequent code.
pthread_cleanup_push() generates compiler errors in subsequent code.
Status: CLOSED NOTABUG
Product: Red Hat Linux
Classification: Retired
Component: gcc (Show other bugs)
7.0
i386 Linux
high Severity high
: ---
: ---
Assigned To: Jakub Jelinek
David Lawrence
:
Depends On:
Blocks:
  Show dependency treegraph
 
Reported: 2001-03-14 20:23 EST by Need Real Name
Modified: 2005-10-31 17:00 EST (History)
0 users

See Also:
Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of:
Environment:
Last Closed: 2001-03-14 20:23:39 EST
Type: ---
Regression: ---
Mount Type: ---
Documentation: ---
CRM:
Verified Versions:
Category: ---
oVirt Team: ---
RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: ---


Attachments (Terms of Use)

  None (edit)
Description Need Real Name 2001-03-14 20:23:35 EST
Here's and example code. I know it must be the line with 
pthread_cleanup_push() because the errors cease when I comment out this 
one line:

EXTERN_C
DWORD	naiBeginThread(	LPVOID			pSecurity,
			UINT		 	unStackSize, 
			void		 	(*pfStartAddr)(void *), 
			void		 	*pArgs,
			UINT			nInitFlag,
			LPDWORD			pdwThreadID)
{
   naiHandleObject_t	*hThread;
   int			nThreadID;

   // Create the thread object
   if ( (hThread = (naiHandleObject_t *)malloc(sizeof(naiHandleObject_t))) 
								== NULL)
   {
      nErrno = ENOMEM;
      return((DWORD)(-1));
   }
   if ( (hThread->Handle = (void *)malloc(sizeof(naiThread_t))) == NULL)
   {
      nErrno = ENOMEM;
      free(hThread);
      return((DWORD)(-1));
   }

   // Start the thread and set all the outbound data
   if ( (nThreadID = pthread_create((naiThread_t *)hThread->Handle,NULL,
		(void *(*) (void *)) pfStartAddr,
		pArgs)) != 0)
   {
      free(hThread->Handle);
      free(hThread);
      return((DWORD)(-1));
   }

   // Push on the clean up routines - memory is freed by naiCleanupThread()
   naiThreadCleanup_t	*pCleanup;
   if ( (pCleanup = (naiThreadCleanup_t *)
			malloc(sizeof(naiThreadCleanup_t))) == NULL)
      return((DWORD)(-1));
   pCleanup->Mutex = hThread->Mutex;
   pCleanup->Condition = hThread->Condition;
   pCleanup->bSignalled = &(hThread->bSignalled);
   pthread_cleanup_push(naiCleanupThread,(void *)pCleanup);

   // The caller must deal with this and convert it to HANDLE type
   if (pdwThreadID != NULL)
   {
      *pdwThreadID = nThreadID;
   }
   hThread->nType = naiOBJECT_THREAD;
   hThread->nReferenceCounter = 1;
   if (pthread_cond_init(&hThread->Condition,NULL) != 0)
   {
      free(hThread->Handle);
      free(hThread);
      return((DWORD)(-1));
   }
   if (pthread_mutex_init(&hThread->Mutex,NULL) != 0)
   {
      free(hThread->Handle);
      free(hThread);
      return((DWORD)(-1));
   }
   hThread->bSignalled = naiFALSE;
   return((DWORD)hThread);
}
//-------------------------------------------------------------------------
---

// Just like naiBeginThread() with the exceptions noted in the docs for 
that
// function.

EXTERN_C
HANDLE	naiCreateThread(	LPSECURITY_ATTRIBUTES	lpThreadAttributes,
				DWORD			dwStackSize,
				LPTHREAD_START_ROUTINE	lpStartAddress,
				LPVOID			lpParameter,
				DWORD			dwCreationFlags,
				LPDWORD			lpThreadId)
{
   HANDLE		*Handle;
   DWORD		dwRet;


   if ( (dwRet = naiBeginThread((LPVOID)lpThreadAttributes,dwStackSize,
			( void (*) (void *) )lpStartAddress,
			(void *)lpParameter,dwCreationFlags,
			lpThreadId)) == -1)
   {
      return(NULL);
   }
   memcpy(&Handle,&dwRet,4);
   return(Handle);
}

//-------------------------------------------------------------------------
---


Here are the compiler errors that are generated (BTW, the code above 
starts with line 1133):
gcc -c -fPIC -g -D_LINUX_REDHAT -I./source -I./include -I../source -
I../include -I../../linux/source -I../linux/include -I../../linux/source -
I../../linux/include -I../../source -I../../include -
o ../linux/bin/portable.o ../../linux/source/portable.cpp
../../linux/source/portable.cpp: In function `DWORD naiBeginThread 
(void *, unsigned int, void (*) (void *), void *, unsigned int, long 
unsigned int *)':
../../linux/source/portable.cpp:1172: parse error before string 
constant
../../linux/source/portable.cpp:1184: `lpThreadAttributes' undeclared 
(first use this function)
../../linux/source/portable.cpp:1184: (Each undeclared identifier is 
reported only once for each function it appears in.)
../../linux/source/portable.cpp:1184: `dwStackSize' undeclared (first 
use this function)
../../linux/source/portable.cpp:1185: `lpStartAddress' undeclared 
(first use this function)
../../linux/source/portable.cpp:1186: `lpParameter' undeclared (first 
use this function)
../../linux/source/portable.cpp:1186: `dwCreationFlags' undeclared 
(first use this function)
../../linux/source/portable.cpp:1187: `lpThreadId' undeclared (first 
use this function)
../../linux/source/portable.cpp:1189: warning: return to non-pointer type 
`DWORD' from NULL
../../linux/source/portable.cpp:1189: warning: argument to non-pointer 
type `long unsigned int' from 
NULL
../../linux/source/portable.cpp:1191: `Handle' undeclared (first use 
this function)
Comment 1 Jakub Jelinek 2001-03-16 05:41:37 EST
This is a bug in the code you're trying to compile.
Citing pthread.h:
/* Install a cleanup handler: ROUTINE will be called with arguments ARG
   when the thread is cancelled or calls pthread_exit.  ROUTINE will also
   be called with arguments ARG when the matching pthread_cleanup_pop
   is executed with non-zero EXECUTE argument.
   pthread_cleanup_push and pthread_cleanup_pop are macros and must always
   be used in matching pairs at the same nesting level of braces. */
You don't have the corresponding pthread_cleanup_pop macro and those must
be used in pairs at the same nesting level. Also, I'd recommend doing something
with the returns if they should be in the same pthread cleanup region
(because pushing cleanup and forgetting to pop it is a bug).

Note You need to log in before you can comment on or make changes to this bug.