On Thu, Oct 14, 2004, Vinu V wrote:

> I am using the pth_key_* APIs in my program and I came across a point
> where the Pth library is crashing. Don't know whether this is a bug
> with Pth or with my program.
> This is what I have done.
>
> int taskVar
> main ()
> {
>
>      int retValue;
>      pth_mutex_t mutex;
>      pth_mutex_t cond;
>
>      pth_spawn(PTH_ATTR_DEFAULT, task1, NULL);
>
>      pth_mutex_init(&mutex);
>      pth_cond_init(&cond);
>
>      pth_key_create(&taskVar, NULL);
>      pth_key_setdata(taskVar, (int *)123);
>      retValue = (int)pth_key_getdata(taskVar);
>      retValue = pth_key_delete(taskVar);
>
>      pth_mutex_acquire(&mutex, 0, NULL);
>      pth_cond_await(&cond, &mutex, NULL);
>      pth_mutex_release(&mutex);
>
> } /* End of main */
>
> void *task1(void *arg)
> {
>       pth_mutex_acquire(&mutex, 0, NULL);
>       pth_cond_notify(&cond, 0);
>       pth_mutex_release(&mutex);
> }
>
> Here the program crashes at pth_cond_await() in main.
> When I comment the pth_key_delete() in main(), then this works perfectly.
>
> I think this is beacause of a bug in pth_key_delete().
>
> int pth_key_delete(pth_key_t key)
> {
>     if (key >= PTH_KEY_MAX)
>         return pth_error(FALSE, EINVAL);
>     if (!pth_keytab[key].used)
>         return pth_error(FALSE, EINVAL);
>     pth_keytab[key].used = FALSE;
>     return TRUE;
> }
>
> This function marks the "used" field of the specified key( in this
> example this is the index 0 of pth_keytab[] array) as FALSE. But it
> is not making the data pointer for this key as NULL. Hence the data
> pointer still contains the value 123.
>
> Now the pth_mutex_acquire internally uses the pth_key_getdata(), which
> returns the a a value of 123 which is invalid value for the mutex
> event and it crashes when it tries to manipulate this event data.
>
> Possible FIX.
> -------------
> This problem got solved when I cleared the data_value pointer within the
> pth_key_delete() function.
>
> int pth_key_delete(pth_key_t key)
> {
>     if (key >= PTH_KEY_MAX)
>         return pth_error(FALSE, EINVAL);
>     if (!pth_keytab[key].used)
>         return pth_error(FALSE, EINVAL);
>
>     pth_keytab[key].used = FALSE;
>     pth_current->data_value[key] =(void *)NULL;
>
>     return TRUE;
> }
>
> Please correct me if I am doing anything wrong here ...

Well, the main problem is that a call to pth_key_delete() is only
valid after clearing (with "pth_key_setdata(..., NULL)") the data
corresponding to this key in *all* threads. Just clearing the key in the
*current* thread is not sufficient. Additionally to clearing the data,
the corresponding destructor has to be called first, too.

The question just is: should pth_key_delete() return with e.g. EBUSY
in case any thread still uses data associated with the key or should
it instead automatically free all the data associated with it in all
threads. I personally think pth_key_delete() should return EBUSY. Any
objections?
                                       Ralf S. Engelschall
                                       [EMAIL PROTECTED]
                                       www.engelschall.com

______________________________________________________________________
GNU Portable Threads (Pth)            http://www.gnu.org/software/pth/
Development Site                      http://www.ossp.org/pkg/lib/pth/
Distribution Files                          ftp://ftp.gnu.org/gnu/pth/
Distribution Snapshots                 ftp://ftp.ossp.org/pkg/lib/pth/
User Support Mailing List                            [EMAIL PROTECTED]
Automated List Manager (Majordomo)           [EMAIL PROTECTED]

Reply via email to