Mutex with DrawFunction for PtRaw

Hello,

I have a PtRaw widget which I am plotting points inside. The redraw function for the PtRaw (when it gets damaged) accesses a global structure. This structure gets updated in another thread, and thus, I had to use a mutex to ensure the redraw function did not access any of it’s members while they were being modified.

The problem is, the mutex won’t work!!! Are there any tricks to mutexes in Photon processes? I declared the mutex in a global header, initialized it to the default values (removed priority inheritance however), and lock it (or so I thought) before doing modifications to the variables. However, when I get into the redraw function, and I try to obtain the mutex, it doesn’t block even though I just locked-it!

Any suggestions?
Thanks.

Show us some code. Maybe build a very simple two threaded example that shows the problem?

What function you use to “lock” the mutex, and what is the return value of that function?

Here is a same code that gives the same “error” as my real code. The error code (45) shown in the output indicates that my thread already has the mutex locked, which is why it cannot lock it again. How can I get around this? The draw() function is called automatically when I attempt to create a new widget on the PtRaw widget.

Thanks.


#include <errno.h>
#include <stdlib.h>
#include <stdio.h>
#include <Pt.h>

void draw(PtWidget_t * widget, PhTile_t * damage);
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
PtArg_t args[4];
PhDim_t Dim = {100,100};
PhPoint_t Pos={10,10},Pos2={0,0};
PtWidget_t *Window,*Raw;

int main(int argc, char *argv[])
{
if( PtInit(NULL)==-1 )
exit(EXIT_FAILURE);
PtSetArg(&args[0], Pt_ARG_POS, &Pos, 0);
PtSetArg(&args[1], Pt_ARG_DIM, &Dim, 0);
if( (Window=PtCreateWidget(PtWindow,Pt_NO_PARENT,2,args)) == NULL)
PtExit(EXIT_FAILURE);

EOK,EAGAIN,EDEADLK,EFAULT,EINVAL,ETIMEDOUT);fflush(stdout);

PtSetArg(&args[0], Pt_ARG_POS, &Pos2, 0);
PtSetArg(&args[2], Pt_ARG_RAW_DRAW_F, &draw, 1 );
if( (Raw=PtCreateWidget(PtRaw,Pt_DEFAULT_PARENT,3,args)) == NULL )
	PtExit(EXIT_FAILURE);
PtRealizeWidget(Window);

printf("Lock1: %i\n",pthread_mutex_lock(&mutex));fflush(stdout);
PtRealizeWidget(PtCreateWidget(PtButton,Pt_DEFAULT_PARENT,0,NULL));
printf("UnLock1: %i\n",pthread_mutex_unlock(&mutex));fflush(stdout);

PtMainLoop();
pthread_mutex_destroy( &mutex );
return EXIT_SUCCESS;

}
void draw( PtWidget_t *widget, PhTile_t *damage )
{
PtSuperClassDraw( PtBasic, widget, damage );
printf(“Lock2: %i\n”,pthread_mutex_lock(&mutex));fflush(stdout);
printf(“Do some Raw Drawing.\n”);fflush(stdout);
printf(“UnLock2: %i\n”,pthread_mutex_unlock(&mutex));fflush(stdout);

return;

}


OUTPUT:

Lock2: 0
Do some Raw Drawing.
UnLock2: 0
Lock1: 0
Lock2: 45
Do some Raw Drawing.
UnLock2: 0
UnLock1: 1
Lock2: 0
Do some Raw Drawing.
UnLock2: 0

The answer is very simple. Let me give you two very big hints.
45 = EDEADLK (Deadlock avoided).
This occurs when a thread which has locked a mutex tries to lock it again, non-recursively. Since it would have to wait for itself to unlock the thread, an event that can never happen while it is waiting, the OS returns an error indicating that the dead lock was avoided.

Note, this is not the same as one thread locking a mutex, and a second trying to lock it. In that case, thread 2 would become blocked waiting for thread 1.

I said 2 hints, but the 2nd should be very clear now, you are only dealing with ONE thread here.

Now take a look at your code, the output, and think about the relationship between the Realize call and the draw call, and you will learn something important.

Good luck.

I feel like I’m back in school…with an electronic blackboard.

I realize that the PtRealize function invokes the PtRaw’s draw function, since I am damaging the PtRaw’s canvas by realizing a new widget (within the same thread). In my real code, I am changing values to a structure, which in turn creates new widgets over-top the PtRaw. By creating the new widgets, I am damaging the PtRaw and it’s draw function gets called…which in turn uses the structure which is being modified! Hence why I was trying to use a mutex to avoid accessing possibly invalid structure member values. Does this make sense to you?

Solution? Temporarily disable the draw function until I have completed the changes to the structure members, and have finished with the PtRealize functions. Afterwards, re-instate the draw function and damage the PtRaw, which will then be able to use VALID data from the structure’s members.

Correct?

Sorry about invoking teacher mode, I thought you might like to discover this yourself.
It’s definitely a Doh! moment.
The reason are seeing this behavior is that PtRealize calls the Draw function.
Here is a psuedo version of what is happening.

main()
{

pthread_mutex_lock()
PtRealize();

}

PtRealize()
{

draw();

}

draw()
{

//This lock fails with 45
pthread_mutex_lock();

}

You only have one thread, so using a mutex is pointless here.
Maybe you are thinking of Java where the Java machine would
silently schedule a draw thread that you don’t want to interfere with.

Maybe what is confusing is that with Photon there are other threads going on.
For example, the Photon kernel has a thread, and the video driver itself
has a thread. But these are in different processes, communicated to by
message passing. You don’t have to worry about interfering with these.

The only reason you would need a mutex at all if you have more than
one thread in your own code, which you do not appear to.
If you did, you might keep the lock in the draw function, but
not call it in the main().

Yeah, the DOH hit pretty quick after your first posting.

For some reason I was under the impression that the draw function was called by PtRealize in a new thread, so it would block until I finished modifying my variables. I can see I will have to make some slight modifications to my code, but nothing too difficult.

Thanks maschoen.

Alternately, if you really are using multiple threads and this scenario is just an initialization “unfortunate situation” consider using a recursive mutex.