Recursive mutex

This is regarding creating Recursive mutex. Iam not able to enable recursive in the mutex attribute.I tried with the following code to set the attribute to PTHREAD_RECURSIVE_ENABLE. But still the attribute is PTHREAD_RECURSIVE_DISABLE read through pthread_mutexattr_getrecursive.

if (pthread_mutexattr_setrecursive(&attr,PTHREAD_RECURSIVE_ENABLE) == EOK) {
if (pthread_mutexattr_getrecursive(&mutex,&rec) == EOK) {
printf(“Recursive %d”,rec);
}
}
The Value of rec varibale is 0 (PTHREAD_RECURSIVE_DISABLE). Even tried setting attribute directly " attr.__flags = PTHREAD_RECURSIVE_ENABLE;", still the value returned by the pthread_mutexattr_getrecursive is 0. QNX Version is 4.5.0.
Please let me know, how i can set the attribute to Recursive.

Thanks,

Let me assume for a minute that this is the exact code that you are using. I have no doubt that you are getting the results you mention. Now what I want you to do is to stare at the code for at least 10-15 minutes to see if you can see the problem. Maybe lookup the routines in the documentation and inspect them and the code carefully. I’ll give you one small hint. I think your setrecursive is actually working.

Now if you still can’t figure this out, maybe you need to consider another career. If you find the error, you can slap your head in the back and say “DOH!”. All good programmers have to do this from time to time.

:slight_smile:.

And there is no such thing as 4.5.0 .

Hi maschoen,
I got the problem, the order in which iam calling the API is wrong. First i need to set the recursive attribute and then call the pthread_mutex_init API.

The code you showed us does not call pthread_mutex_init() so hmmm, that means there must still be something else wrong with it.

I think you referring to &mutex parameter in the pthread_mutexattr_getrecursive api. instead of &attr.

I wrongly understood the API pthread_mutexattr_getrecursive(), I thought this will refer to the mutex created rather than attribute. Because it is quite obvious that attribute value assigned will be the value read back. I wanted to confirm whether mutex is created with the attribute passed.

Actually I wanted to see the recursive behavior of mutex. So in my experimental code tried with attributes PTHREAD_RECURSIVE_ENABLE and PTHREAD_RECURSIVE_DISABLE in both the cases second lock from same thread is succeeding(.i.e not blocking). To check whether attributes are successfully set to the mutex created, I tried getting the mutex attributes by calling pthread_mutexattr_getrecursive.

Iam learning QNX, if you know with what API can i get the atrributes set to the mutex, it will be helpful.

My experimental code :
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

void func1 (pthread_mutex_t pmtx);
void func2 (pthread_mutex_t pmtx);
/
============================================================================

  • @func main

  • @desc Entry point for the application

  • @modif None

  • ============================================================================
    */
    int main (int argc, char ** argv)
    {
    pthread_mutexattr_t attr = {0};
    pthread_mutex_t mutex;
    int status = -1,rec = -1;

    printf("\nMutex Experiment\n");

    /attr.__flags = PTHREAD_RECURSIVE_DISABLE;
    printf(“Recursive1 %d\n”,(attr.__flags & PTHREAD_RECURSIVE_DISABLE) )
    /

    status = pthread_mutexattr_setrecursive(&attr,PTHREAD_RECURSIVE_DISABLE );
    printf(“Recursive2 %d\n”,(attr.__flags & PTHREAD_RECURSIVE_DISABLE) );

    pthread_mutex_init (&mutex,&attr);
    printf(“Recursive3 %d\n”,(attr.__flags & PTHREAD_RECURSIVE_DISABLE) );

    status = pthread_mutexattr_getrecursive(&attr,&rec);
    if (status == 0) {
    printf(“Recursive %d”,rec);
    }

    func1 (&mutex);

    func2 (&mutex);

    status = pthread_mutex_unlock(&mutex);
    printf(“unlock %d\n”,status);

    status = pthread_mutex_unlock(&mutex);
    printf(“unlock %d\n”,status);

    return (0);
    }

void func1 (pthread_mutex_t *pmtx)
{
int status = 0;
status = pthread_mutex_lock (pmtx);
printf ("\nFunc1 Status %d",status);
}

void func2 (pthread_mutex_t *pmtx)
{
int status = 0;
status = pthread_mutex_lock (pmtx);
printf ("\nFunc2 Status %d",status);
printf ("\nIf mutex is owned, mutex doesn’t lock it, returns with EDEADLK\n");

}

I hope this helps:

#include <libc.h>
#include <pthread.h>

pthread_mutex_t mutex_1;
pthread_mutexattr_t attr_1;

pthread_mutex_t mutex_2;
pthread_mutexattr_t attr_2;

int main()
{
int ret;
int recursive;

//
//	Test 1, non-recursive mutex
//

//
//	Init Mutex Attr 1
//
ret = pthread_mutexattr_init(&attr_1);
if (ret)
{
	fprintf(stderr,"Mutex Init Attr 1 failed error %d\n",ret);
	exit(-1);
}
else
{
	fprintf(stderr,"Mutex Init Attr 1 (non-recursive) Successful\n");
}

//
//	Set Recursive value of Mutex Attr 1 
//
ret = pthread_mutexattr_setrecursive(&attr_2,PTHREAD_RECURSIVE_DISABLE);
if (ret)
{
	fprintf(stderr,"Mutex Attr SetRecursive 1 (non-recursive) failed error %d\n",ret);
	exit(-1);
}
else
{
	fprintf(stderr,"Mutex Attr SetRecursive 2 (non-recursive) Successful\n");
}
//
//	Check Recursive value of Mutex Attr 1 
//
ret = pthread_mutexattr_getrecursive(&attr_1,&recursive);
if (ret)
{
	fprintf(stderr,"Mutex Attr GetRecursive 1 (non-recursive) failed error %d\n",ret);
	exit(-1);
}
else
{
	fprintf(stderr,"Mutex Attr GetRecursive 1 (non-recursive) Successful, value %d\n",recursive);
}

//
//	Init Mutex 1
//
ret = pthread_mutex_init(&mutex_1,&attr_1);
if (ret)
{
	fprintf(stderr,"Mutex Init 1 failed error %d\n",ret);
	exit(-1);
}
else
{
	fprintf(stderr,"Mutex Init 1 (non-recursive) Successful\n");
}


//
//	Lock Mutex 1, first time
//
ret = pthread_mutex_lock(&mutex_1);
if (ret)
{
	fprintf(stderr,"Mutex 1 Lock failed error %d\n",ret);
	exit(-1);
}
else
{
	fprintf(stderr,"Mutex 1 Lock Successful\n");
}

//
//	Lock Mutex 1, 2nd time
//
ret = pthread_mutex_lock(&mutex_1);
if (ret)
{
	fprintf(stderr,"Mutex 1 2nd Lock failed error %xh EDEADLK=%xh\n",ret,EDEADLK);
}
else
{
	fprintf(stderr,"Mutex 1 2nd Lock Successful? (This would be bad)\n");
	exit(-1);
}

fprintf(stderr,"\n");

//
//	Test 2, recursive mutex
//

//
//	Init Mutex Attr 2
//
ret = pthread_mutexattr_init(&attr_2);
if (ret)
{
	fprintf(stderr,"Mutex Init Attr 2 failed error %d\n",ret);
	exit(-1);
}
else
{
	fprintf(stderr,"Mutex Init Attr 2 (recursive) Successful\n");
}

//
//	Set Recursive value of Mutex Attr 2 
//
ret = pthread_mutexattr_setrecursive(&attr_2,PTHREAD_RECURSIVE_ENABLE);
if (ret)
{
	fprintf(stderr,"Mutex Attr SetRecursive 2 failed error %d\n",ret);
	exit(-1);
}
else
{
	fprintf(stderr,"Mutex Attr SetRecursive 2 Successful\n");
}

//
//	Check Recursive value of Mutex Attr 2 
//
ret = pthread_mutexattr_getrecursive(&attr_2,&recursive);
if (ret)
{
	fprintf(stderr,"Mutex Attr GetRecursive 2 failed error %d\n",ret);
	exit(-1);
}
else
{
	fprintf(stderr,"Mutex Attr GetRecursive 2 (recursive) Successful, value %d\n",recursive);
}

//
//	Init Mutex 2
//
ret = pthread_mutex_init(&mutex_2,&attr_2);
if (ret)
{
	fprintf(stderr,"Mutex Init 2 failed error %d\n",ret);
	exit(-1);
}
else
{
	fprintf(stderr,"Mutex Init 2 (recursive) Successful\n");
}


//
//	Lock Mutex 2, first time
//
ret = pthread_mutex_lock(&mutex_2);
if (ret)
{
	fprintf(stderr,"Mutex 2 Lock failed error %d\n",ret);
	exit(-1);
}
else
{
	fprintf(stderr,"Mutex 2 Lock Successful\n");
}

//
//	Lock Mutex 2, 2nd time
//
ret = pthread_mutex_lock(&mutex_2);
if (ret)
{
	fprintf(stderr,"Mutex 2 2nd Lock failed error %xh\n",ret);
}
else
{
	fprintf(stderr,"Mutex 2 2nd Lock Successful\n");
	exit(-1);
}

}